@drghaliasri/butex 5.6.0 → 6.0.0

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/document2/ids.ts","../src/editor/digits.ts","../src/document2/articleMeta.ts","../src/document2/citations.ts","../src/ast/commands/index.ts","../src/ast/arabic_ast.ts","../src/document/mathObject.ts","../src/document2/labels.ts","../src/document2/inlineScanner.ts","../src/document2/importJson.ts","../src/editor/accentCommands.ts","../src/editor/atomicCommands.ts","../src/editor/atomicCommandsOperators.ts","../src/editor/factory.ts","../src/editor/characterFonts.ts","../src/editor/divideOperator.ts","../src/editor/render.ts","../src/editor/state.ts","../src/editor/display/delimiter.ts","../src/editor/display/frac.ts","../src/editor/display/sqrt.ts","../src/editor/display/overset.ts","../src/editor/display/underset.ts","../src/editor/display/accent.ts","../src/editor/display/env.ts","../src/diwani-font.ts","../src/editor/display/atomicCommand.ts","../src/editor/display/atomicCommandsOperators.ts","../src/editor/styles.ts","../src/document/normalizeCharImport.ts","../src/document/mathEditorAdapter.ts","../src/document2/mathBridge.ts","../src/document2/commands.ts","../src/document2/keys.ts","../src/document2/arabicPreamble.ts","../src/document2/exportLatex.ts","../src/document2/exportJson.ts","../src/document2/history.ts","../src/document2/blockSelection.ts","../src/document2/previewModel.ts"],"sourcesContent":["let nextId = 1;\n\nexport function document2Id(prefix: string): string {\n const id = `${prefix}_${String(nextId)}`;\n nextId += 1;\n return id;\n}\n","import type { DigitFormId } from './types.js';\n\nconst WESTERN = '0123456789';\nconst ARABIC_INDIC = '٠١٢٣٤٥٦٧٨٩';\nconst PERSIAN_INDIC = '۰۱۲۳۴۵۶۷۸۹';\n\nconst digitSets: Record<DigitFormId, string> = {\n western: WESTERN,\n arabicIndic: ARABIC_INDIC,\n persianIndic: PERSIAN_INDIC,\n};\n\nfunction digitValue(char: string): number {\n const western = WESTERN.indexOf(char);\n if (western >= 0) {\n return western;\n }\n const arabicIndic = ARABIC_INDIC.indexOf(char);\n if (arabicIndic >= 0) {\n return arabicIndic;\n }\n return PERSIAN_INDIC.indexOf(char);\n}\n\nexport function formatDigits(value: string, digitForm: DigitFormId = 'western'): string {\n const target = digitSets[digitForm];\n return Array.from(value, (char) => {\n const value = digitValue(char);\n return value >= 0 ? target[value] : char;\n }).join('');\n}\n","import { formatDigits } from '../editor/digits.js';\nimport type { DigitFormId } from '../editor/types.js';\nimport type { ButexUiLocale } from '../uiLocale.js';\nimport type { Document2HijriDate, Document2Meta, HijriMonthId } from './types.js';\n\nexport const BUTEX_BASMALA_LINE1 = 'بِسْمِ ٱللَّٰهِ ٱلرَّحْمَٰنِ ٱلرَّحِيمِ';\n\nexport const BUTEX_BASMALA_LINE2 = 'وَٱلصَّلَاةُ وَٱلسَّلَامُ عَلَىٰ رَسُولِ ٱللَّٰهِ';\n\nexport const BUTEX_BASMALA_SALAWAT = 'صَلَّى ٱللَّهُ عَلَيْهِ وَسَلَّمَ';\n\n/** Three-line basmala joined for UI / plain-text matchers. */\nexport const BUTEX_BASMALA = `${BUTEX_BASMALA_LINE1}\\n${BUTEX_BASMALA_LINE2}\\n${BUTEX_BASMALA_SALAWAT}`;\n\nexport const BUTEX_CLOSING_HAMDALA = 'الْحَمْدُ لِلَّهِ نَفَعَنَا بِعِلْمِهِ';\n\nfunction escapeButexTextArg(text: string): string {\n return text.replace(/\\\\/g, '\\\\textbackslash{}').replace(/[{}]/g, '\\\\$&');\n}\n\nfunction butexFontDisplayTex(macro: '\\\\butexdiwani' | '\\\\butexmaghribi', text: string): string {\n return `${macro}{${escapeButexTextArg(text)}}`;\n}\n\n/** Display-math body using BuTeX Diwani (for MathJax preview islands). */\nexport function butexDiwaniDisplayTex(text: string): string {\n return butexFontDisplayTex('\\\\butexdiwani', text);\n}\n\n/** Full display equation for XeLaTeX export. */\nexport function butexDiwaniDisplayLatex(text: string): string {\n return `\\\\[\\n${butexDiwaniDisplayTex(text)}\\n\\\\]`;\n}\n\n/** Display-math body using BuTeX Maghribi (for document chrome). */\nexport function butexMaghribiDisplayTex(text: string): string {\n return butexFontDisplayTex('\\\\butexmaghribi', text);\n}\n\n/** Full display equation using BuTeX Maghribi for XeLaTeX export. */\nexport function butexMaghribiDisplayLatex(text: string): string {\n return `\\\\[\\n${butexMaghribiDisplayTex(text)}\\n\\\\]`;\n}\n\nconst BASMALA_LINES = [BUTEX_BASMALA_LINE1, BUTEX_BASMALA_LINE2, BUTEX_BASMALA_SALAWAT] as const;\n\n/** Three-line Maghribi body for MathJax basmala islands. */\nexport function butexBasmalaDisplayTex(): string {\n return BASMALA_LINES.map((line) => butexMaghribiDisplayTex(line)).join(' \\\\\\\\ ');\n}\n\n/** Standalone display equation when there is no \\\\maketitle (title-less docs). */\nexport function butexBasmalaDisplayLatex(): string {\n return `\\\\[\\n\\\\begin{gathered}\\n${BASMALA_LINES.map((line) => butexMaghribiDisplayTex(line)).join(' \\\\\\\\\\n')}\\n\\\\end{gathered}\\n\\\\]`;\n}\n\n/**\n * Keep \\\\maketitle inside the current column when twocolumn is on.\n * Standard article otherwise does \\\\twocolumn[\\\\@maketitle] and spans both columns.\n * Call after titling so \\\\@maketitle still includes \\\\pretitle hooks.\n */\nexport function butexInColumnMaketitleHook(): string {\n return String.raw`\\makeatletter\n\\renewcommand{\\maketitle}{%\n \\par\n \\begingroup\n \\renewcommand\\thefootnote{\\@fnsymbol\\c@footnote}%\n \\def\\@makefnmark{\\rlap{\\@textsuperscript{\\normalfont\\@thefnmark}}}%\n \\long\\def\\@makefntext##1{\\parindent 1em\\noindent\n \\hb@xt@1.8em{\\hss\\@textsuperscript{\\normalfont\\@thefnmark}}##1}%\n \\@maketitle\n \\thispagestyle{plain}\\@thanks\n \\endgroup\n \\setcounter{footnote}{0}%\n \\global\\let\\thanks\\relax\n \\global\\let\\maketitle\\relax\n \\global\\let\\@maketitle\\relax\n \\global\\let\\@thanks\\@empty\n \\global\\let\\@author\\@empty\n \\global\\let\\@date\\@empty\n \\global\\let\\@title\\@empty\n \\global\\let\\title\\relax\n \\global\\let\\author\\relax\n \\global\\let\\date\\relax\n \\global\\let\\and\\relax\n}\n\\makeatother`;\n}\n\n/** Titling hooks so the basmala stays attached to the visible title. */\nexport function butexBasmalaTitlingPreamble(options: { twocolumn?: boolean } = {}): string {\n const lines = [\n '\\\\usepackage{titling}',\n '\\\\pretitle{%',\n ' \\\\begin{center}',\n ...BASMALA_LINES.map((line, index) => {\n const suffix = index < BASMALA_LINES.length - 1 ? '\\\\\\\\' : '';\n return ` ${butexMaghribiDisplayTex(line)}${suffix}`;\n }),\n ' \\\\par\\\\vspace{1.5em}',\n ' \\\\LARGE',\n '}',\n '\\\\posttitle{\\\\par\\\\end{center}}',\n ];\n if (options.twocolumn) {\n lines.push(butexInColumnMaketitleHook());\n }\n return lines.join('\\n');\n}\nexport const HIJRI_YEAR_MIN = 1400;\nexport const HIJRI_YEAR_MAX = 1500;\n\nexport const HIJRI_MONTH_IDS: HijriMonthId[] = [\n 'محرم',\n 'صفر',\n 'ربيع الأول',\n 'ربيع الآخر',\n 'جمادى الأولى',\n 'جمادى الآخرة',\n 'رجب',\n 'شعبان',\n 'رمضان',\n 'شوال',\n 'ذو القعدة',\n 'ذو الحجة',\n];\n\nconst HIJRI_MONTH_LABELS_EN: Record<HijriMonthId, string> = {\n محرم: 'Muharram',\n صفر: 'Safar',\n 'ربيع الأول': 'Rabiʻ I',\n 'ربيع الآخر': 'Rabiʻ II',\n 'جمادى الأولى': 'Jumada I',\n 'جمادى الآخرة': 'Jumada II',\n رجب: 'Rajab',\n شعبان: 'Shaʻban',\n رمضان: 'Ramadan',\n شوال: 'Shawwal',\n 'ذو القعدة': 'Dhul Qaʻdah',\n 'ذو الحجة': 'Dhul Hijjah',\n};\n\n/** Legacy Latin month ids from earlier drafts — accepted on import only. */\nconst LEGACY_LATIN_MONTH: Record<string, HijriMonthId> = {\n muharram: 'محرم',\n safar: 'صفر',\n rabiAwwal: 'ربيع الأول',\n rabiThani: 'ربيع الآخر',\n jumadaAwwal: 'جمادى الأولى',\n jumadaThani: 'جمادى الآخرة',\n rajab: 'رجب',\n shaban: 'شعبان',\n ramadan: 'رمضان',\n shawwal: 'شوال',\n dhulQadah: 'ذو القعدة',\n dhulHijjah: 'ذو الحجة',\n};\n\nexport const DEFAULT_HIJRI_DATE: Document2HijriDate = {\n day: 1,\n month: 'محرم',\n year: 1448,\n};\n\nexport function hijriMonthLabel(month: HijriMonthId, locale: ButexUiLocale = 'ar'): string {\n return locale === 'en' ? HIJRI_MONTH_LABELS_EN[month] : month;\n}\n\nexport function emptyDocument2Meta(): Document2Meta {\n return {\n title: '',\n authors: '',\n date: { ...DEFAULT_HIJRI_DATE },\n abstract: '',\n };\n}\n\nfunction clampInt(value: number, min: number, max: number): number {\n if (!Number.isFinite(value)) {\n return min;\n }\n return Math.min(max, Math.max(min, Math.trunc(value)));\n}\n\nfunction isHijriMonthId(value: unknown): value is HijriMonthId {\n return typeof value === 'string' && (HIJRI_MONTH_IDS as string[]).includes(value);\n}\n\nfunction resolveHijriMonthId(value: unknown): HijriMonthId {\n if (isHijriMonthId(value)) {\n return value;\n }\n if (typeof value === 'string' && value in LEGACY_LATIN_MONTH) {\n return LEGACY_LATIN_MONTH[value]!;\n }\n return DEFAULT_HIJRI_DATE.month;\n}\n\nexport function normalizeDocument2HijriDate(value: unknown): Document2HijriDate {\n if (typeof value !== 'object' || value === null) {\n return { ...DEFAULT_HIJRI_DATE };\n }\n const raw = value as Record<string, unknown>;\n const day = clampInt(typeof raw.day === 'number' ? raw.day : Number(raw.day), 1, 30);\n const year = clampInt(typeof raw.year === 'number' ? raw.year : Number(raw.year), HIJRI_YEAR_MIN, HIJRI_YEAR_MAX);\n const month = resolveHijriMonthId(raw.month);\n return { day, month, year };\n}\n\nexport function normalizeDocument2Meta(value: unknown): Document2Meta {\n if (typeof value !== 'object' || value === null) {\n return emptyDocument2Meta();\n }\n const raw = value as Record<string, unknown>;\n return {\n title: typeof raw.title === 'string' ? raw.title : '',\n authors: typeof raw.authors === 'string' ? raw.authors : '',\n date: normalizeDocument2HijriDate(raw.date),\n abstract: typeof raw.abstract === 'string' ? raw.abstract : '',\n };\n}\n\nexport type Document2MetaProp = Partial<Omit<Document2Meta, 'date'>> & {\n date?: Partial<Document2HijriDate>;\n};\n\n/** Prop fills gaps; JSON wins only when the key is present on the JSON object. */\nexport function mergeDocument2Meta(fromJson: unknown, fromProp?: Document2MetaProp): Document2Meta {\n const fromPropMeta: Document2Meta = {\n title: typeof fromProp?.title === 'string' ? fromProp.title : '',\n authors: typeof fromProp?.authors === 'string' ? fromProp.authors : '',\n abstract: typeof fromProp?.abstract === 'string' ? fromProp.abstract : '',\n date: fromProp?.date\n ? normalizeDocument2HijriDate({ ...DEFAULT_HIJRI_DATE, ...fromProp.date })\n : { ...DEFAULT_HIJRI_DATE },\n };\n if (typeof fromJson !== 'object' || fromJson === null) {\n return fromPropMeta;\n }\n const json = fromJson as Record<string, unknown>;\n return {\n title: 'title' in json && typeof json.title === 'string' ? json.title : fromPropMeta.title,\n authors: 'authors' in json && typeof json.authors === 'string' ? json.authors : fromPropMeta.authors,\n abstract: 'abstract' in json && typeof json.abstract === 'string' ? json.abstract : fromPropMeta.abstract,\n date: 'date' in json ? normalizeDocument2HijriDate(json.date) : fromPropMeta.date,\n };\n}\n\n/** For live Document2Node meta: prop fills empty title/authors/abstract; date patch merges. */\nexport function fillDocument2MetaGaps(current: Document2Meta, fromProp?: Document2MetaProp): Document2Meta {\n if (!fromProp) {\n return cloneDocument2Meta(current);\n }\n return {\n title: current.title.trim().length > 0 ? current.title : typeof fromProp.title === 'string' ? fromProp.title : current.title,\n authors:\n current.authors.trim().length > 0\n ? current.authors\n : typeof fromProp.authors === 'string'\n ? fromProp.authors\n : current.authors,\n abstract:\n current.abstract.trim().length > 0\n ? current.abstract\n : typeof fromProp.abstract === 'string'\n ? fromProp.abstract\n : current.abstract,\n date: fromProp.date\n ? normalizeDocument2HijriDate({ ...current.date, ...fromProp.date })\n : { ...current.date },\n };\n}\n\nexport function document2HasMaketitle(meta: Document2Meta): boolean {\n return meta.title.trim().length > 0 || meta.authors.trim().length > 0;\n}\n\nexport function document2HasAbstract(meta: Document2Meta): boolean {\n return meta.abstract.trim().length > 0;\n}\n\nexport function document2HasTitleStack(meta: Document2Meta): boolean {\n return document2HasMaketitle(meta) || document2HasAbstract(meta);\n}\n\nexport type FormatHijriDateOptions = {\n locale?: ButexUiLocale;\n digitForm?: DigitFormId;\n};\n\nexport function formatHijriDate(date: Document2HijriDate, options: FormatHijriDateOptions | ButexUiLocale = 'ar'): string {\n const opts: FormatHijriDateOptions = typeof options === 'string' ? { locale: options } : options;\n const locale = opts.locale ?? 'ar';\n const digitForm: DigitFormId =\n opts.digitForm ?? (locale === 'en' ? 'western' : 'arabicIndic');\n const month = hijriMonthLabel(date.month, locale);\n const day = formatDigits(String(date.day), digitForm);\n const year = formatDigits(String(date.year), digitForm);\n if (locale === 'en') {\n return `${day} ${month} ${year} AH`;\n }\n return `${day} ${month} ${year}هـ`;\n}\n\nexport function cloneDocument2Meta(meta: Document2Meta): Document2Meta {\n return {\n title: meta.title,\n authors: meta.authors,\n date: { ...meta.date },\n abstract: meta.abstract,\n };\n}\n","import { formatDigits } from '../editor/digits.js';\nimport type { DigitFormId } from '../editor/types.js';\nimport type { FormatCiteLabelOptions, Reference2, Reference2Json, ReferenceFieldSeparator } from './types.js';\nimport { document2Id } from './ids.js';\n\nexport const DEFAULT_REFERENCE_FIELD_SEPARATOR: ReferenceFieldSeparator = '،';\n\nexport function normalizeReferenceFieldSeparator(value: unknown): ReferenceFieldSeparator {\n return value === ',' ? ',' : DEFAULT_REFERENCE_FIELD_SEPARATOR;\n}\n\nexport function referenceNumberMap(references: Array<Pick<Reference2, 'key'>>): Map<string, number> {\n const map = new Map<string, number>();\n references.forEach((reference, index) => {\n if (!map.has(reference.key)) {\n map.set(reference.key, index + 1);\n }\n });\n return map;\n}\n\nexport function resolveCiteNumbers(keys: string[], references: Array<Pick<Reference2, 'key'>>): Array<number | null> {\n const map = referenceNumberMap(references);\n return keys.map((key) => map.get(key) ?? null);\n}\n\nexport function formatCiteLabel(\n keys: string[],\n references: Array<Pick<Reference2, 'key'>>,\n options: FormatCiteLabelOptions = {},\n): string {\n const documentDirection = options.documentDirection ?? 'rtl';\n const digitForm: DigitFormId = options.digitForm ?? (documentDirection === 'rtl' ? 'arabicIndic' : 'western');\n const numbers = resolveCiteNumbers(keys, references).map((value) => (value === null ? '?' : String(value)));\n const display = documentDirection === 'rtl' ? [...numbers].reverse() : numbers;\n const separator = documentDirection === 'rtl' ? '،' : ', ';\n const body = display.map((part) => formatDigits(part, digitForm)).join(separator);\n return `[${body}]`;\n}\n\nexport function formatBibliographyNumber(index: number, options: FormatCiteLabelOptions = {}): string {\n const documentDirection = options.documentDirection ?? 'rtl';\n const digitForm: DigitFormId = options.digitForm ?? (documentDirection === 'rtl' ? 'arabicIndic' : 'western');\n return formatDigits(String(index), digitForm);\n}\n\nexport function parseCiteKeys(source: string): string[] {\n const match = /^\\\\cite\\{([^}]*)\\}$/.exec(source.trim());\n if (!match) {\n return [];\n }\n return (match[1] ?? '')\n .split(',')\n .map((key) => key.trim())\n .filter((key) => key.length > 0);\n}\n\nexport function citeTokenLatex(keys: string[]): string {\n return `\\\\cite{${keys.join(',')}}`;\n}\n\nexport function referenceFromJson(json: Reference2Json): Reference2 {\n return {\n id: document2Id('ref'),\n key: json.key,\n authors: typeof json.authors === 'string' ? json.authors : '',\n title: typeof json.title === 'string' ? json.title : '',\n year: typeof json.year === 'string' ? json.year : '',\n url: typeof json.url === 'string' ? json.url : '',\n venue: typeof json.venue === 'string' ? json.venue : '',\n fieldSeparator: normalizeReferenceFieldSeparator(json.field_separator),\n };\n}\n\nexport function createEmptyReference2(partial: Partial<Reference2Json> = {}): Reference2 {\n return referenceFromJson({\n key: partial.key ?? `ref${String(Date.now()).slice(-4)}`,\n authors: partial.authors,\n title: partial.title,\n year: partial.year,\n url: partial.url,\n venue: partial.venue,\n field_separator: partial.field_separator,\n });\n}\n\n/** Joined authors/title/venue/year for preview and export (no \\\\bibitem wrapper). */\nexport function bibliographyEntryBody(\n reference: Pick<Reference2, 'authors' | 'title' | 'venue' | 'year' | 'fieldSeparator'>,\n separator: ReferenceFieldSeparator = reference.fieldSeparator,\n options: { digitForm?: DigitFormId } = {},\n): string {\n const year =\n options.digitForm !== undefined ? formatDigits(reference.year, options.digitForm) : reference.year;\n const parts = [reference.authors, reference.title, reference.venue, year].filter((part) => part.trim().length > 0);\n return parts.join(`${separator} `);\n}\n\nexport function bibliographyEntryLatex(reference: Reference2): string {\n const body = bibliographyEntryBody(reference);\n const url = reference.url.trim().length > 0 ? ` \\\\url{${reference.url}}` : '';\n return `\\\\bibitem{${reference.key}} ${body}${url}`.trim();\n}\n\n/**\n * Build an href for a bibliography URL. Values without a scheme become https://…\n * so the browser does not resolve them against the editor origin (e.g. localhost).\n * Leaves http(s)/mailto/ftp and other schemed URLs unchanged. Empty → ''.\n */\nexport function absoluteHttpHref(url: string): string {\n const trimmed = url.trim();\n if (trimmed.length === 0) {\n return '';\n }\n if (/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(trimmed)) {\n return trimmed;\n }\n if (trimmed.startsWith('//')) {\n return `https:${trimmed}`;\n }\n return `https://${trimmed}`;\n}\n","import type { ChainNode } from '../arabic_ast.js';\n\ntype CommandRenderContext = {\n name: string;\n optionalArgs: ChainNode[];\n mandatoryArgs: ChainNode[];\n renderChain: (chain: ChainNode) => string;\n};\n\nexport function renderCommandCore(context: CommandRenderContext): string {\n const optional = context.optionalArgs.map((arg) => `[${context.renderChain(arg)}]`).join('');\n const mandatory = context.mandatoryArgs.map((arg) => `{${context.renderChain(arg)}}`).join('');\n return context.name + optional + mandatory;\n}\n","import { renderCommandCore } from './commands/index.js';\n\nexport type ArabicNodeJson = {\n node_type: string;\n expr?: string;\n name?: string;\n superscript?: ChainJson | null;\n subscript?: ChainJson | null;\n left_delim_expr?: string;\n right_delim_expr?: string;\n inner_expr?: ChainJson;\n optional_args?: ChainJson[];\n mandatory_args?: ChainJson[];\n opening?: string;\n closing?: string;\n lines?: ChainJson[];\n};\n\nexport type ChainJson = {\n node_type: 'ChainClass';\n chain: ArabicNodeJson[];\n};\n\nexport class State {\n // Empty for now, like the Python State placeholder used by BaseNode.\n}\n\nexport class BaseAstNode {\n state: State;\n superscript: ChainNode | null;\n subscript: ChainNode | null;\n nodeType: string;\n\n constructor(state: State | null = null) {\n if (state === null) {\n state = new State();\n }\n\n this.state = state;\n this.superscript = null;\n this.subscript = null;\n this.nodeType = this.constructor.name;\n }\n\n latex(): string {\n throw new Error('NotImplementedError');\n }\n\n arabicLatex(): string {\n throw new Error('NotImplementedError');\n }\n\n toArabicLatex(): string {\n return this.arabicLatex();\n }\n\n /** Latin-style scripts: `^{...}` and `_{...}` for english_json rendering. */\n latexScripts(): string {\n let s = '';\n\n if (this.superscript !== null) {\n s += '^{' + this.superscript.latex() + '}';\n }\n\n if (this.subscript !== null) {\n s += '_{' + this.subscript.latex() + '}';\n }\n\n return s;\n }\n\n /**\n * Arabic scripts use \\\\prescript{sup}{sub}{content} (matches reference Python output).\n * Call with rendered strings for sup/sub chains (may be empty strings).\n */\n arabicLatexScripts(sup: string, sub: string, content: string): string {\n if (sup !== '' || sub !== '') {\n return '\\\\prescript{' + sup + '}{' + sub + '}{' + content + '}';\n }\n return content;\n }\n}\n\nexport class ChainNode {\n chain: BaseAstNode[];\n\n constructor(chain: BaseAstNode[] = []) {\n this.chain = chain;\n }\n\n latex(): string {\n return this.chain.map((node) => node.latex()).join(' ');\n }\n toEnglishLatex(): string {\n return this.chain.map((node) => node.latex()).join(' ');\n }\n /** RTL: reverse order relative to Latin chain (see test/ref_tests.txt). */\n arabicLatex(): string {\n const reversed = this.chain.slice().reverse();\n return reversed.map((node) => node.arabicLatex()).join(' ');\n }\n\n toArabicLatex(): string {\n return this.arabicLatex();\n }\n}\n\nexport class NumberNode extends BaseAstNode {\n expr: string;\n\n constructor(expr: string, state: State | null = null) {\n super(state);\n this.nodeType = 'NumberObject';\n this.expr = expr;\n }\n\n latex(): string {\n return this.expr + this.latexScripts();\n }\n\n arabicLatex(): string {\n const sup = this.superscript !== null ? this.superscript.arabicLatex() : '';\n const sub = this.subscript !== null ? this.subscript.arabicLatex() : '';\n return this.arabicLatexScripts(sup, sub, this.expr);\n }\n}\n\nexport class CharNode extends BaseAstNode {\n expr: string;\n\n constructor(expr: string, state: State | null = null) {\n super(state);\n this.nodeType = 'CharObject';\n this.expr = expr;\n }\n\n latex(): string {\n return this.expr + this.latexScripts();\n }\n\n arabicLatex(): string {\n const sup = this.superscript !== null ? this.superscript.arabicLatex() : '';\n const sub = this.subscript !== null ? this.subscript.arabicLatex() : '';\n return this.arabicLatexScripts(sup, sub, this.expr);\n }\n}\n\n/**\n * Operator leaf: value comes from JSON as-is (English or Arabic side already chosen by the service).\n * Scripts are not appended (Python parity).\n */\nexport class OperatorNode extends BaseAstNode {\n expr: string;\n\n constructor(expr: string, state: State | null = null) {\n super(state);\n this.nodeType = 'OperatorObject';\n this.expr = expr;\n }\n\n latex(): string {\n return this.expr;\n }\n\n arabicLatex(): string {\n return this.expr;\n }\n}\n\nexport class DelimiterNode extends BaseAstNode {\n leftDelimExpr: string;\n innerExpr: ChainNode;\n rightDelimExpr: string;\n\n constructor(leftDelimExpr: string, innerExpr: ChainNode, rightDelimExpr: string, state: State | null = null) {\n super(state);\n this.nodeType = 'DelimiterObject';\n this.leftDelimExpr = leftDelimExpr;\n this.innerExpr = innerExpr;\n this.rightDelimExpr = rightDelimExpr;\n }\n\n latex(): string {\n return this.leftDelimExpr + this.innerExpr.latex() + this.rightDelimExpr + this.latexScripts();\n }\n\n arabicLatex(): string {\n const sup = this.superscript !== null ? this.superscript.arabicLatex() : '';\n const sub = this.subscript !== null ? this.subscript.arabicLatex() : '';\n const content = this.leftDelimExpr + this.innerExpr.arabicLatex() + this.rightDelimExpr;\n return this.arabicLatexScripts(sup, sub, content);\n }\n}\n\nexport class CommandNode extends BaseAstNode {\n name: string;\n optionalArgs: ChainNode[];\n mandatoryArgs: ChainNode[];\n\n constructor(\n name: string,\n optionalArgs: ChainNode[] = [],\n mandatoryArgs: ChainNode[] = [],\n state: State | null = null\n ) {\n super(state);\n this.nodeType = 'CommandObject';\n this.name = name;\n this.optionalArgs = optionalArgs;\n this.mandatoryArgs = mandatoryArgs;\n }\n\n latex(): string {\n const content = renderCommandCore({\n name: this.name,\n optionalArgs: this.optionalArgs,\n mandatoryArgs: this.mandatoryArgs,\n renderChain: (chain) => chain.latex(),\n });\n return content + this.latexScripts();\n }\n\n arabicLatex(): string {\n const sup = this.superscript !== null ? this.superscript.arabicLatex() : '';\n const sub = this.subscript !== null ? this.subscript.arabicLatex() : '';\n const arabicName =\n this.name === '\\\\sqrt' || this.name === '\\\\arabsqrt' ? '\\\\arsqrt' : this.name;\n const content = renderCommandCore({\n name: arabicName,\n optionalArgs: this.optionalArgs,\n mandatoryArgs: this.mandatoryArgs,\n renderChain: (chain) => chain.arabicLatex(),\n });\n return this.arabicLatexScripts(sup, sub, content);\n }\n}\n\nexport class EnvNode extends BaseAstNode {\n opening: string;\n lines: ChainNode[];\n closing: string;\n\n constructor(opening: string, lines: ChainNode[] = [], closing: string, state: State | null = null) {\n super(state);\n this.nodeType = 'EnvObject';\n this.opening = opening;\n this.lines = lines;\n this.closing = closing;\n }\n\n latex(): string {\n if (this.lines.length === 0) {\n return this.opening + this.closing + this.latexScripts();\n }\n\n const formattedLines = this.lines.map((line) => ` ${line.latex()}`);\n const content = formattedLines.join(' \\\\\\\\' + '\\n');\n return `${this.opening}\\n${content}\\n${this.closing}` + this.latexScripts();\n }\n\n arabicLatex(): string {\n const sup = this.superscript !== null ? this.superscript.arabicLatex() : '';\n const sub = this.subscript !== null ? this.subscript.arabicLatex() : '';\n\n if (this.lines.length === 0) {\n return this.arabicLatexScripts(sup, sub, this.opening + this.closing);\n }\n\n const formattedLines = this.lines.map((line) => ` ${line.arabicLatex()}`);\n const content = formattedLines.join(' \\\\\\\\' + '\\n');\n const fullContent = `${this.opening}\\n${content}\\n${this.closing}`;\n return this.arabicLatexScripts(sup, sub, fullContent);\n }\n}\n\ntype ParseMode = 'english' | 'arabic';\n\nfunction parseScripts(node: BaseAstNode, json: ArabicNodeJson, mode: ParseMode): void {\n if (json.superscript) {\n node.superscript = parseChain(json.superscript, mode);\n }\n\n if (json.subscript) {\n node.subscript = parseChain(json.subscript, mode);\n }\n}\n\nfunction parseNode(json: ArabicNodeJson, mode: ParseMode): BaseAstNode {\n if (json.node_type === 'DelimiterObject') {\n const node = parseDelimiter(json, mode);\n parseScripts(node, json, mode);\n return node;\n }\n\n if (json.node_type === 'OperatorObject') {\n if (typeof json.expr !== 'string') {\n throw new Error('OperatorObject requires string expr');\n }\n const node = new OperatorNode(json.expr);\n parseScripts(node, json, mode);\n return node;\n }\n\n if (json.node_type === 'CommandObject') {\n const node = parseCommand(json, mode);\n parseScripts(node, json, mode);\n return node;\n }\n\n if (json.node_type === 'EnvObject') {\n const node = parseEnv(json, mode);\n parseScripts(node, json, mode);\n return node;\n }\n\n if (typeof json.expr !== 'string') {\n throw new Error(`${json.node_type} requires string expr`);\n }\n\n let node: BaseAstNode;\n\n if (json.node_type === 'NumberObject') {\n node = new NumberNode(json.expr);\n } else if (json.node_type === 'CharObject') {\n node = new CharNode(json.expr);\n } else {\n throw new Error(`Unsupported node_type: ${json.node_type}`);\n }\n\n parseScripts(node, json, mode);\n return node;\n}\n\nfunction parseDelimiter(json: ArabicNodeJson, mode: ParseMode): DelimiterNode {\n if (typeof json.left_delim_expr !== 'string') {\n throw new Error('DelimiterObject requires string left_delim_expr');\n }\n\n if (!json.inner_expr || json.inner_expr.node_type !== 'ChainClass') {\n throw new Error('DelimiterObject requires ChainClass inner_expr');\n }\n\n if (typeof json.right_delim_expr !== 'string') {\n throw new Error('DelimiterObject requires string right_delim_expr');\n }\n\n const innerExpr = parseChain(json.inner_expr, mode);\n return new DelimiterNode(json.left_delim_expr, innerExpr, json.right_delim_expr);\n}\n\nfunction parseCommand(json: ArabicNodeJson, mode: ParseMode): CommandNode {\n if (typeof json.name !== 'string') {\n throw new Error('CommandObject requires string name');\n }\n\n const optionalJson = Array.isArray(json.optional_args) ? json.optional_args : [];\n const mandatoryJson = Array.isArray(json.mandatory_args) ? json.mandatory_args : [];\n const optionalArgs = optionalJson.map((arg) => parseChain(arg, mode));\n const mandatoryArgs = mandatoryJson.map((arg) => parseChain(arg, mode));\n\n return new CommandNode(json.name, optionalArgs, mandatoryArgs);\n}\n\nfunction parseEnv(json: ArabicNodeJson, mode: ParseMode): EnvNode {\n if (typeof json.opening !== 'string') {\n throw new Error('EnvObject requires string opening');\n }\n\n if (typeof json.closing !== 'string') {\n throw new Error('EnvObject requires string closing');\n }\n\n if (!Array.isArray(json.lines)) {\n throw new Error('EnvObject requires lines array');\n }\n\n const lines = json.lines.map((line) => parseChain(line, mode));\n return new EnvNode(json.opening, lines, json.closing);\n}\n\nfunction parseChain(json: ChainJson, mode: ParseMode): ChainNode {\n if (json.node_type !== 'ChainClass') {\n throw new Error(`Expected ChainClass, got: ${json.node_type}`);\n }\n\n const nodes = json.chain.map((childJson) => parseNode(childJson, mode));\n return new ChainNode(nodes);\n}\n\n/** Import AST from Python english_dict JSON (Latin expr fields). */\nexport function fromEnglishJson(json: ChainJson | ArabicNodeJson): ChainNode | BaseAstNode {\n if (json.node_type === 'ChainClass') {\n return parseChain(json as ChainJson, 'english');\n }\n return parseNode(json, 'english');\n}\n\n/** Import AST from Python arabic_dict JSON (Arabic expr fields). Same shape as English; values differ. */\nexport function fromArabicJson(json: ChainJson | ArabicNodeJson): ChainNode | BaseAstNode {\n if (json.node_type === 'ChainClass') {\n return parseChain(json as ChainJson, 'arabic');\n }\n return parseNode(json, 'arabic');\n}\n","import {\n BaseAstNode,\n ChainNode,\n CharNode,\n CommandNode,\n DelimiterNode,\n EnvNode,\n NumberNode,\n OperatorNode,\n fromArabicJson,\n fromEnglishJson,\n type ArabicNodeJson,\n type ChainJson,\n} from '../ast/arabic_ast.js';\nimport type { DocumentParseMode, MathNode, MathObjectJson } from './types.js';\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nfunction isMathObjectJson(value: unknown): value is MathObjectJson {\n return isObject(value) && value.node_type === 'MathObject';\n}\n\nfunction assertChainNode(value: unknown): ChainNode {\n if (!(value instanceof ChainNode)) {\n throw new Error('MathObject lines must parse to ChainNode');\n }\n return value;\n}\n\nexport function fromMathObjectJson(json: unknown, mode: DocumentParseMode = 'english'): MathNode {\n if (!isMathObjectJson(json)) {\n throw new Error('MathObject requires node_type \"MathObject\"');\n }\n\n if (typeof json.math_mode !== 'string') {\n throw new Error('MathObject requires string math_mode');\n }\n\n if (typeof json.closing !== 'string') {\n throw new Error('MathObject requires string closing');\n }\n\n if (!Array.isArray(json.lines) || json.lines.length === 0) {\n throw new Error('MathObject requires non-empty lines array');\n }\n\n const parseChain = mode === 'arabic' ? fromArabicJson : fromEnglishJson;\n const lines = json.lines.map((line) => assertChainNode(parseChain(line)));\n\n return {\n nodeType: 'MathObject',\n mathMode: json.math_mode,\n lines,\n closing: json.closing,\n };\n}\n\nfunction scriptsToJson(node: BaseAstNode, path: string): Pick<ArabicNodeJson, 'superscript' | 'subscript'> {\n return {\n ...(node.superscript ? { superscript: chainToJson(node.superscript, `${path}.superscript`) } : {}),\n ...(node.subscript ? { subscript: chainToJson(node.subscript, `${path}.subscript`) } : {}),\n };\n}\n\nfunction nodeToJson(node: BaseAstNode, path: string): ArabicNodeJson {\n const scripts = scriptsToJson(node, path);\n if (node instanceof CharNode || node instanceof NumberNode || node instanceof OperatorNode) {\n return { node_type: node.nodeType, expr: node.expr, ...scripts };\n }\n if (node instanceof DelimiterNode) {\n return {\n node_type: 'DelimiterObject',\n left_delim_expr: node.leftDelimExpr,\n inner_expr: chainToJson(node.innerExpr, `${path}.inner_expr`),\n right_delim_expr: node.rightDelimExpr,\n ...scripts,\n };\n }\n if (node instanceof CommandNode) {\n return {\n node_type: 'CommandObject',\n name: node.name,\n optional_args: node.optionalArgs.map((arg, index) => chainToJson(arg, `${path}.optional_args[${String(index)}]`)),\n mandatory_args: node.mandatoryArgs.map((arg, index) => chainToJson(arg, `${path}.mandatory_args[${String(index)}]`)),\n ...scripts,\n };\n }\n if (node instanceof EnvNode) {\n return {\n node_type: 'EnvObject',\n opening: node.opening,\n lines: node.lines.map((line, index) => chainToJson(line, `${path}.lines[${String(index)}]`)),\n closing: node.closing,\n ...scripts,\n };\n }\n throw new Error(`Unsupported runtime math node at ${path}: ${node.nodeType}`);\n}\n\nfunction chainToJson(chain: ChainNode, path: string): ChainJson {\n if (!(chain instanceof ChainNode)) {\n throw new Error(`Expected live ChainNode at ${path}`);\n }\n return {\n node_type: 'ChainClass',\n chain: chain.chain.map((node, index) => nodeToJson(node, `${path}.chain[${String(index)}]`)),\n };\n}\n\nexport function toMathObjectJson(math: MathNode): MathObjectJson {\n if (math.nodeType !== 'MathObject' || !Array.isArray(math.lines) || math.lines.length === 0) {\n throw new Error('Cannot serialize invalid runtime MathObject');\n }\n return {\n node_type: 'MathObject',\n math_mode: math.mathMode,\n lines: math.lines.map((line, index) => chainToJson(line, `$.lines[${String(index)}]`)),\n closing: math.closing,\n };\n}\n\nexport function renderMathNodeLatex(math: MathNode): string {\n const lines = math.lines.map((line) => line.arabicLatex());\n\n if (math.mathMode === '$' || math.mathMode === '\\\\(') {\n return math.mathMode + lines.join(' ') + math.closing;\n }\n\n if (math.mathMode === '$$' || math.mathMode === '\\\\[') {\n if (lines.length === 1) {\n return math.mathMode + '\\n' + lines[0] + '\\n' + math.closing;\n }\n return math.mathMode + '\\n' + lines.map((line) => ` ${line}`).join(' \\\\\\\\\\n') + '\\n' + math.closing;\n }\n\n if (lines.length === 1) {\n return `${math.mathMode}\\n ${lines[0]}\\n${math.closing}`;\n }\n\n return `${math.mathMode}\\n${lines.map((line) => ` ${line}`).join(' \\\\\\\\\\n')}\\n${math.closing}`;\n}\n\nexport function isDisplayMathNode(math: MathNode): boolean {\n return math.mathMode === '$$' || math.mathMode === '\\\\[' || math.mathMode.startsWith('\\\\begin{');\n}\n","import { formatDigits } from '../editor/digits.js';\nimport type { DigitFormId } from '../editor/types.js';\nimport type { ButexUiLocale } from '../uiLocale.js';\nimport { formatBibliographyNumber } from './citations.js';\nimport type {\n Document2Block,\n Document2Direction,\n Document2Node,\n FormatCiteLabelOptions,\n ImageBlock2,\n InlineField2,\n MathToken2,\n TableBlock2,\n} from './types.js';\n\nexport type Document2LabelKind = 'fig' | 'tab' | 'eq';\n\nexport type Document2LabelEntry = {\n key: string;\n kind: Document2LabelKind;\n caption: string;\n /** Block id for fig/tab, or math token id for eq. */\n ownerId: string;\n number: number;\n};\n\nexport type FloatMetaPatch = {\n centered?: boolean;\n captionEnabled?: boolean;\n caption?: string;\n labelEnabled?: boolean;\n label?: string;\n};\n\nexport function defaultFloatMeta(): {\n centered: true;\n captionEnabled: false;\n caption: '';\n labelEnabled: false;\n label: '';\n} {\n return {\n centered: true,\n captionEnabled: false,\n caption: '',\n labelEnabled: false,\n label: '',\n };\n}\n\nexport function parseFloatMetaFromJson(json: {\n caption?: string;\n label?: string;\n caption_enabled?: boolean;\n label_enabled?: boolean;\n centered?: boolean;\n}): {\n centered: boolean;\n captionEnabled: boolean;\n caption: string;\n labelEnabled: boolean;\n label: string;\n} {\n const caption = typeof json.caption === 'string' ? json.caption : '';\n const label = typeof json.label === 'string' ? json.label : '';\n return {\n centered: json.centered !== false,\n captionEnabled: json.caption_enabled === true || (typeof json.caption_enabled !== 'boolean' && caption.length > 0),\n caption,\n labelEnabled: json.label_enabled === true || (typeof json.label_enabled !== 'boolean' && label.trim().length > 0),\n label,\n };\n}\n\nexport function parseRefKeys(source: string): { keys: string[]; refCommand: 'ref' | 'eqref' } {\n const eqref = /^\\\\eqref\\{([^}]*)\\}$/.exec(source.trim());\n if (eqref) {\n return {\n refCommand: 'eqref',\n keys: (eqref[1] ?? '')\n .split(',')\n .map((key) => key.trim())\n .filter((key) => key.length > 0),\n };\n }\n const ref = /^\\\\ref\\{([^}]*)\\}$/.exec(source.trim());\n if (ref) {\n return {\n refCommand: 'ref',\n keys: (ref[1] ?? '')\n .split(',')\n .map((key) => key.trim())\n .filter((key) => key.length > 0),\n };\n }\n return { keys: [], refCommand: 'ref' };\n}\n\nexport function refTokenLatex(keys: string[], refCommand: 'ref' | 'eqref'): string {\n const command = refCommand === 'eqref' ? '\\\\eqref' : '\\\\ref';\n return `${command}{${keys.join(',')}}`;\n}\n\n/** Collect enabled labels in document order, numbering per kind. */\nexport function collectDocument2Labels(document: Document2Node): Document2LabelEntry[] {\n const entries: Document2LabelEntry[] = [];\n const counters: Record<Document2LabelKind, number> = { fig: 0, tab: 0, eq: 0 };\n\n function pushEqFromField(tokens: MathToken2[] | InlineField2['tokens']): void {\n for (const token of tokens) {\n if (token.kind !== 'math') {\n continue;\n }\n if (token.display && token.labelEnabled && token.label && token.label.trim().length > 0) {\n counters.eq += 1;\n entries.push({\n key: token.label.trim(),\n kind: 'eq',\n caption: '',\n ownerId: token.id,\n number: counters.eq,\n });\n }\n }\n }\n\n function walk(blocks: Document2Block[]): void {\n for (const block of blocks) {\n if (block.kind === 'image' && block.labelEnabled && block.label.trim().length > 0) {\n counters.fig += 1;\n entries.push({\n key: block.label.trim(),\n kind: 'fig',\n caption: block.captionEnabled ? block.caption : '',\n ownerId: block.id,\n number: counters.fig,\n });\n }\n if (block.kind === 'table') {\n if (block.labelEnabled && block.label.trim().length > 0) {\n counters.tab += 1;\n entries.push({\n key: block.label.trim(),\n kind: 'tab',\n caption: block.captionEnabled ? block.caption : '',\n ownerId: block.id,\n number: counters.tab,\n });\n }\n for (const row of block.rows) {\n for (const cell of row) {\n pushEqFromField(cell.tokens);\n }\n }\n }\n if (block.kind === 'textBlock') {\n pushEqFromField(block.field.tokens);\n }\n if (block.kind === 'list') {\n for (const item of block.items) {\n pushEqFromField(item.field.tokens);\n walk(item.blocks);\n }\n }\n }\n }\n\n walk(document.blocks);\n return entries;\n}\n\nexport function labelNumberMap(document: Document2Node): Map<string, { kind: Document2LabelKind; number: number }> {\n const map = new Map<string, { kind: Document2LabelKind; number: number }>();\n for (const entry of collectDocument2Labels(document)) {\n if (!map.has(entry.key)) {\n map.set(entry.key, { kind: entry.kind, number: entry.number });\n }\n }\n return map;\n}\n\nexport type FormatFloatCaptionTitleOptions = {\n uiLocale?: ButexUiLocale;\n documentDirection?: Document2Direction;\n digitForm?: DigitFormId;\n};\n\n/** Localized numbered float/equation title: الشكل ١ / Figure 1 / المعادلة ١. */\nexport function formatFloatCaptionTitle(\n kind: Document2LabelKind,\n number: number,\n options: FormatFloatCaptionTitleOptions = {},\n): string {\n const locale = options.uiLocale ?? 'ar';\n const kindWord =\n kind === 'fig'\n ? locale === 'ar'\n ? 'الشكل'\n : 'Figure'\n : kind === 'tab'\n ? locale === 'ar'\n ? 'الجدول'\n : 'Table'\n : locale === 'ar'\n ? 'المعادلة'\n : 'Equation';\n const digits = formatBibliographyNumber(number, {\n documentDirection: options.documentDirection ?? (locale === 'ar' ? 'rtl' : 'ltr'),\n digitForm: options.digitForm ?? (locale === 'ar' ? 'arabicIndic' : 'western'),\n });\n return `${kindWord} ${digits}`;\n}\n\n/** Caption line as shown in document preview: الشكل ١: نص / Figure 1. text. */\nexport function formatFloatCaptionPreview(\n title: string,\n caption: string | undefined,\n uiLocale: ButexUiLocale = 'ar',\n): string {\n const trimmed = caption?.trim() ?? '';\n if (trimmed.length === 0) {\n return title;\n }\n const separator = uiLocale === 'ar' ? ': ' : '. ';\n return `${title}${separator}${trimmed}`;\n}\n\nexport function formatRefLabel(\n keys: string[],\n document: Document2Node,\n refCommand: 'ref' | 'eqref',\n options: FormatCiteLabelOptions = {},\n): string {\n const documentDirection: Document2Direction = options.documentDirection ?? 'rtl';\n const digitForm: DigitFormId = options.digitForm ?? (documentDirection === 'rtl' ? 'arabicIndic' : 'western');\n const map = labelNumberMap(document);\n const parts = keys.map((key) => {\n const hit = map.get(key);\n if (!hit) {\n return '?';\n }\n return formatDigits(String(hit.number), digitForm);\n });\n const body = parts.join(documentDirection === 'rtl' ? '،' : ', ');\n if (refCommand === 'eqref') {\n return `(${body})`;\n }\n return body;\n}\n\nexport function stripDisplayMathDelimiters(source: string): string {\n const trimmed = source.trim();\n if (trimmed.startsWith('\\\\[') && trimmed.endsWith('\\\\]')) {\n return trimmed.slice(2, -2).trim();\n }\n if (trimmed.startsWith('$$') && trimmed.endsWith('$$')) {\n return trimmed.slice(2, -2).trim();\n }\n if (trimmed.startsWith('\\\\begin{equation}') && trimmed.endsWith('\\\\end{equation}')) {\n return trimmed.slice('\\\\begin{equation}'.length, -'\\\\end{equation}'.length).trim();\n }\n return trimmed;\n}\n\nexport function applyFloatMetaPatch<T extends ImageBlock2 | TableBlock2>(block: T, patch: FloatMetaPatch): void {\n if (typeof patch.centered === 'boolean') {\n block.centered = patch.centered;\n }\n if (typeof patch.captionEnabled === 'boolean') {\n block.captionEnabled = patch.captionEnabled;\n }\n if (typeof patch.caption === 'string') {\n block.caption = patch.caption;\n }\n if (typeof patch.labelEnabled === 'boolean') {\n block.labelEnabled = patch.labelEnabled;\n }\n if (typeof patch.label === 'string') {\n block.label = patch.label;\n }\n}\n","import type { DetectedInlineSpan2, DetectedMathSpan2 } from './types.js';\nimport { parseCiteKeys } from './citations.js';\nimport { parseRefKeys } from './labels.js';\n\nconst MATH_ENVIRONMENTS = new Set([\n 'equation',\n 'equation*',\n 'align',\n 'align*',\n 'aligned',\n 'gather',\n 'gather*',\n 'multline',\n 'multline*',\n]);\n\nfunction isEscaped(value: string, index: number): boolean {\n let slashCount = 0;\n let i = index - 1;\n while (i >= 0 && value[i] === '\\\\') {\n slashCount += 1;\n i -= 1;\n }\n return slashCount % 2 === 1;\n}\n\nfunction findClosingDollar(value: string, start: number): number {\n let i = start;\n while (i < value.length) {\n if (value[i] === '$' && !isEscaped(value, i)) {\n return i;\n }\n i += 1;\n }\n return -1;\n}\n\nfunction environmentSpan(value: string, start: number): DetectedMathSpan2 | null {\n const match = /^\\\\begin\\{([A-Za-z*]+)\\}/.exec(value.slice(start));\n if (!match) {\n return null;\n }\n\n const envName = match[1] ?? '';\n if (!MATH_ENVIRONMENTS.has(envName)) {\n return null;\n }\n\n const opening = match[0] ?? '';\n const closing = `\\\\end{${envName}}`;\n const closingStart = value.indexOf(closing, start + opening.length);\n if (closingStart < 0) {\n return null;\n }\n\n const end = closingStart + closing.length;\n return { start, end, source: value.slice(start, end), opening, closing, display: true };\n}\n\nfunction citeSpan(value: string, start: number): DetectedInlineSpan2 | null {\n if (!value.startsWith('\\\\cite{', start) || isEscaped(value, start)) {\n return null;\n }\n const openBrace = start + '\\\\cite'.length;\n if (value[openBrace] !== '{') {\n return null;\n }\n let depth = 0;\n for (let i = openBrace; i < value.length; i += 1) {\n const char = value[i];\n if (char === '{' && !isEscaped(value, i)) {\n depth += 1;\n continue;\n }\n if (char === '}' && !isEscaped(value, i)) {\n depth -= 1;\n if (depth === 0) {\n const end = i + 1;\n const source = value.slice(start, end);\n return { kind: 'cite', start, end, source, keys: parseCiteKeys(source) };\n }\n }\n }\n return null;\n}\n\nfunction refSpan(value: string, start: number): DetectedInlineSpan2 | null {\n const eqrefPrefix = '\\\\eqref{';\n const refPrefix = '\\\\ref{';\n let refCommand: 'ref' | 'eqref' = 'ref';\n let prefix = refPrefix;\n if (value.startsWith(eqrefPrefix, start) && !isEscaped(value, start)) {\n refCommand = 'eqref';\n prefix = eqrefPrefix;\n } else if (value.startsWith(refPrefix, start) && !isEscaped(value, start)) {\n refCommand = 'ref';\n prefix = refPrefix;\n } else {\n return null;\n }\n\n const openBrace = start + prefix.length - 1;\n if (value[openBrace] !== '{') {\n return null;\n }\n let depth = 0;\n for (let i = openBrace; i < value.length; i += 1) {\n const char = value[i];\n if (char === '{' && !isEscaped(value, i)) {\n depth += 1;\n continue;\n }\n if (char === '}' && !isEscaped(value, i)) {\n depth -= 1;\n if (depth === 0) {\n const end = i + 1;\n const source = value.slice(start, end);\n const parsed = parseRefKeys(source);\n return { kind: 'ref', start, end, source, keys: parsed.keys, refCommand };\n }\n }\n }\n return null;\n}\n\nfunction mathSpanAt(value: string, i: number): DetectedMathSpan2 | null {\n if (value.startsWith('\\\\begin{', i)) {\n return environmentSpan(value, i);\n }\n\n if (value.startsWith('\\\\(', i)) {\n const close = value.indexOf('\\\\)', i + 2);\n if (close >= 0) {\n const end = close + 2;\n return { start: i, end, source: value.slice(i, end), opening: '\\\\(', closing: '\\\\)', display: false };\n }\n }\n\n if (value.startsWith('\\\\[', i)) {\n const close = value.indexOf('\\\\]', i + 2);\n if (close >= 0) {\n const end = close + 2;\n return { start: i, end, source: value.slice(i, end), opening: '\\\\[', closing: '\\\\]', display: true };\n }\n }\n\n if (value.startsWith('$$', i) && !isEscaped(value, i)) {\n const close = value.indexOf('$$', i + 2);\n if (close >= 0) {\n const end = close + 2;\n return { start: i, end, source: value.slice(i, end), opening: '$$', closing: '$$', display: true };\n }\n }\n\n if (value[i] === '$' && !isEscaped(value, i)) {\n const close = findClosingDollar(value, i + 1);\n if (close >= 0) {\n const end = close + 1;\n return { start: i, end, source: value.slice(i, end), opening: '$', closing: '$', display: false };\n }\n }\n\n return null;\n}\n\n/** Math-only spans (used for math_objects alignment counts). */\nexport function detectMathSpans2(value: string): DetectedMathSpan2[] {\n return detectInlineSpans2(value)\n .filter((span): span is DetectedInlineSpan2 & { kind: 'math' } => span.kind === 'math')\n .map(({ kind: _kind, ...span }) => span);\n}\n\n/** Left-to-right math + \\\\cite + \\\\ref/\\\\eqref spans without overlap. */\nexport function detectInlineSpans2(value: string): DetectedInlineSpan2[] {\n const spans: DetectedInlineSpan2[] = [];\n let i = 0;\n\n while (i < value.length) {\n const cite = citeSpan(value, i);\n if (cite) {\n spans.push(cite);\n i = cite.end;\n continue;\n }\n\n const ref = refSpan(value, i);\n if (ref) {\n spans.push(ref);\n i = ref.end;\n continue;\n }\n\n const math = mathSpanAt(value, i);\n if (math) {\n spans.push({ kind: 'math', ...math });\n i = math.end;\n continue;\n }\n\n i += 1;\n }\n\n return spans;\n}\n","import { fromMathObjectJson } from '../document/mathObject.js';\nimport { normalizeDocument2Meta, emptyDocument2Meta } from './articleMeta.js';\nimport { referenceFromJson } from './citations.js';\nimport { document2Id } from './ids.js';\nimport { detectInlineSpans2, detectMathSpans2 } from './inlineScanner.js';\nimport { parseFloatMetaFromJson } from './labels.js';\nimport type {\n BibliographyBlock2,\n Document2Block,\n Document2BlockJson,\n Document2Diagnostic,\n Document2MathObjectJson,\n Document2ListItemJson,\n Document2Node,\n Document2ParseMode,\n ImageBlock2,\n ImportDocument2Options,\n InlineField2,\n InlineToken2,\n ListBlock2,\n ListItem2,\n RawBlock2,\n Reference2,\n Reference2Json,\n TableBlock2,\n TextFormatSpan2Json,\n TextStyle2,\n TextBlock2,\n} from './types.js';\n\nconst TEXT_COMMANDS = new Set(['\\\\section', '\\\\subsection', '\\\\subsubsection', '\\\\paragraph']);\nconst LIST_COMMANDS = new Set(['\\\\begin{itemize}', '\\\\begin{enumerate}']);\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nfunction requireString(value: unknown, message: string): string {\n if (typeof value !== 'string') {\n throw new Error(message);\n }\n return value;\n}\n\nfunction isRecordOfStrings(value: unknown): value is Record<string, string> {\n return isObject(value) && Object.values(value).every((entry) => typeof entry === 'string');\n}\n\nfunction asBlockJson(value: unknown): Document2BlockJson {\n if (!isObject(value)) {\n throw new Error('Document block must be an object');\n }\n if (typeof value.command !== 'string') {\n throw new Error('Document block requires string command');\n }\n return value as Document2BlockJson;\n}\n\nfunction pushDiagnostic(diagnostics: Document2Diagnostic[], options: ImportDocument2Options, path: string, message: string): void {\n if (options.strict) {\n throw new Error(message);\n }\n diagnostics.push({ code: 'math_alignment', message, path });\n}\n\nfunction parseReferences(json: unknown): Reference2[] {\n if (!Array.isArray(json)) {\n return [];\n }\n const references: Reference2[] = [];\n for (const entry of json) {\n if (!isObject(entry) || typeof entry.key !== 'string' || entry.key.trim().length === 0) {\n continue;\n }\n references.push(\n referenceFromJson({\n key: entry.key.trim(),\n authors: typeof entry.authors === 'string' ? entry.authors : undefined,\n title: typeof entry.title === 'string' ? entry.title : undefined,\n year: typeof entry.year === 'string' ? entry.year : undefined,\n url: typeof entry.url === 'string' ? entry.url : undefined,\n venue: typeof entry.venue === 'string' ? entry.venue : undefined,\n field_separator:\n entry.field_separator === ',' || entry.field_separator === '،'\n ? entry.field_separator\n : undefined,\n } satisfies Reference2Json),\n );\n }\n return references;\n}\n\nexport function createInlineField2(\n value = '',\n mathObjects: Array<Document2MathObjectJson | null> = [],\n options: ImportDocument2Options = {},\n path = '$',\n diagnostics: Document2Diagnostic[] = [],\n formats: TextFormatSpan2Json[] = [],\n): InlineField2 {\n const mode: Document2ParseMode = options.mode ?? 'english';\n const spans = detectInlineSpans2(value);\n const mathSpans = spans.filter((span) => span.kind === 'math');\n const tokens: InlineToken2[] = [];\n let index = 0;\n let mathObjectIndex = 0;\n\n if (mathObjects.length > 0 && mathObjects.length !== mathSpans.length) {\n pushDiagnostic(diagnostics, options, path, `math_objects count mismatch: detected ${String(mathSpans.length)}, got ${String(mathObjects.length)}`);\n }\n\n for (const span of spans) {\n if (span.start > index) {\n pushFormattedTextTokens(tokens, value.slice(index, span.start), index, formats);\n }\n\n if (span.kind === 'cite') {\n tokens.push({\n id: document2Id('cite'),\n kind: 'cite',\n keys: span.keys.length > 0 ? span.keys : [],\n });\n index = span.end;\n continue;\n }\n\n if (span.kind === 'ref') {\n tokens.push({\n id: document2Id('ref'),\n kind: 'ref',\n keys: span.keys.length > 0 ? span.keys : [],\n refCommand: span.refCommand,\n });\n index = span.end;\n continue;\n }\n\n const mathJson = mathObjects[mathObjectIndex];\n mathObjectIndex += 1;\n const structuredMathJson = mathJson?.node_type === 'MathObject' ? mathJson : null;\n if (structuredMathJson && (structuredMathJson.math_mode !== span.opening || structuredMathJson.closing !== span.closing)) {\n pushDiagnostic(diagnostics, options, path, 'math_objects order mismatch');\n }\n\n if (structuredMathJson && structuredMathJson.math_mode === span.opening && structuredMathJson.closing === span.closing) {\n tokens.push({\n id: document2Id('math'),\n kind: 'math',\n display: span.display,\n opening: span.opening,\n closing: span.closing,\n source: span.source,\n sourceSide:\n structuredMathJson.source_side === 'arabic' || structuredMathJson.source_side === 'english'\n ? structuredMathJson.source_side\n : mode,\n math: fromMathObjectJson(structuredMathJson, mode),\n editable: true,\n sourceOwner: structuredMathJson.source_owner === 'editor' ? 'editor' : 'imported-structured',\n ...(typeof structuredMathJson.label_enabled === 'boolean' ? { labelEnabled: structuredMathJson.label_enabled } : {}),\n ...(typeof structuredMathJson.label === 'string' ? { label: structuredMathJson.label } : {}),\n });\n } else {\n tokens.push({\n id: document2Id('math'),\n kind: 'math',\n display: span.display,\n opening: span.opening,\n closing: span.closing,\n source: span.source,\n math: null,\n editable: false,\n reason: 'هذه المعادلة محفوظة كنص خام فقط حاليا',\n sourceOwner: 'raw',\n ...(mathJson?.node_type === 'RawMathObject' && typeof mathJson.label_enabled === 'boolean'\n ? { labelEnabled: mathJson.label_enabled }\n : {}),\n ...(mathJson?.node_type === 'RawMathObject' && typeof mathJson.label === 'string'\n ? { label: mathJson.label }\n : {}),\n });\n }\n\n index = span.end;\n }\n\n if (index < value.length || tokens.length === 0) {\n pushFormattedTextTokens(tokens, value.slice(index), index, formats);\n }\n\n return { id: document2Id('field'), tokens: compactTextTokens(tokens) };\n}\n\nfunction styleFromFormat(format: TextFormatSpan2Json): TextStyle2 | null {\n const style: TextStyle2 = {};\n if (format.bold === true) {\n style.bold = true;\n }\n if (format.italic === true) {\n style.italic = true;\n }\n if (format.underline === true) {\n style.underline = true;\n }\n return style.bold || style.italic || style.underline ? style : null;\n}\n\nfunction mergeTextStyle(base: TextStyle2 | undefined, added: TextStyle2): TextStyle2 {\n return {\n ...(base?.bold ? { bold: true as const } : {}),\n ...(base?.italic ? { italic: true as const } : {}),\n ...(base?.underline ? { underline: true as const } : {}),\n ...(added.bold ? { bold: true as const } : {}),\n ...(added.italic ? { italic: true as const } : {}),\n ...(added.underline ? { underline: true as const } : {}),\n };\n}\n\nfunction textStylesEqual(a: TextStyle2 | undefined, b: TextStyle2 | undefined): boolean {\n return Boolean(a?.bold) === Boolean(b?.bold) && Boolean(a?.italic) === Boolean(b?.italic) && Boolean(a?.underline) === Boolean(b?.underline);\n}\n\nfunction compactTextTokens(tokens: InlineToken2[]): InlineToken2[] {\n const compacted: InlineToken2[] = [];\n for (const token of tokens) {\n const previous = compacted[compacted.length - 1];\n if (previous?.kind === 'text' && token.kind === 'text' && textStylesEqual(previous.style, token.style)) {\n previous.text += token.text;\n } else {\n compacted.push(token);\n }\n }\n return compacted;\n}\n\nfunction styleKey(style: TextStyle2 | undefined): string {\n return `${style?.bold ? 'b' : ''}${style?.italic ? 'i' : ''}${style?.underline ? 'u' : ''}`;\n}\n\nfunction pushFormattedTextTokens(tokens: InlineToken2[], text: string, sourceStart: number, formats: TextFormatSpan2Json[]): void {\n if (text.length === 0) {\n tokens.push({ id: document2Id('text'), kind: 'text', text });\n return;\n }\n const styles: Array<TextStyle2 | undefined> = Array.from({ length: text.length });\n for (const format of formats) {\n const style = styleFromFormat(format);\n if (!style || !Number.isFinite(format.start) || !Number.isFinite(format.end)) {\n continue;\n }\n const start = Math.max(0, Math.min(text.length, Math.trunc(format.start) - sourceStart));\n const end = Math.max(0, Math.min(text.length, Math.trunc(format.end) - sourceStart));\n if (end <= start) {\n continue;\n }\n for (let index = start; index < end; index += 1) {\n styles[index] = mergeTextStyle(styles[index], style);\n }\n }\n\n let chunkStart = 0;\n for (let index = 1; index <= text.length; index += 1) {\n if (index < text.length && styleKey(styles[index]) === styleKey(styles[chunkStart])) {\n continue;\n }\n const chunk = text.slice(chunkStart, index);\n const style = styles[chunkStart];\n tokens.push({ id: document2Id('text'), kind: 'text', text: chunk, ...(style ? { style } : {}) });\n chunkStart = index;\n }\n}\n\nfunction closingForList(command: '\\\\begin{itemize}' | '\\\\begin{enumerate}'): '\\\\end{itemize}' | '\\\\end{enumerate}' {\n return command === '\\\\begin{itemize}' ? '\\\\end{itemize}' : '\\\\end{enumerate}';\n}\n\nfunction parseTextBlock(json: Document2BlockJson, options: ImportDocument2Options, path: string, diagnostics: Document2Diagnostic[]): TextBlock2 {\n const value = requireString(json.value, `${json.command} requires string value`);\n return {\n id: document2Id('block'),\n kind: 'textBlock',\n command: json.command as TextBlock2['command'],\n field: createInlineField2(value, json.math_objects ?? [], options, `${path}.value`, diagnostics, json.command === '\\\\paragraph' ? json.formats ?? [] : []),\n ...(json.centered === true ? { centered: true } : {}),\n };\n}\n\nfunction parseListItem(json: Document2ListItemJson, options: ImportDocument2Options, path: string, diagnostics: Document2Diagnostic[]): ListItem2 {\n const value = requireString(json.value, 'Document list item requires string value');\n const blocksJson = Array.isArray(json.blocks) ? json.blocks : [];\n return {\n id: document2Id('item'),\n field: createInlineField2(value, json.math_objects ?? [], options, `${path}.value`, diagnostics, json.formats ?? []),\n blocks: blocksJson.map((block, index) => parseBlock(asBlockJson(block), options, `${path}.blocks[${String(index)}]`, diagnostics)),\n };\n}\n\nfunction parseListBlock(json: Document2BlockJson, options: ImportDocument2Options, path: string, diagnostics: Document2Diagnostic[]): ListBlock2 {\n if (!Array.isArray(json.items)) {\n throw new Error(`${json.command} requires items array`);\n }\n const command = json.command as ListBlock2['command'];\n const closing = closingForList(command);\n return {\n id: document2Id('block'),\n kind: 'list',\n command,\n closing,\n items: json.items.map((item, index) => parseListItem(item, options, `${path}.items[${String(index)}]`, diagnostics)),\n };\n}\n\nfunction parseTableBlock(json: Document2BlockJson, options: ImportDocument2Options, path: string, diagnostics: Document2Diagnostic[]): TableBlock2 {\n if (!Array.isArray(json.rows)) {\n throw new Error('\\\\begin{tabular} requires rows array');\n }\n\n const mathObjects = json.math_objects ?? [];\n let mathObjectIndex = 0;\n const rows = json.rows.map((row, rowIndex) => {\n if (!Array.isArray(row)) {\n throw new Error('\\\\begin{tabular} rows must be arrays');\n }\n return row.map((cell, columnIndex) => {\n const value = requireString(cell, '\\\\begin{tabular} cells must be strings');\n const spanCount = detectMathSpans2(value).length;\n const cellMathObjects = mathObjects.slice(mathObjectIndex, mathObjectIndex + spanCount);\n mathObjectIndex += spanCount;\n const cellFormats = json.cell_formats?.[rowIndex]?.[columnIndex] ?? [];\n return createInlineField2(value, cellMathObjects, options, `${path}.rows[${String(rowIndex)}][${String(columnIndex)}]`, diagnostics, cellFormats);\n });\n });\n\n if (mathObjects.length > 0 && mathObjects.length !== mathObjectIndex) {\n pushDiagnostic(diagnostics, options, path, `math_objects count mismatch: detected ${String(mathObjectIndex)}, got ${String(mathObjects.length)}`);\n }\n\n return {\n id: document2Id('block'),\n kind: 'table',\n command: '\\\\begin{tabular}',\n closing: '\\\\end{tabular}',\n columns: typeof json.columns === 'string' ? json.columns : '',\n rows,\n ...parseFloatMetaFromJson(json),\n };\n}\n\nfunction parseImageBlock(json: Document2BlockJson): ImageBlock2 {\n const assetId = typeof json.asset_id === 'string' && json.asset_id.length > 0 ? json.asset_id : undefined;\n const value =\n assetId !== undefined\n ? typeof json.value === 'string'\n ? json.value\n : ''\n : requireString(json.value, '\\\\includegraphics requires string value');\n return {\n id: document2Id('block'),\n kind: 'image',\n command: '\\\\includegraphics',\n value,\n ...(assetId !== undefined ? { assetId } : {}),\n options: isRecordOfStrings(json.options) ? json.options : {},\n ...parseFloatMetaFromJson(json),\n };\n}\n\nfunction parseRawBlock(json: Document2BlockJson): RawBlock2 {\n return {\n id: document2Id('block'),\n kind: 'raw',\n command: '\\\\raw',\n value: typeof json.value === 'string' ? json.value : '',\n };\n}\n\nfunction parseBibliographyBlock(): BibliographyBlock2 {\n return {\n id: document2Id('block'),\n kind: 'bibliography',\n command: '\\\\begin{thebibliography}',\n closing: '\\\\end{thebibliography}',\n };\n}\n\nfunction parseBlock(json: Document2BlockJson, options: ImportDocument2Options, path: string, diagnostics: Document2Diagnostic[]): Document2Block {\n if (TEXT_COMMANDS.has(json.command)) {\n return parseTextBlock(json, options, path, diagnostics);\n }\n if (LIST_COMMANDS.has(json.command)) {\n return parseListBlock(json, options, path, diagnostics);\n }\n if (json.command === '\\\\begin{tabular}') {\n return parseTableBlock(json, options, path, diagnostics);\n }\n if (json.command === '\\\\includegraphics') {\n return parseImageBlock(json);\n }\n if (json.command === '\\\\begin{thebibliography}' || json.command === '\\\\bibliography') {\n return parseBibliographyBlock();\n }\n if (json.command === '\\\\raw') {\n return parseRawBlock(json);\n }\n return {\n id: document2Id('block'),\n kind: 'raw',\n command: '\\\\raw',\n value: typeof json.value === 'string' ? json.value : json.command,\n };\n}\n\nexport function fromDocumentJson2(json: unknown, options: ImportDocument2Options = {}): Document2Node {\n if (!isObject(json) || json.node_type !== 'DocumentObject') {\n throw new Error('DocumentObject requires node_type \"DocumentObject\"');\n }\n if (!Array.isArray(json.blocks)) {\n throw new Error('DocumentObject requires blocks array');\n }\n\n const diagnostics: Document2Diagnostic[] = [];\n return {\n nodeType: 'DocumentObject',\n meta: normalizeDocument2Meta(json.meta),\n references: parseReferences(json.references),\n blocks: json.blocks.map((block, index) => parseBlock(asBlockJson(block), options, `$.blocks[${String(index)}]`, diagnostics)),\n diagnostics,\n };\n}\n\nexport function createEmptyDocument2(): Document2Node {\n return {\n nodeType: 'DocumentObject',\n meta: emptyDocument2Meta(),\n references: [],\n blocks: [],\n diagnostics: [],\n };\n}\n","export type AccentPlacement = 'over' | 'under';\n\nexport const ACCENT_COMMANDS = {\n vec: {\n id: 'vec',\n englishTex: '\\\\vec',\n arabicTex: '\\\\arabvec',\n placement: 'over' as const,\n label: '⃗',\n title: 'سهم فوق',\n },\n hat: {\n id: 'hat',\n englishTex: '\\\\hat',\n arabicTex: '\\\\hat',\n placement: 'over' as const,\n label: 'ˆ',\n title: 'قبعة',\n },\n tilde: {\n id: 'tilde',\n englishTex: '\\\\tilde',\n arabicTex: '\\\\tilde',\n placement: 'over' as const,\n label: '˜',\n title: 'مدة',\n },\n dot: {\n id: 'dot',\n englishTex: '\\\\dot',\n arabicTex: '\\\\dot',\n placement: 'over' as const,\n label: '˙',\n title: 'نقطة فوق',\n },\n ddot: {\n id: 'ddot',\n englishTex: '\\\\ddot',\n arabicTex: '\\\\ddot',\n placement: 'over' as const,\n label: '¨',\n title: 'نقطتان فوق',\n },\n dddot: {\n id: 'dddot',\n englishTex: '\\\\dddot',\n arabicTex: '\\\\dddot',\n placement: 'over' as const,\n label: '⃛',\n title: 'ثلاث نقاط فوق',\n },\n bar: {\n id: 'bar',\n englishTex: '\\\\bar',\n arabicTex: '\\\\bar',\n placement: 'over' as const,\n label: '¯',\n title: 'خط فوق',\n },\n check: {\n id: 'check',\n englishTex: '\\\\check',\n arabicTex: '\\\\check',\n placement: 'over' as const,\n label: 'ˇ',\n title: 'علامة تحقق',\n },\n breve: {\n id: 'breve',\n englishTex: '\\\\breve',\n arabicTex: '\\\\breve',\n placement: 'over' as const,\n label: '˘',\n title: 'قوس قصير',\n },\n acute: {\n id: 'acute',\n englishTex: '\\\\acute',\n arabicTex: '\\\\grave',\n placement: 'over' as const,\n label: '´',\n title: 'نبرة حادة',\n },\n grave: {\n id: 'grave',\n englishTex: '\\\\grave',\n arabicTex: '\\\\acute',\n placement: 'over' as const,\n label: '`',\n title: 'نبرة ثقيلة',\n },\n overline: {\n id: 'overline',\n englishTex: '\\\\overline',\n arabicTex: '\\\\overline',\n placement: 'over' as const,\n label: '‾',\n title: 'خط علوي ممتد',\n },\n underline: {\n id: 'underline',\n englishTex: '\\\\underline',\n arabicTex: '\\\\underline',\n placement: 'under' as const,\n label: '_',\n title: 'خط سفلي',\n },\n overleftarrow: {\n id: 'overleftarrow',\n englishTex: '\\\\overleftarrow',\n arabicTex: '\\\\overrightarrow',\n placement: 'over' as const,\n label: '←',\n title: 'سهم علوي إلى اليسار',\n },\n overrightarrow: {\n id: 'overrightarrow',\n englishTex: '\\\\overrightarrow',\n arabicTex: '\\\\overleftarrow',\n placement: 'over' as const,\n label: '→',\n title: 'سهم علوي إلى اليمين',\n },\n overleftrightarrow: {\n id: 'overleftrightarrow',\n englishTex: '\\\\overleftrightarrow',\n arabicTex: '\\\\overleftrightarrow',\n placement: 'over' as const,\n label: '↔',\n title: 'سهم علوي مزدوج الاتجاه',\n },\n} as const;\n\nexport type AccentCommandId = keyof typeof ACCENT_COMMANDS;\n\nexport type AccentCommandSpec = (typeof ACCENT_COMMANDS)[AccentCommandId] & {\n placement: AccentPlacement;\n};\n\nexport function accentCommandSpec(id: string): AccentCommandSpec | null {\n return Object.prototype.hasOwnProperty.call(ACCENT_COMMANDS, id)\n ? ACCENT_COMMANDS[id as AccentCommandId]\n : null;\n}\n\nexport function accentCommandsList(): AccentCommandSpec[] {\n return Object.values(ACCENT_COMMANDS);\n}\n\n/** Resolve accent id from a TeX command name like `\\hat` or `\\arabvec`. */\nexport function accentCommandIdFromTex(tex: string): AccentCommandId | null {\n const normalized = tex.startsWith('\\\\') ? tex : `\\\\${tex}`;\n for (const spec of Object.values(ACCENT_COMMANDS)) {\n if (spec.englishTex === normalized) {\n return spec.id;\n }\n }\n for (const spec of Object.values(ACCENT_COMMANDS)) {\n if (spec.arabicTex === normalized) {\n return spec.id;\n }\n }\n return null;\n}\n","export const ATOMIC_COMMANDS = {\n ///////////////////////// Functions ////////////////////////////////\n\n //////////////// Trigonometric Functions \n cos: {\n id: 'cos',\n category: 'function',\n englishTex: '\\\\cos',\n arabicTex: '\\\\arcos',\n arabicLabel: 'جتا',\n title: 'جيب التمام',\n },\n sin: {\n id: 'sin',\n category: 'function',\n englishTex: '\\\\sin',\n arabicTex: '\\\\arsin',\n arabicLabel: 'جا',\n title: 'جيب',\n },\n tan: {\n id: 'tan',\n category: 'function',\n englishTex: '\\\\tan',\n arabicTex: '\\\\artan',\n arabicLabel: 'ظا',\n title: 'ظل',\n },\n cot: {\n id: 'cot',\n category: 'function',\n englishTex: '\\\\cot',\n arabicTex: '\\\\arcot',\n arabicLabel: 'ظتا',\n title: 'ظل تمام',\n },\n sec: {\n id: 'sec',\n category: 'function',\n englishTex: '\\\\sec',\n arabicTex: '\\\\arsec',\n arabicLabel: 'قا',\n title: 'قاطع',\n },\n csc: {\n id: 'csc',\n category: 'function',\n englishTex: '\\\\csc',\n arabicTex: '\\\\arcsc',\n arabicLabel: 'قتا',\n title: 'قاطع تمام',\n },\n\n\n /////////////////// Arc Trigonometric Functions \n arccos: {\n id: 'arccos',\n category: 'function',\n englishTex: '\\\\arccos',\n arabicTex: '\\\\aracos',\n arabicLabel: 'قجتا',\n title: 'قاطع جيب التمام',\n },\n arcsin: {\n id: 'arcsin',\n category: 'function',\n englishTex: '\\\\arcsin',\n arabicTex: '\\\\arasin',\n arabicLabel: 'قجا',\n title: 'قاطع جيب',\n },\n arctan: {\n id: 'arctan',\n category: 'function',\n englishTex: '\\\\arctan',\n arabicTex: '\\\\aratan',\n arabicLabel: 'قظا',\n title: 'قاطع ظل',\n },\n arccot: {\n id: 'arccot',\n category: 'function',\n englishTex: '\\\\arccot',\n arabicTex: '\\\\aracot',\n arabicLabel: 'قظتا',\n title: 'قاطع ظل التمام',\n },\n arcsec: {\n id: 'arcsec',\n category: 'function',\n englishTex: '\\\\arcsec',\n arabicTex: '\\\\arasec',\n arabicLabel: 'ققا',\n title: 'قاطع القاطع',\n },\n arccsc: {\n id: 'arccsc',\n category: 'function',\n englishTex: '\\\\arccsc',\n arabicTex: '\\\\aracsc',\n arabicLabel: 'ققتا',\n title: 'قاطع القاطع التمام',\n },\n\n ///////////////// Hyperbolic Functions \n cosh: {\n id: 'cosh',\n category: 'function',\n englishTex: '\\\\cosh',\n arabicTex: '\\\\arcosh',\n arabicLabel: 'جتزا',\n title: 'جيب التمام الزائد',\n },\n sinh: {\n id: 'sinh',\n category: 'function',\n englishTex: '\\\\sinh',\n arabicTex: '\\\\arsinh',\n arabicLabel: 'جزا',\n title: 'جيب الزائد',\n },\n tanh: {\n id: 'tanh',\n category: 'function',\n englishTex: '\\\\tanh',\n arabicTex: '\\\\artanh',\n arabicLabel: 'ظزا',\n title: 'ظل الزائد',\n },\n coth: {\n id: 'coth',\n category: 'function',\n englishTex: '\\\\coth',\n arabicTex: '\\\\arcoth',\n arabicLabel: 'ظتزا',\n title: 'ظل تمام الزائد',\n },\n\n ////// These function somehow doesnt exist in LaTeX and therefore MathJax, skip for now. no problem.\n // sech: {\n // id: 'sech',\n // category: 'function',\n // englishTex: '\\\\sech',\n // arabicTex: '\\\\arsech',\n // arabicLabel: 'قزا',\n // title: 'قاطع الزائد',\n // },\n // csch: {\n // id: 'csch',\n // category: 'function',\n // englishTex: '\\\\csch',\n // arabicTex: '\\\\arcsch',\n // arabicLabel: 'قتزا',\n // title: 'قاطع تمام الزائد',\n // },\n\n\n ///////////////// arc Hyperbolic Functions \n ///// Not on MathJax, skip for now, it is okay.\n\n\n\n ////////////////////// Limits & Series ////////////////////////////////\n sum: {\n id: 'sum',\n category: 'limits_series',\n englishTex: '\\\\sum',\n arabicTex: '\\\\arsum',\n arabicLabel: 'مجـــ',\n title: 'مجموع',\n },\n prod: {\n id: 'prod',\n category: 'limits_series',\n englishTex: '\\\\prod',\n arabicTex: '\\\\arprod',\n arabicLabel: 'جـــد',\n title: 'جداء',\n },\n lim: {\n id: 'lim',\n category: 'limits_series',\n englishTex: '\\\\lim',\n arabicTex: '\\\\arlim',\n arabicLabel: 'نـــــها',\n title: 'حد',\n },\n max: {\n id: 'max',\n category: 'limits_series',\n englishTex: '\\\\max',\n arabicTex: '\\\\armax',\n arabicLabel: 'أكبر',\n title: 'أكبر',\n },\n min: {\n id: 'min',\n category: 'limits_series',\n englishTex: '\\\\min',\n arabicTex: '\\\\armin',\n arabicLabel: 'أصغر',\n title: 'أصغر',\n },\n sup: {\n id: 'sup',\n category: 'limits_series',\n englishTex: '\\\\sup',\n arabicTex: '\\\\arsup',\n arabicLabel: 'أعلى',\n title: 'أعلى',\n },\n inf: {\n id: 'inf',\n category: 'limits_series',\n englishTex: '\\\\inf',\n arabicTex: '\\\\arinf',\n arabicLabel: 'أدنى',\n title: 'أدنى',\n },\n\n ////////////////////// Logarithmic and Exponential and Determinant Functions ////////////////////////////////\n pi: {\n id: 'pi',\n category: 'function2',\n englishTex: '\\\\pi',\n arabicTex: '\\\\arpi',\n arabicLabel: 'ط',\n title: 'نسبة الدائرة',\n },\n exp: {\n id: 'exp',\n category: 'function2',\n englishTex: '\\\\exp',\n arabicTex: '\\\\arexp',\n arabicLabel: 'هـ',\n title: 'أسية',\n },\n ln: {\n id: 'ln',\n category: 'function2',\n englishTex: '\\\\ln',\n arabicTex: '\\\\arln',\n arabicRenderTex: '\\\\prescript{}{\\\\arexp}{\\\\arlog}',\n arabicLabel: 'لو',\n title: 'لوغاريتم طبيعي',\n },\n log: {\n id: 'log',\n category: 'function2',\n englishTex: '\\\\log',\n arabicTex: '\\\\arlog',\n arabicLabel: 'لو',\n title: 'لوغاريتم',\n },\n det: {\n id: 'det',\n category: 'function2',\n englishTex: '\\\\det',\n arabicTex: '\\\\ardet',\n arabicLabel: 'محدد',\n title: 'محدد',\n },\n\n ////////////////////// Derivatives ////////////////////////////////\n ad: {\n id: 'ad',\n category: 'derivative',\n englishTex: '\\\\mathrm{d}',\n englishLabel: 'd',\n arabicTex: '\\\\ad',\n arabicLabel: 'ء',\n title: 'علامة الاشتقاق',\n },\n\n ////////////////////// Groups /////////////////////////////////\n N: {\n id: 'N',\n category: 'groups',\n englishTex: '\\\\mathbb{N}',\n arabicTex: '\\\\arabN',\n arabicLabel: 'ط',\n title: 'أعداد طبيعية',\n },\n Z: {\n id: 'Z',\n category: 'groups',\n englishTex: '\\\\mathbb{Z}',\n arabicTex: '\\\\arabZ',\n arabicLabel: 'ص',\n title: 'أعداد صحيحة',\n },\n Q: {\n id: 'Q',\n category: 'groups',\n englishTex: '\\\\mathbb{Q}',\n arabicTex: '\\\\arabQ',\n arabicLabel: 'ن',\n title: 'أعداد نسبية',\n },\n R: {\n id: 'R',\n category: 'groups',\n englishTex: '\\\\mathbb{R}',\n arabicTex: '\\\\arabR',\n arabicLabel: 'ح',\n title: 'أعداد حقيقية',\n },\n C: {\n id: 'C',\n category: 'groups',\n englishTex: '\\\\mathbb{C}',\n arabicTex: '\\\\arabC',\n arabicLabel: 'ع',\n title: 'أعداد عُقدية',\n },\n H: {\n id: 'H',\n category: 'groups',\n englishTex: '\\\\mathbb{H}',\n arabicTex: '\\\\arabH',\n arabicLabel: 'ر',\n title: 'أعداد رباعية',\n },\n\n ////////////////////// Operations ////////////////////////////\n\n\n ////////////////////// Spacing ////////////////////////////////\n negThinSpace: {\n id: 'negThinSpace',\n category: 'spacing',\n englishTex: '\\\\!',\n arabicTex: '\\\\!',\n arabicLabel: '',\n title: 'فراغ سالب رفيع',\n spacing: { direction: 'negative', level: 1 },\n },\n mediumSpace: {\n id: 'mediumSpace',\n category: 'spacing',\n englishTex: '\\\\:',\n arabicTex: '\\\\:',\n arabicLabel: '',\n title: 'فراغ متوسط',\n spacing: { direction: 'positive', level: 1 },\n },\n thickSpace: {\n id: 'thickSpace',\n category: 'spacing',\n englishTex: '\\\\;',\n arabicTex: '\\\\;',\n arabicLabel: '',\n title: 'فراغ عريض',\n spacing: { direction: 'positive', level: 2 },\n },\n quadSpace: {\n id: 'quadSpace',\n category: 'spacing',\n englishTex: '\\\\quad',\n arabicTex: '\\\\quad',\n arabicLabel: '',\n title: 'فراغ كبير',\n spacing: { direction: 'positive', level: 3 },\n },\n qquadSpace: {\n id: 'qquadSpace',\n category: 'spacing',\n englishTex: '\\\\qquad',\n arabicTex: '\\\\qquad',\n arabicLabel: '',\n title: 'فراغ كبير جدا',\n spacing: { direction: 'positive', level: 4 },\n },\n} as const;\n\nexport type AtomicCommandId = keyof typeof ATOMIC_COMMANDS;\nexport type AtomicCommandCategory = 'function' | 'function2' | 'limits_series' | 'groups' | 'spacing' | 'derivative';\nexport type SpacingDirection = 'positive' | 'negative';\n\nexport type AtomicCommandSpec = (typeof ATOMIC_COMMANDS)[AtomicCommandId] & {\n arabicRenderTex?: string;\n englishLabel?: string;\n};\nexport type SpacingCommandSpec = AtomicCommandSpec & {\n category: 'spacing';\n spacing: {\n direction: SpacingDirection;\n level: 1 | 2 | 3 | 4;\n };\n};\n\nexport function atomicCommandsByCategory(category: AtomicCommandCategory): AtomicCommandSpec[] {\n return Object.values(ATOMIC_COMMANDS).filter((command) => command.category === category);\n}\n\nexport function isSpacingCommandSpec(spec: AtomicCommandSpec | null): spec is SpacingCommandSpec {\n return spec?.category === 'spacing';\n}\n\nexport function atomicCommandSpec(id: string): AtomicCommandSpec | null {\n return Object.prototype.hasOwnProperty.call(ATOMIC_COMMANDS, id)\n ? ATOMIC_COMMANDS[id as AtomicCommandId]\n : null;\n}\n","export const ATOMIC_OPERATOR_COMMANDS = {\n inf: {\n id: 'inf',\n category: 'operators1',\n Tex: '\\\\infty',\n mirror: true,\n Label: '∞',\n title: 'اللانهاية',\n svg_path: null,\n },\n times: {\n id: 'times',\n category: 'operators1',\n Tex: '\\\\times',\n mirror: false,\n Label: '×',\n title: 'ضرب',\n svg_path: null,\n },\n div: {\n id: 'div',\n category: 'operators1',\n Tex: '\\\\div',\n mirror: false,\n Label: '÷',\n title: 'قسمة',\n svg_path: null,\n },\n pm: {\n id: 'pm',\n category: 'operators1',\n Tex: '\\\\pm',\n mirror: false,\n Label: '±',\n title: 'زائد أو ناقص',\n svg_path: null,\n },\n mp: {\n id: 'mp',\n category: 'operators1',\n Tex: '\\\\mp',\n mirror: false,\n Label: '∓',\n title: 'ناقص أو زائد',\n svg_path: null,\n },\n neq: {\n id: 'neq',\n category: 'operators1',\n Tex: '\\\\neq',\n mirror: true,\n compileMirror: true,\n Label: '≠',\n title: 'لا يساوي',\n svg_path: null,\n },\n approx: {\n id: 'approx',\n category: 'operators1',\n Tex: '\\\\approx',\n mirror: false,\n displayMirror: true,\n Label: '≈',\n title: 'تقريبا يساوي',\n svg_path: null,\n },\n sim: {\n id: 'sim',\n category: 'operators1',\n Tex: '\\\\sim',\n mirror: false,\n displayMirror: true,\n Label: '∼',\n title: 'مشابه',\n svg_path: null,\n },\n mid: {\n id: 'mid',\n category: 'operators1',\n Tex: '\\\\mid',\n mirror: false,\n Label: '∣',\n title: 'يقسم',\n svg_path: null,\n },\n leq: {\n id: 'leq',\n category: 'operators1',\n Tex: '\\\\leq',\n mirror: true,\n displayMirror: false,\n compileMirror: true,\n Label: '≤',\n title: 'أصغر من أو يساوي',\n svg_path: null,\n },\n geq: {\n id: 'geq',\n category: 'operators1',\n Tex: '\\\\geq',\n mirror: true,\n displayMirror: false,\n compileMirror: true,\n Label: '≥',\n title: 'أكبر من أو يساوي',\n svg_path: null,\n },\n coloneqq: {\n id: 'coloneqq',\n category: 'operators1',\n Tex: '\\\\coloneqq',\n mirror: true,\n displayMirror: false,\n compileMirror: true,\n Label: '≔',\n title: 'يعرف بأنه يساوي',\n svg_path: null,\n },\n eqqcolon: {\n id: 'eqqcolon',\n category: 'operators1',\n Tex: '\\\\eqqcolon',\n mirror: true,\n displayMirror: false,\n compileMirror: true,\n Label: '≕',\n title: 'يساوي بالتعريف',\n svg_path: null,\n },\n\n ///// Operators 2\n propto: {\n id: 'propto',\n category: 'operators2',\n Tex: '\\\\propto',\n mirror: true,\n displayMirror: false,\n compileMirror: true,\n Label: '∝',\n title: 'يتناسب مع',\n svg_path: null,\n },\n in: {\n id: 'in',\n category: 'operators2',\n Tex: '\\\\in',\n mirror: true,\n displayMirror: false,\n compileMirror: true,\n Label: '∈',\n title: 'ينتمي إلى',\n svg_path: null,\n },\n notin: {\n id: 'notin',\n category: 'operators2',\n Tex: '\\\\notin',\n mirror: false,\n displayMirror: true,\n Label: '∉',\n title: 'لا ينتمي إلى',\n svg_path: null,\n },\n subset: {\n id: 'subset',\n category: 'operators2',\n Tex: '\\\\subset',\n mirror: true,\n displayMirror: false,\n compileMirror: true,\n Label: '⊂',\n title: 'مجموعة جزئية من',\n svg_path: null,\n },\n supset: {\n id: 'supset',\n category: 'operators2',\n Tex: '\\\\supset',\n mirror: true,\n displayMirror: false,\n compileMirror: true,\n Label: '⊃',\n title: 'مجموعة شاملة لـ',\n svg_path: null,\n },\n subseteq: {\n id: 'subseteq',\n category: 'operators2',\n Tex: '\\\\subseteq',\n mirror: true,\n displayMirror: false,\n compileMirror: true,\n Label: '⊆',\n title: 'مجموعة جزئية أو تساوي',\n svg_path: null,\n },\n supseteq: {\n id: 'supseteq',\n category: 'operators2',\n Tex: '\\\\supseteq',\n mirror: true,\n displayMirror: false,\n compileMirror: true,\n Label: '⊇',\n title: 'مجموعة شاملة أو تساوي',\n svg_path: null,\n },\n cap: {\n id: 'cap',\n category: 'operators2',\n Tex: '\\\\cap',\n mirror: false,\n displayMirror: true,\n Label: '∩',\n title: 'تقاطع',\n svg_path: null,\n },\n cup: {\n id: 'cup',\n category: 'operators2',\n Tex: '\\\\cup',\n mirror: false,\n displayMirror: true,\n Label: '∪',\n title: 'اتحاد',\n svg_path: null,\n },\n emptyset: {\n id: 'emptyset',\n category: 'operators2',\n Tex: '\\\\emptyset',\n mirror: false,\n displayMirror: true,\n Label: '∅',\n title: 'المجموعة الخالية',\n svg_path: null,\n },\n nsubseteq: {\n id: 'nsubseteq',\n category: 'operators2',\n Tex: '\\\\nsubseteq',\n mirror: true,\n displayMirror: false,\n compileMirror: true,\n Label: '⊈',\n title: 'ليست مجموعة جزئية أو تساوي',\n svg_path: null,\n },\n nsupseteq: {\n id: 'nsupseteq',\n category: 'operators2',\n Tex: '\\\\nsupseteq',\n mirror: true,\n displayMirror: false,\n compileMirror: true,\n Label: '⊉',\n title: 'ليست مجموعة شاملة أو تساوي',\n svg_path: null,\n },\n\n ///// Dots\n ldots: {\n id: 'ldots',\n category: 'dots',\n Tex: '\\\\ldots',\n mirror: false,\n Label: '…',\n title: 'نقاط أفقية',\n svg_path: null,\n },\n cdot: {\n id: 'cdot',\n category: 'dots',\n Tex: '\\\\cdot',\n mirror: false,\n Label: '·',\n title: 'نقطة ضرب',\n svg_path: null,\n },\n cdots: {\n id: 'cdots',\n category: 'dots',\n Tex: '\\\\cdots',\n mirror: false,\n Label: '⋯',\n title: 'نقاط وسطية أفقية',\n svg_path: null,\n },\n vdots: {\n id: 'vdots',\n category: 'dots',\n Tex: '\\\\vdots',\n mirror: false,\n Label: '⋮',\n title: 'نقاط عمودية',\n svg_path: null,\n },\n ddots: {\n id: 'ddots',\n category: 'dots',\n Tex: '\\\\ddots',\n mirror: true,\n displayMirror: false,\n compileMirror: true,\n Label: '⋱',\n title: 'نقاط قطرية',\n svg_path: null,\n },\n\n /// Operators 3\n leftrightarrowDouble: {\n id: 'leftrightarrowDouble',\n category: 'operators3',\n Tex: '\\\\Leftrightarrow',\n mirror: false,\n Label: '⇔',\n title: 'يكافئ',\n svg_path: null,\n },\n implies: {\n id: 'implies',\n category: 'operators3',\n Tex: '\\\\implies',\n mirror: true,\n compileMirror: true,\n Label: '⇒',\n title: 'يستلزم',\n svg_path: null,\n },\n impliedby: {\n id: 'impliedby',\n category: 'operators3',\n Tex: '\\\\impliedby',\n mirror: true,\n compileMirror: true,\n Label: '⇐',\n title: 'مستلزم من',\n svg_path: null,\n },\n iff: {\n id: 'iff',\n category: 'operators3',\n Tex: '\\\\iff',\n mirror: false,\n Label: '⇔',\n title: 'إذا وفقط إذا',\n svg_path: null,\n },\n Longrightarrow: {\n id: 'Longrightarrow',\n category: 'operators3',\n Tex: '\\\\Longrightarrow',\n mirror: true,\n compileMirror: true,\n Label: '⟹',\n title: 'سهم مزدوج طويل إلى اليمين',\n svg_path: null,\n },\n Longleftarrow: {\n id: 'Longleftarrow',\n category: 'operators3',\n Tex: '\\\\Longleftarrow',\n mirror: true,\n compileMirror: true,\n Label: '⟸',\n title: 'سهم مزدوج طويل إلى اليسار',\n svg_path: null,\n },\n to: {\n id: 'to',\n category: 'operators3',\n Tex: '\\\\to',\n mirror: true,\n compileMirror: true,\n Label: '→',\n title: 'يؤول إلى',\n svg_path: null,\n },\n rightleftharpoons: {\n id: 'rightleftharpoons',\n category: 'operators3',\n Tex: '\\\\rightleftharpoons',\n mirror: true,\n compileMirror: true,\n Label: '⇌',\n title: 'اتزان',\n svg_path: null,\n },\n leftarrow: {\n id: 'leftarrow',\n category: 'operators3',\n Tex: '\\\\leftarrow',\n mirror: true,\n compileMirror: true,\n Label: '←',\n title: 'سهم إلى اليسار',\n svg_path: null,\n },\n rightarrow: {\n id: 'rightarrow',\n category: 'operators3',\n Tex: '\\\\rightarrow',\n mirror: true,\n compileMirror: true,\n Label: '→',\n title: 'سهم إلى اليمين',\n svg_path: null,\n },\n leftarrowDouble: {\n id: 'leftarrowDouble',\n category: 'operators3',\n Tex: '\\\\Leftarrow',\n mirror: true,\n compileMirror: true,\n Label: '⇐',\n title: 'سهم مزدوج إلى اليسار',\n svg_path: null,\n },\n rightarrowDouble: {\n id: 'rightarrowDouble',\n category: 'operators3',\n Tex: '\\\\Rightarrow',\n mirror: true,\n compileMirror: true,\n Label: '⇒',\n title: 'سهم مزدوج إلى اليمين',\n svg_path: null,\n },\n leftharpoonup: {\n id: 'leftharpoonup',\n category: 'operators3',\n Tex: '\\\\leftharpoonup',\n mirror: true,\n compileMirror: true,\n Label: '↼',\n title: 'سهم خطافي علوي إلى اليسار',\n svg_path: null,\n },\n rightharpoonup: {\n id: 'rightharpoonup',\n category: 'operators3',\n Tex: '\\\\rightharpoonup',\n mirror: true,\n compileMirror: true,\n Label: '⇀',\n title: 'سهم خطافي علوي إلى اليمين',\n svg_path: null,\n },\n leftharpoondown: {\n id: 'leftharpoondown',\n category: 'operators3',\n Tex: '\\\\leftharpoondown',\n mirror: true,\n compileMirror: true,\n Label: '↽',\n title: 'سهم خطافي سفلي إلى اليسار',\n svg_path: null,\n },\n rightharpoondown: {\n id: 'rightharpoondown',\n category: 'operators3',\n Tex: '\\\\rightharpoondown',\n mirror: true,\n compileMirror: true,\n Label: '⇁',\n title: 'سهم خطافي سفلي إلى اليمين',\n svg_path: null,\n },\n\n // Integrals\n int: {\n id: 'int',\n category: 'integrals',\n Tex: '\\\\int',\n mirror: true,\n compileMirror: true,\n Label: '∫',\n title: 'تكامل',\n svg_path: null,\n },\n iint: {\n id: 'iint',\n category: 'integrals',\n Tex: '\\\\iint',\n mirror: true,\n displayMirror: false,\n compileMirror: true,\n Label: '∬',\n title: 'تكامل مزدوج',\n svg_path: null,\n },\n iiint: {\n id: 'iiint',\n category: 'integrals',\n Tex: '\\\\iiint',\n mirror: true,\n displayMirror: false,\n compileMirror: true,\n Label: '∭',\n title: 'تكامل ثلاثي',\n svg_path: null,\n },\n iiiint: {\n id: 'iiiint',\n category: 'integrals',\n Tex: '\\\\iiiint',\n mirror: true,\n displayMirror: false,\n compileMirror: true,\n Label: '⨌',\n title: 'تكامل رباعي',\n svg_path: null,\n },\n oint: {\n id: 'oint',\n category: 'integrals',\n Tex: '\\\\oint',\n mirror: true,\n displayMirror: false,\n compileMirror: true,\n Label: '∮',\n title: 'تكامل مغلق',\n svg_path: null,\n },\n oiint: {\n id: 'oiint',\n category: 'integrals',\n Tex: '\\\\oiint',\n mirror: true,\n displayMirror: false,\n compileMirror: true,\n Label: '∯',\n title: 'تكامل سطحي مغلق',\n svg_path: null,\n },\n oiiint: {\n id: 'oiiint',\n category: 'integrals',\n Tex: '\\\\oiiint',\n mirror: true,\n displayMirror: false,\n compileMirror: true,\n Label: '∰',\n title: 'تكامل حجمي مغلق',\n svg_path: null,\n },\n} as const;\n\nexport type AtomicOperatorCommandId = keyof typeof ATOMIC_OPERATOR_COMMANDS;\n\nexport type AtomicOperatorCommandCategory =\n | 'operators1'\n | 'operators2'\n | 'operators3'\n | 'dots'\n | 'integrals';\n\nexport type AtomicOperatorCommandSpec =\n (typeof ATOMIC_OPERATOR_COMMANDS)[AtomicOperatorCommandId] & {\n displayMirror?: boolean;\n compileMirror?: boolean;\n };\n\nexport function shouldMirrorOperatorDisplay(\n command: AtomicOperatorCommandSpec | null | undefined,\n): boolean {\n return command?.displayMirror ?? command?.mirror ?? false;\n}\n\nconst MIRRORED_OPERATOR_TEX = Object.values(ATOMIC_OPERATOR_COMMANDS)\n .filter((command) => command.mirror)\n .map((command) => command.Tex)\n .sort((a, b) => b.length - a.length) as string[];\n\nconst COMPILE_MIRRORED_OPERATOR_TEX = Object.values(ATOMIC_OPERATOR_COMMANDS)\n .filter((command) => 'compileMirror' in command && command.compileMirror)\n .map((command) => command.Tex)\n .sort((a, b) => b.length - a.length) as string[];\n\nfunction matchingMirroredOperatorFrom(tex: string, index: number, operatorTexList: string[]): string | null {\n for (const operatorTex of operatorTexList) {\n if (!tex.startsWith(operatorTex, index)) {\n continue;\n }\n const next = tex[index + operatorTex.length];\n if (next != null && /[A-Za-z]/.test(next)) {\n continue;\n }\n return operatorTex;\n }\n return null;\n}\n\nfunction findMatchingBrace(tex: string, openIndex: number): number {\n let depth = 0;\n for (let index = openIndex; index < tex.length; index += 1) {\n const char = tex[index];\n if (char === '\\\\') {\n index += 1;\n continue;\n }\n if (char === '{') {\n depth += 1;\n } else if (char === '}') {\n depth -= 1;\n if (depth === 0) {\n return index;\n }\n }\n }\n return -1;\n}\n\nexport function mirrorBuTeXOperatorsInTex(tex: string, options: { target?: 'preview' | 'compile' } = {}): string {\n const mirroredOperatorTex = options.target === 'compile'\n ? COMPILE_MIRRORED_OPERATOR_TEX\n : MIRRORED_OPERATOR_TEX;\n let result = '';\n let index = 0;\n\n while (index < tex.length) {\n if (tex.startsWith('\\\\butexmirror{', index)) {\n const end = findMatchingBrace(tex, index + '\\\\butexmirror'.length);\n if (end !== -1) {\n const bodyStart = index + '\\\\butexmirror{'.length;\n const body = tex.slice(bodyStart, end);\n if (\n options.target === 'compile' &&\n MIRRORED_OPERATOR_TEX.includes(body) &&\n !mirroredOperatorTex.includes(body)\n ) {\n result += body;\n } else {\n result += tex.slice(index, end + 1);\n }\n index = end + 1;\n continue;\n }\n }\n\n const operatorTex = matchingMirroredOperatorFrom(tex, index, mirroredOperatorTex);\n if (operatorTex) {\n result += `\\\\butexmirror{${operatorTex}}`;\n index += operatorTex.length;\n continue;\n }\n\n result += tex[index];\n index += 1;\n }\n\n return result;\n}\n\nexport function atomicOperatorCommandsByCategory(\n category: AtomicOperatorCommandCategory,\n): AtomicOperatorCommandSpec[] {\n return Object.values(ATOMIC_OPERATOR_COMMANDS).filter(\n (command) => command.category === category,\n );\n}\n\nexport function atomicOperatorCommandSpec(\n id: string,\n): AtomicOperatorCommandSpec | null {\n return Object.prototype.hasOwnProperty.call(ATOMIC_OPERATOR_COMMANDS, id)\n ? ATOMIC_OPERATOR_COMMANDS[id as AtomicOperatorCommandId]\n : null;\n}\n","import type { EditorChain, EditorNode, EditorSession, EditorSide, EnvColumnAlignment, GridEnvName, MatrixEnvStyle } from './types.js';\nimport type { AccentCommandId } from './accentCommands.js';\nimport type { AtomicCommandId } from './atomicCommands.js';\nimport type { AtomicOperatorCommandId } from './atomicCommandsOperators.js';\n\nlet nextId = 1;\n\nfunction makeId(prefix: string): string {\n const id = `${prefix}_${String(nextId)}`;\n nextId += 1;\n return id;\n}\n\nexport function createEditorChain(nodes: EditorNode[] = []): EditorChain {\n return {\n id: makeId('chain'),\n nodes,\n };\n}\n\nexport function createEditorNode(kind: EditorNode['kind'], expr: string): EditorNode {\n return {\n id: makeId('node'),\n kind,\n expr,\n characterFont: undefined,\n superscript: null,\n subscript: null,\n leftDelimExpr: '',\n rightDelimExpr: '',\n innerExpr: null,\n numerator: null,\n denominator: null,\n radicand: null,\n rootIndex: null,\n overExpr: null,\n underExpr: null,\n baseExpr: null,\n envName: null,\n matrixStyle: null,\n matrixRows: null,\n columnAlignments: null,\n };\n}\n\nexport function createDelimiterNode(leftDelimExpr: string, rightDelimExpr: string): EditorNode {\n return {\n ...createEditorNode('delimiter', ''),\n leftDelimExpr,\n rightDelimExpr,\n innerExpr: createEditorChain(),\n };\n}\n\nexport function createFracNode(): EditorNode {\n return {\n ...createEditorNode('frac', ''),\n numerator: createEditorChain(),\n denominator: createEditorChain(),\n };\n}\n\nexport function createSqrtNode(): EditorNode {\n return {\n ...createEditorNode('sqrt', ''),\n radicand: createEditorChain(),\n rootIndex: createEditorChain(),\n };\n}\n\nexport function createOversetNode(): EditorNode {\n return {\n ...createEditorNode('overset', ''),\n overExpr: createEditorChain(),\n baseExpr: createEditorChain(),\n };\n}\n\nexport function createUndersetNode(): EditorNode {\n return {\n ...createEditorNode('underset', ''),\n underExpr: createEditorChain(),\n baseExpr: createEditorChain(),\n };\n}\n\nexport function createAccentNode(accentId: AccentCommandId): EditorNode {\n return {\n ...createEditorNode('accent', accentId),\n baseExpr: createEditorChain(),\n };\n}\n\nexport function createMatrixEnvNode(style: MatrixEnvStyle, rows: number, columns: number): EditorNode {\n return createGridEnvNode(style, rows, columns);\n}\n\nexport function createGridEnvNode(\n envName: GridEnvName,\n rows: number,\n columns: number,\n columnAlignments?: EnvColumnAlignment[],\n): EditorNode {\n const safeRows = Math.max(1, Math.min(12, Math.trunc(rows)));\n const safeColumns = Math.max(1, Math.min(12, Math.trunc(columns)));\n const matrixStyles = new Set<GridEnvName>(['matrix', 'pmatrix', 'bmatrix', 'Bmatrix', 'vmatrix', 'Vmatrix']);\n const isMatrix = matrixStyles.has(envName) && envName !== 'array' && envName !== 'aligned';\n return {\n ...createEditorNode('env', ''),\n envName,\n matrixStyle: isMatrix ? (envName as MatrixEnvStyle) : null,\n matrixRows: Array.from({ length: safeRows }, () =>\n Array.from({ length: safeColumns }, () => createEditorChain()),\n ),\n columnAlignments: envName === 'array'\n ? Array.from({ length: safeColumns }, (_, index) => columnAlignments?.[index] ?? 'c')\n : null,\n };\n}\n\nexport function createAtomicCommandNode(commandId: AtomicCommandId): EditorNode {\n return createEditorNode('atomicCommand', commandId);\n}\n\nexport function createAtomicOperatorCommandNode(commandId: AtomicOperatorCommandId): EditorNode {\n return createEditorNode('atomicOperatorCommand', commandId);\n}\n\nexport function cloneEditorSession(session: EditorSession): EditorSession {\n return {\n englishTree: structuredClone(session.englishTree),\n arabicTree: structuredClone(session.arabicTree),\n activeSide: session.activeSide,\n splitLeafTyping: session.splitLeafTyping,\n forceSplitNextLeaf: session.forceSplitNextLeaf,\n arabicReverseNumberTyping: session.arabicReverseNumberTyping,\n currentCharacterFont: session.currentCharacterFont ?? 'default',\n currentDigitForm: session.currentDigitForm ?? 'western',\n caret: { ...session.caret },\n selection: session.selection ? { ...session.selection } : null,\n selectedNodeId: session.selectedNodeId,\n selectedStructureNodeId: session.selectedStructureNodeId,\n sync: structuredClone(session.sync),\n debugLog: session.debugLog.slice(),\n };\n}\n\nfunction collectNodeIds(chain: EditorChain, ids: string[]): void {\n for (const node of chain.nodes) {\n ids.push(node.id);\n if (node.superscript) {\n collectNodeIds(node.superscript, ids);\n }\n if (node.subscript) {\n collectNodeIds(node.subscript, ids);\n }\n if (node.innerExpr) {\n collectNodeIds(node.innerExpr, ids);\n }\n if (node.numerator) {\n collectNodeIds(node.numerator, ids);\n }\n if (node.denominator) {\n collectNodeIds(node.denominator, ids);\n }\n if (node.rootIndex) {\n collectNodeIds(node.rootIndex, ids);\n }\n if (node.radicand) {\n collectNodeIds(node.radicand, ids);\n }\n if (node.overExpr) {\n collectNodeIds(node.overExpr, ids);\n }\n if (node.underExpr) {\n collectNodeIds(node.underExpr, ids);\n }\n if (node.baseExpr) {\n collectNodeIds(node.baseExpr, ids);\n }\n if (node.matrixRows) {\n for (const row of node.matrixRows) {\n for (const cell of row) {\n collectNodeIds(cell, ids);\n }\n }\n }\n }\n}\n\nexport function buildInitialSyncMap(englishTree: EditorChain, arabicTree: EditorChain): EditorSession['sync'] {\n const englishIds: string[] = [];\n const arabicIds: string[] = [];\n collectNodeIds(englishTree, englishIds);\n collectNodeIds(arabicTree, arabicIds);\n\n const all = new Set<string>([...englishIds, ...arabicIds]);\n const sync: EditorSession['sync'] = {};\n for (const nodeId of all) {\n sync[nodeId] = { expr: 'synced' };\n }\n return sync;\n}\n\nexport function createEditorSession(englishTree: EditorChain, arabicTree: EditorChain, activeSide: EditorSide = 'arabic'): EditorSession {\n return {\n englishTree,\n arabicTree,\n activeSide,\n splitLeafTyping: false,\n forceSplitNextLeaf: false,\n arabicReverseNumberTyping: true,\n currentCharacterFont: 'default',\n currentDigitForm: 'western',\n caret: {\n chainId: englishTree.id,\n index: 0,\n },\n selection: null,\n selectedNodeId: null,\n selectedStructureNodeId: null,\n sync: buildInitialSyncMap(englishTree, arabicTree),\n debugLog: [],\n };\n}\n","import type { CharacterFontId } from './types.js';\n\nexport type CharacterFontSpec = {\n id: CharacterFontId;\n label: string;\n titleKey:\n | 'defaultFont'\n | 'takweenFont'\n | 'diwaniFont'\n | 'diwaniOutlineFont'\n | 'maghribiFont';\n cssClass?: string;\n mathJaxClass?: string;\n macro?: string;\n latexFontCommand?: string;\n latexFontFamily?: string;\n browserFontStack?: string;\n importAliases?: string[];\n svgLayoutKey?: string;\n};\n\nexport const CHARACTER_FONT_SPECS: CharacterFontSpec[] = [\n {\n id: 'default',\n label: 'س',\n titleKey: 'defaultFont',\n },\n {\n id: 'takween',\n label: 'تك',\n titleKey: 'takweenFont',\n cssClass: 'node-value--takween',\n mathJaxClass: 'butex-takween-text',\n macro: '\\\\butextakween',\n latexFontCommand: '\\\\takween',\n latexFontFamily: 'Takween',\n browserFontStack: '\"BuTeX Takween\", Amiri, \"Segoe UI\", Tahoma, sans-serif',\n importAliases: ['\\\\takween'],\n svgLayoutKey: 'takween',\n },\n {\n id: 'diwani',\n label: 'ديو',\n titleKey: 'diwaniFont',\n cssClass: 'node-value--diwani',\n mathJaxClass: 'butex-diwani-text',\n macro: '\\\\butexdiwani',\n latexFontCommand: '\\\\diwani',\n latexFontFamily: 'Diwani Letter',\n browserFontStack: '\"Diwani Letter\", Amiri, \"Segoe UI\", Tahoma, sans-serif',\n importAliases: ['\\\\diwani'],\n svgLayoutKey: 'diwani',\n },\n {\n id: 'diwaniOutline',\n label: 'ظل',\n titleKey: 'diwaniOutlineFont',\n cssClass: 'node-value--diwani-outline',\n mathJaxClass: 'butex-diwani-outline-text',\n macro: '\\\\butexdiwanioutline',\n latexFontCommand: '\\\\diwanioutlineshaded',\n latexFontFamily: 'Diwani Outline Shaded',\n browserFontStack: '\"BuTeX Diwani Outline\", \"Diwani Letter\", Amiri, \"Segoe UI\", Tahoma, sans-serif',\n importAliases: ['\\\\diwanioutlineshaded'],\n svgLayoutKey: 'diwani-outline',\n },\n {\n id: 'maghribi',\n label: 'مغ',\n titleKey: 'maghribiFont',\n cssClass: 'node-value--maghribi',\n mathJaxClass: 'butex-maghribi-text',\n macro: '\\\\butexmaghribi',\n latexFontCommand: '\\\\maghribi',\n latexFontFamily: 'Almaghribi Warsh Quran',\n browserFontStack: '\"Almaghribi Warsh Quran\", Amiri, \"Segoe UI\", Tahoma, sans-serif',\n svgLayoutKey: 'maghribi',\n },\n];\n\nexport const CHARACTER_FONT_OPTIONS = CHARACTER_FONT_SPECS.map(({ id, label }) => ({ id, label }));\n\nexport const NON_DEFAULT_CHARACTER_FONT_SPECS = CHARACTER_FONT_SPECS.filter(\n (font): font is CharacterFontSpec & { macro: string } => font.id !== 'default' && typeof font.macro === 'string',\n);\n\nexport function characterFontSpec(fontId: CharacterFontId): CharacterFontSpec {\n return CHARACTER_FONT_SPECS.find((font) => font.id === fontId) ?? CHARACTER_FONT_SPECS[0];\n}\n\nexport function characterFontSpecByMacro(macro: string): CharacterFontSpec | null {\n return NON_DEFAULT_CHARACTER_FONT_SPECS.find(\n (font) => font.macro === macro || font.importAliases?.includes(macro),\n ) ?? null;\n}\n","import type { EditorSide } from './types.js';\n\n/** LTR divide stroke stored on the English tree (reference OperatorObject `/`). */\nexport const DIVIDE_OPERATOR_EN = '/';\n\n/** RTL divide stroke shown on the Arabic editing surface. */\nexport const DIVIDE_OPERATOR_AR = '\\\\';\n\nexport function isDivideOperatorExpr(expr: string): boolean {\n return expr === DIVIDE_OPERATOR_EN || expr === DIVIDE_OPERATOR_AR;\n}\n\nexport function divideOperatorSurfaceExpr(expr: string, side: EditorSide): string {\n if (!isDivideOperatorExpr(expr)) {\n return expr;\n }\n return side === 'arabic' ? DIVIDE_OPERATOR_AR : DIVIDE_OPERATOR_EN;\n}\n\nexport function renderDivideOperatorLatex(side: EditorSide): string {\n return side === 'arabic' ? '\\\\backslash' : DIVIDE_OPERATOR_EN;\n}\n","import type { DigitFormId, EditorChain, EditorNode, EditorSession, EnvColumnAlignment } from './types.js';\nimport { accentCommandSpec } from './accentCommands.js';\nimport { atomicCommandSpec } from './atomicCommands.js';\nimport { atomicOperatorCommandSpec } from './atomicCommandsOperators.js';\nimport { characterFontSpec } from './characterFonts.js';\nimport { isDivideOperatorExpr, renderDivideOperatorLatex } from './divideOperator.js';\nimport { formatDigits } from './digits.js';\n\ntype RenderOptions = {\n digitForm?: DigitFormId;\n};\n\nfunction selectedDigitForm(options?: RenderOptions): DigitFormId {\n return options?.digitForm ?? 'western';\n}\n\nfunction latinScripts(node: EditorNode, options?: RenderOptions): string {\n let scripts = '';\n if (node.superscript) {\n scripts += `^{${renderChainEnglish(node.superscript, options)}}`;\n }\n if (node.subscript) {\n scripts += `_{${renderChainEnglish(node.subscript, options)}}`;\n }\n return scripts;\n}\n\nfunction optionalRootIndexEnglish(node: EditorNode, options?: RenderOptions): string {\n if (!node.rootIndex) {\n return '';\n }\n const rendered = renderChainEnglish(node.rootIndex, options);\n return rendered === '' ? '' : `[${rendered}]`;\n}\n\nfunction optionalRootIndexArabic(node: EditorNode, options?: RenderOptions): string {\n if (!node.rootIndex) {\n return '';\n }\n const rendered = renderChainArabic(node.rootIndex, options);\n return rendered === '' ? '' : `[${rendered}]`;\n}\n\nfunction arabicScripts(node: EditorNode, content: string, options?: RenderOptions): string {\n const sup = node.superscript ? renderChainArabic(node.superscript, options) : '';\n const sub = node.subscript ? renderChainArabic(node.subscript, options) : '';\n if (sup !== '' || sub !== '') {\n return `\\\\prescript{${sup}}{${sub}}{${content}}`;\n }\n return content;\n}\n\nfunction renderMatrixRowsEnglish(node: EditorNode, options?: RenderOptions): string {\n if (!node.matrixRows) {\n return '';\n }\n const envName = node.envName ?? node.matrixStyle;\n if (!envName) {\n return '';\n }\n const rows = node.matrixRows.map((row) => row.map((cell) => renderChainEnglish(cell, options)).join(' & '));\n if (envName === 'array') {\n const spec = (node.columnAlignments ?? []).slice(0, node.matrixRows[0]?.length ?? 0).join('');\n return `\\\\begin{array}{${spec || 'c'}}${rows.join(' \\\\\\\\\\n')}\\\\end{array}`;\n }\n return `\\\\begin{${envName}}${rows.join(' \\\\\\\\\\n')}\\\\end{${envName}}`;\n}\n\nfunction reverseAlignmentForArabic(alignment: EnvColumnAlignment): EnvColumnAlignment {\n if (alignment === 'l') {\n return 'r';\n }\n if (alignment === 'r') {\n return 'l';\n }\n return 'c';\n}\n\nfunction renderMatrixRowsArabic(node: EditorNode, options?: RenderOptions): string {\n if (!node.matrixRows) {\n return '';\n }\n const envName = node.envName ?? node.matrixStyle;\n if (!envName) {\n return '';\n }\n const rows = node.matrixRows.map((row) =>\n row\n .slice()\n .reverse()\n .map((cell) => renderChainArabic(cell, options))\n .join(' & '),\n );\n if (envName === 'array') {\n const spec = (node.columnAlignments ?? [])\n .slice(0, node.matrixRows[0]?.length ?? 0)\n .reverse()\n .map(reverseAlignmentForArabic)\n .join('');\n return `\\\\begin{array}{${spec || 'c'}}${rows.join(' \\\\\\\\\\n')}\\\\end{array}`;\n }\n return `\\\\begin{${envName}}${rows.join(' \\\\\\\\\\n')}\\\\end{${envName}}`;\n}\n\nfunction renderAccentEnglish(\n command: 'overset' | 'underset',\n accent: EditorChain | null,\n base: EditorChain | null,\n options?: RenderOptions,\n): string {\n const baseTex = base ? renderChainEnglish(base, options) : '';\n const accentTex = accent ? renderChainEnglish(accent, options) : '';\n if (accentTex === '') {\n return baseTex;\n }\n return `\\\\${command}{${accentTex}}{${baseTex}}`;\n}\n\nfunction renderAccentArabic(\n command: 'overset' | 'underset',\n accent: EditorChain | null,\n base: EditorChain | null,\n options?: RenderOptions,\n): string {\n const baseTex = base ? renderChainArabic(base, options) : '';\n const accentTex = accent ? renderChainArabic(accent, options) : '';\n if (accentTex === '') {\n return baseTex;\n }\n return `\\\\${command}{${accentTex}}{${baseTex}}`;\n}\n\nfunction escapeText(s: string): string {\n return s.replace(/\\\\/g, '\\\\textbackslash{}').replace(/[{}]/g, '\\\\$&');\n}\n\nfunction renderCharContent(node: EditorNode, options?: RenderOptions): string {\n const expr = formatDigits(node.expr, selectedDigitForm(options));\n const font = node.characterFont ?? 'default';\n const macro = characterFontSpec(font).macro;\n if (macro) {\n return `${macro}{${escapeText(expr)}}`;\n }\n return expr;\n}\n\nfunction renderNodeEnglish(node: EditorNode, options?: RenderOptions): string {\n if (node.kind === 'delimiter' && node.innerExpr) {\n return `${node.leftDelimExpr}${renderChainEnglish(node.innerExpr, options)}${node.rightDelimExpr}${latinScripts(node, options)}`;\n }\n if (node.kind === 'frac' && node.numerator && node.denominator) {\n const body = `\\\\frac{${renderChainEnglish(node.numerator, options)}}{${renderChainEnglish(node.denominator, options)}}`;\n return `${body}${latinScripts(node, options)}`;\n }\n if (node.kind === 'sqrt' && node.radicand) {\n const body = `\\\\sqrt${optionalRootIndexEnglish(node, options)}{${renderChainEnglish(node.radicand, options)}}`;\n return `${body}${latinScripts(node, options)}`;\n }\n if (node.kind === 'overset' && node.baseExpr) {\n const body = renderAccentEnglish('overset', node.overExpr, node.baseExpr, options);\n return `${body}${latinScripts(node, options)}`;\n }\n if (node.kind === 'underset' && node.baseExpr) {\n const body = renderAccentEnglish('underset', node.underExpr, node.baseExpr, options);\n return `${body}${latinScripts(node, options)}`;\n }\n if (node.kind === 'accent' && node.baseExpr) {\n const cmd = accentCommandSpec(node.expr)?.englishTex ?? `\\\\${node.expr}`;\n const body = `${cmd}{${renderChainEnglish(node.baseExpr, options)}}`;\n return `${body}${latinScripts(node, options)}`;\n }\n if (node.kind === 'env') {\n return `${renderMatrixRowsEnglish(node, options)}${latinScripts(node, options)}`;\n }\n if (node.kind === 'atomicCommand') {\n const body = atomicCommandSpec(node.expr)?.englishTex ?? node.expr;\n return `${body}${latinScripts(node, options)}`;\n }\n if (node.kind === 'atomicOperatorCommand') {\n const body = atomicOperatorCommandSpec(node.expr)?.Tex ?? node.expr;\n return `${body}${latinScripts(node, options)}`;\n }\n if (node.kind === 'char') {\n return `${renderCharContent(node, options)}${latinScripts(node, options)}`;\n }\n if (node.kind === 'operator' && isDivideOperatorExpr(node.expr)) {\n return `${renderDivideOperatorLatex('english')}${latinScripts(node, options)}`;\n }\n return `${formatDigits(node.expr, selectedDigitForm(options))}${latinScripts(node, options)}`;\n}\n\nfunction renderNodeArabic(node: EditorNode, options?: RenderOptions): string {\n if (node.kind === 'delimiter' && node.innerExpr) {\n const content = `${node.leftDelimExpr}${renderChainArabic(node.innerExpr, options)}${node.rightDelimExpr}`;\n return arabicScripts(node, content, options);\n }\n if (node.kind === 'frac' && node.numerator && node.denominator) {\n const content = `\\\\frac{${renderChainArabic(node.numerator, options)}}{${renderChainArabic(node.denominator, options)}}`;\n return arabicScripts(node, content, options);\n }\n if (node.kind === 'sqrt' && node.radicand) {\n const content = `\\\\arsqrt${optionalRootIndexArabic(node, options)}{${renderChainArabic(node.radicand, options)}}`;\n return arabicScripts(node, content, options);\n }\n if (node.kind === 'overset' && node.baseExpr) {\n const content = renderAccentArabic('overset', node.overExpr, node.baseExpr, options);\n return arabicScripts(node, content, options);\n }\n if (node.kind === 'underset' && node.baseExpr) {\n const content = renderAccentArabic('underset', node.underExpr, node.baseExpr, options);\n return arabicScripts(node, content, options);\n }\n if (node.kind === 'accent' && node.baseExpr) {\n const cmd = accentCommandSpec(node.expr)?.arabicTex ?? `\\\\${node.expr}`;\n const content = `${cmd}{${renderChainArabic(node.baseExpr, options)}}`;\n return arabicScripts(node, content, options);\n }\n if (node.kind === 'env') {\n return arabicScripts(node, renderMatrixRowsArabic(node, options), options);\n }\n if (node.kind === 'atomicCommand') {\n const spec = atomicCommandSpec(node.expr);\n const content = spec?.arabicRenderTex ?? spec?.arabicTex ?? node.expr;\n return arabicScripts(node, content, options);\n }\n if (node.kind === 'atomicOperatorCommand') {\n const spec = atomicOperatorCommandSpec(node.expr);\n const tex = spec?.Tex ?? node.expr;\n const content = spec?.mirror ? `\\\\butexmirror{${tex}}` : tex;\n return arabicScripts(node, content, options);\n }\n if (node.kind === 'char') {\n const expr = formatDigits(node.expr, selectedDigitForm(options));\n const content = renderCharContent(node, options);\n return arabicScripts(node, (node.characterFont ?? 'default') === 'default'\n ? `\\\\text{${escapeText(expr)}}`\n : content, options);\n }\n if (node.kind === 'operator' && isDivideOperatorExpr(node.expr)) {\n return arabicScripts(node, renderDivideOperatorLatex('arabic'), options);\n }\n return arabicScripts(node, formatDigits(node.expr, selectedDigitForm(options)), options);\n}\n\nexport function renderChainEnglish(chain: EditorChain, options?: RenderOptions): string {\n return chain.nodes.map((node) => renderNodeEnglish(node, options)).join(' ');\n}\n\nexport function renderChainArabic(chain: EditorChain, options?: RenderOptions): string {\n return chain.nodes\n .slice()\n .reverse()\n .map((node) => renderNodeArabic(node, options))\n .join(' ');\n}\n\nexport function renderEnglishLatexFromSession(session: EditorSession): string {\n return renderChainEnglish(session.englishTree, { digitForm: session.currentDigitForm ?? 'western' });\n}\n\nexport function renderArabicLatexFromSession(session: EditorSession): string {\n return renderChainArabic(session.arabicTree, { digitForm: session.currentDigitForm ?? 'western' });\n}\n","import { caretStep } from './caretOrder.js';\nimport {\n type EditorFragment,\n regenerateFragmentIds,\n serializeSelection,\n} from './clipboard.js';\nimport {\n cloneEditorSession,\n createDelimiterNode,\n createEditorChain,\n createEditorNode,\n createFracNode,\n createSqrtNode,\n createAccentNode,\n createOversetNode,\n createUndersetNode,\n createGridEnvNode,\n createAtomicCommandNode,\n createAtomicOperatorCommandNode,\n} from './factory.js';\nimport { renderArabicLatexFromSession, renderEnglishLatexFromSession } from './render.js';\nimport { buildFirstDerivativeFrac, buildSecondDerivativeFrac, derivativeTemplateInitialCaret } from './derivativeTemplates.js';\nimport {\n buildLimitsSeriesTemplate,\n limitsSeriesTemplateInitialCaret,\n buildAccentPairTemplate,\n accentPairTemplateInitialCaret,\n} from './limitsTemplates.js';\nimport { DIVIDE_OPERATOR_AR, DIVIDE_OPERATOR_EN } from './divideOperator.js';\nimport { coveredNodeIds, isSelectionActive, nodeChildChains, normalizeSelection } from './selection.js';\nimport { activeTreeKey, findChainById, findNodeById, passiveTreeKey } from './traversal.js';\nimport type {\n CharacterFontId,\n DigitFormId,\n EditorChain,\n EditorDebugEntry,\n EditorNode,\n EditorSession,\n EditorSide,\n EnvColumnAlignment,\n GridEnvName,\n MatrixEnvStyle,\n} from './types.js';\nimport type { ButexUiLocale } from '../uiLocale.js';\nimport { equationEditorMessages } from './uiLocale.js';\nimport type { AccentCommandId } from './accentCommands.js';\nimport type { AtomicCommandId } from './atomicCommands.js';\nimport type { AtomicOperatorCommandId } from './atomicCommandsOperators.js';\n\nfunction ensureSyncEntry(session: EditorSession, nodeId: string): void {\n if (!session.sync[nodeId]) {\n session.sync[nodeId] = { expr: 'synced' };\n }\n}\n\nfunction markExprSync(session: EditorSession, nodeId: string): void {\n const english = findNodeById(session.englishTree, nodeId);\n const arabic = findNodeById(session.arabicTree, nodeId);\n ensureSyncEntry(session, nodeId);\n if (!english || !arabic) {\n session.sync[nodeId].expr = 'diverged';\n return;\n }\n session.sync[nodeId].expr = english.node.expr === arabic.node.expr ? 'synced' : 'diverged';\n}\n\n/** Keep highlighted node aligned with caret (keyboard + programmatic caret moves). */\nexport function syncSelectionToCaret(session: EditorSession): void {\n const activeKey = activeTreeKey(session.activeSide);\n const tree = session[activeKey];\n const { chainId, index } = session.caret;\n const located = findChainById(tree, chainId);\n if (!located) {\n session.selectedNodeId = null;\n return;\n }\n if (index > 0) {\n session.selectedNodeId = located.chain.nodes[index - 1].id;\n return;\n }\n if (located.relation.kind === 'superscript' || located.relation.kind === 'subscript') {\n session.selectedNodeId = located.relation.ownerNodeId;\n return;\n }\n if (\n located.relation.kind === 'inner' ||\n located.relation.kind === 'numerator' ||\n located.relation.kind === 'denominator' ||\n located.relation.kind === 'radicand' ||\n located.relation.kind === 'rootIndex' ||\n located.relation.kind === 'overExpr' ||\n located.relation.kind === 'underExpr' ||\n located.relation.kind === 'baseExpr' ||\n located.relation.kind === 'matrixCell'\n ) {\n session.selectedNodeId = located.relation.ownerNodeId;\n return;\n }\n session.selectedNodeId = null;\n}\n\nfunction appendDebug(session: EditorSession, command: string, note: string): void {\n const entry: EditorDebugEntry = {\n timestamp: new Date().toISOString(),\n command,\n activeSide: session.activeSide,\n englishLatex: renderEnglishLatexFromSession(session),\n arabicLatex: renderArabicLatexFromSession(session),\n renderOk: true,\n renderError: null,\n note,\n };\n const nextLog = session.debugLog.concat(entry);\n session.debugLog = nextLog.slice(-120);\n}\n\nfunction insertMirroredNode(session: EditorSession, chainId: string, index: number, englishNode: EditorNode, arabicNode: EditorNode): void {\n const englishLocated = findChainById(session.englishTree, chainId);\n const arabicLocated = findChainById(session.arabicTree, chainId);\n if (!englishLocated || !arabicLocated) {\n return;\n }\n const safeIndex = Math.max(0, Math.min(index, englishLocated.chain.nodes.length));\n englishLocated.chain.nodes.splice(safeIndex, 0, englishNode);\n arabicLocated.chain.nodes.splice(safeIndex, 0, arabicNode);\n ensureSyncEntry(session, englishNode.id);\n markExprSync(session, englishNode.id);\n}\n\nfunction syncMatrixCellChainIds(englishNode: EditorNode, arabicNode: EditorNode): void {\n const englishRows = englishNode.matrixRows ?? [];\n const arabicRows = arabicNode.matrixRows ?? [];\n const rowLimit = Math.min(englishRows.length, arabicRows.length);\n for (let rowIndex = 0; rowIndex < rowLimit; rowIndex += 1) {\n const englishRow = englishRows[rowIndex];\n const arabicRow = arabicRows[rowIndex];\n const columnLimit = Math.min(englishRow.length, arabicRow.length);\n for (let columnIndex = 0; columnIndex < columnLimit; columnIndex += 1) {\n arabicRow[columnIndex].id = englishRow[columnIndex].id;\n }\n }\n}\n\nfunction createMatrixRow(columnCount: number): EditorChain[] {\n return Array.from({ length: columnCount }, () => createEditorChain());\n}\n\nfunction findSelectedMatrixPair(session: EditorSession): { english: EditorNode; arabic: EditorNode } | null {\n const targetNodeId = session.selectedStructureNodeId ?? session.selectedNodeId;\n if (!targetNodeId) {\n return null;\n }\n const englishLocated = findNodeById(session.englishTree, targetNodeId);\n const arabicLocated = findNodeById(session.arabicTree, targetNodeId);\n if (!englishLocated || !arabicLocated) {\n return null;\n }\n if (englishLocated.node.kind !== 'env' || arabicLocated.node.kind !== 'env') {\n return null;\n }\n return { english: englishLocated.node, arabic: arabicLocated.node };\n}\n\nfunction normalizeArrayAlignments(node: EditorNode): void {\n if ((node.envName ?? node.matrixStyle) !== 'array' || !node.matrixRows) {\n return;\n }\n const columnCount = Math.max(1, node.matrixRows[0]?.length ?? 1);\n const current = node.columnAlignments ?? [];\n node.columnAlignments = Array.from({ length: columnCount }, (_, index) => current[index] ?? 'c');\n}\n\nfunction removeMirroredNodeById(session: EditorSession, nodeId: string): boolean {\n const englishLocated = findNodeById(session.englishTree, nodeId);\n const arabicLocated = findNodeById(session.arabicTree, nodeId);\n if (!englishLocated || !arabicLocated) {\n return false;\n }\n englishLocated.chain.nodes.splice(englishLocated.index, 1);\n arabicLocated.chain.nodes.splice(arabicLocated.index, 1);\n delete session.sync[nodeId];\n return true;\n}\n\n/**\n * Mutates `next` to remove every node covered by its current selection (mirrored\n * across EN/AR), parks the caret at selection.start, and clears the selection.\n * Returns true when something was removed.\n */\nfunction applyDeleteSelectionRange(next: EditorSession): boolean {\n if (!isSelectionActive(next.selection)) {\n next.selection = null;\n return false;\n }\n const ids = coveredNodeIds(next);\n if (ids.length === 0) {\n next.selection = null;\n return false;\n }\n const sel = next.selection;\n if (!sel) {\n return false;\n }\n const start = Math.min(sel.anchorIndex, sel.focusIndex);\n const chainId = sel.chainId;\n for (const id of ids) {\n removeMirroredNodeById(next, id);\n }\n next.caret = { chainId, index: start };\n next.selection = null;\n next.selectedStructureNodeId = null;\n return true;\n}\n\n/** Recursively ensure sync entries for an inserted mirrored subtree (top + nested). */\nfunction syncSubtreeRecursive(session: EditorSession, eng: EditorNode, ar: EditorNode): void {\n ensureSyncEntry(session, eng.id);\n markExprSync(session, eng.id);\n const engChains = nodeChildChains(eng);\n const arChains = nodeChildChains(ar);\n const limit = Math.min(engChains.length, arChains.length);\n for (let c = 0; c < limit; c += 1) {\n const ec = engChains[c];\n const ac = arChains[c];\n const innerLimit = Math.min(ec.nodes.length, ac.nodes.length);\n for (let j = 0; j < innerLimit; j += 1) {\n syncSubtreeRecursive(session, ec.nodes[j], ac.nodes[j]);\n }\n }\n}\n\nexport function switchSide(session: EditorSession): EditorSession {\n const next = cloneEditorSession(session);\n next.activeSide = next.activeSide === 'english' ? 'arabic' : 'english';\n next.selection = null;\n appendDebug(next, 'switchSide', `active=${next.activeSide}`);\n return next;\n}\n\nexport function setSplitLeafTyping(session: EditorSession, enabled: boolean): EditorSession {\n const next = cloneEditorSession(session);\n next.splitLeafTyping = enabled;\n appendDebug(next, 'setSplitLeafTyping', enabled ? 'on' : 'off');\n return next;\n}\n\nexport function setArabicReverseNumberTyping(session: EditorSession, enabled: boolean): EditorSession {\n const next = cloneEditorSession(session);\n next.arabicReverseNumberTyping = enabled;\n appendDebug(next, 'setArabicReverseNumberTyping', enabled ? 'on' : 'off');\n return next;\n}\n\nexport function setCaret(session: EditorSession, chainId: string, index: number): EditorSession {\n const next = cloneEditorSession(session);\n const activeKey = activeTreeKey(next.activeSide);\n const located = findChainById(next[activeKey], chainId);\n if (!located) {\n return session;\n }\n next.caret = {\n chainId,\n index: Math.max(0, Math.min(index, located.chain.nodes.length)),\n };\n next.selection = null;\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n return next;\n}\n\nexport function moveCaret(session: EditorSession, delta: -1 | 1): EditorSession {\n const next = cloneEditorSession(session);\n const activeKey = activeTreeKey(next.activeSide);\n const tree = next[activeKey];\n const located = findChainById(tree, next.caret.chainId);\n if (!located) {\n return session;\n }\n next.caret = caretStep(tree, next.caret, delta);\n next.selection = null;\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaret', `delta=${String(delta)} dfs`);\n return next;\n}\n\nexport function horizontalCaretDelta(session: EditorSession, direction: 'left' | 'right'): -1 | 1 {\n const activeKey = activeTreeKey(session.activeSide);\n const tree = session[activeKey];\n const located = findChainById(tree, session.caret.chainId);\n const inMatrixCell = located?.relation.kind === 'matrixCell';\n const canMoveInsideCell =\n inMatrixCell &&\n session.activeSide === 'arabic' &&\n ((direction === 'left' && session.caret.index < located.chain.nodes.length) ||\n (direction === 'right' && session.caret.index > 0));\n if (session.activeSide === 'arabic' && (!inMatrixCell || canMoveInsideCell)) {\n return direction === 'left' ? 1 : -1;\n }\n return direction === 'left' ? -1 : 1;\n}\n\nexport function moveCaretHorizontal(session: EditorSession, direction: 'left' | 'right'): EditorSession {\n const activeKey = activeTreeKey(session.activeSide);\n const tree = session[activeKey];\n const located = findChainById(tree, session.caret.chainId);\n if (!located || located.relation.kind !== 'matrixCell') {\n return moveCaret(session, horizontalCaretDelta(session, direction));\n }\n\n const textDelta = session.activeSide === 'arabic'\n ? direction === 'left' ? 1 : -1\n : direction === 'left' ? -1 : 1;\n const nextIndex = session.caret.index + textDelta;\n if (nextIndex >= 0 && nextIndex <= located.chain.nodes.length) {\n return moveCaret(session, textDelta);\n }\n\n const ownerLocated =\n located.relation.ownerNodeId !== null ? findNodeById(tree, located.relation.ownerNodeId) : null;\n const ownerNode = ownerLocated?.node ?? null;\n if (!ownerLocated || !ownerNode?.matrixRows) {\n return session;\n }\n\n const rowIndex = located.relation.rowIndex ?? 0;\n const columnIndex = located.relation.columnIndex ?? 0;\n const row = ownerNode.matrixRows[rowIndex];\n if (!row) {\n return session;\n }\n\n const toVisualIndex = (column: number, columnCount: number): number =>\n session.activeSide === 'arabic' ? columnCount - 1 - column : column;\n const fromVisualIndex = (visualColumn: number, columnCount: number): number =>\n session.activeSide === 'arabic' ? columnCount - 1 - visualColumn : visualColumn;\n const entryIndex = (cell: EditorChain): number => {\n if (session.activeSide === 'arabic') {\n return direction === 'left' ? 0 : cell.nodes.length;\n }\n return direction === 'left' ? cell.nodes.length : 0;\n };\n\n const visualDelta = direction === 'left' ? -1 : 1;\n const currentVisualIndex = toVisualIndex(columnIndex, row.length);\n let targetRowIndex = rowIndex;\n let targetVisualIndex = currentVisualIndex + visualDelta;\n\n if (targetVisualIndex < 0 || targetVisualIndex >= row.length) {\n if (direction === 'left') {\n if (session.activeSide === 'arabic') {\n targetRowIndex = rowIndex + 1;\n const targetRow = ownerNode.matrixRows[targetRowIndex];\n if (targetRow) {\n targetVisualIndex = targetRow.length - 1;\n }\n } else {\n targetRowIndex = rowIndex - 1;\n const targetRow = ownerNode.matrixRows[targetRowIndex];\n if (targetRow) {\n targetVisualIndex = targetRow.length - 1;\n }\n }\n } else if (session.activeSide === 'arabic') {\n targetRowIndex = rowIndex - 1;\n targetVisualIndex = 0;\n } else {\n targetRowIndex = rowIndex + 1;\n targetVisualIndex = 0;\n }\n }\n\n const targetRow = ownerNode.matrixRows[targetRowIndex];\n if (targetRow && targetVisualIndex >= 0 && targetVisualIndex < targetRow.length) {\n const targetColumnIndex = fromVisualIndex(targetVisualIndex, targetRow.length);\n const targetCell = targetRow[targetColumnIndex];\n if (targetCell) {\n const next = cloneEditorSession(session);\n next.caret = { chainId: targetCell.id, index: entryIndex(targetCell) };\n next.selection = null;\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretHorizontal', `matrix-${direction}`);\n return next;\n }\n }\n\n const next = cloneEditorSession(session);\n const exitsAfter =\n (session.activeSide === 'english' && direction === 'right') ||\n (session.activeSide === 'arabic' && direction === 'left');\n next.caret = {\n chainId: ownerLocated.chain.id,\n index: exitsAfter ? ownerLocated.index + 1 : ownerLocated.index,\n };\n next.selection = null;\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretHorizontal', `matrix-${direction}-exit`);\n return next;\n}\n\nexport function moveCaretVertical(session: EditorSession, direction: 'up' | 'down'): EditorSession {\n const next = cloneEditorSession(session);\n next.selection = null;\n const activeKey = activeTreeKey(next.activeSide);\n const tree = next[activeKey];\n const located = findChainById(tree, next.caret.chainId);\n if (!located) {\n return session;\n }\n\n const ownerLocated =\n located.relation.ownerNodeId !== null ? findNodeById(tree, located.relation.ownerNodeId) : null;\n const ownerNode = ownerLocated?.node ?? null;\n\n if (located.relation.kind === 'numerator' && ownerLocated && ownerNode && ownerNode.denominator) {\n if (direction === 'down') {\n next.caret = {\n chainId: ownerNode.denominator.id,\n index: ownerNode.denominator.nodes.length,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretVertical', 'frac-num->den');\n return next;\n }\n next.caret = {\n chainId: ownerLocated.chain.id,\n index: ownerLocated.index,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretVertical', 'frac-num-up-exit');\n return next;\n }\n\n if (located.relation.kind === 'denominator' && ownerLocated && ownerNode && ownerNode.numerator) {\n if (direction === 'up') {\n next.caret = {\n chainId: ownerNode.numerator.id,\n index: ownerNode.numerator.nodes.length,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretVertical', 'frac-den->num');\n return next;\n }\n next.caret = {\n chainId: ownerLocated.chain.id,\n index: ownerLocated.index + 1,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretVertical', 'frac-den-down-exit');\n return next;\n }\n\n if (located.relation.kind === 'rootIndex' && ownerLocated && ownerNode && ownerNode.radicand) {\n if (direction === 'down') {\n next.caret = {\n chainId: ownerNode.radicand.id,\n index: ownerNode.radicand.nodes.length,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretVertical', 'sqrt-root->radicand');\n return next;\n }\n next.caret = {\n chainId: ownerLocated.chain.id,\n index: ownerLocated.index,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretVertical', 'sqrt-root-up-exit');\n return next;\n }\n\n if (located.relation.kind === 'radicand' && ownerLocated && ownerNode && ownerNode.rootIndex) {\n if (direction === 'up') {\n next.caret = {\n chainId: ownerNode.rootIndex.id,\n index: ownerNode.rootIndex.nodes.length,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretVertical', 'sqrt-radicand->root');\n return next;\n }\n next.caret = {\n chainId: ownerLocated.chain.id,\n index: ownerLocated.index + 1,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretVertical', 'sqrt-radicand-down-exit');\n return next;\n }\n\n if (located.relation.kind === 'overExpr' && ownerLocated && ownerNode && ownerNode.baseExpr) {\n if (direction === 'down') {\n next.caret = {\n chainId: ownerNode.baseExpr.id,\n index: ownerNode.baseExpr.nodes.length,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretVertical', 'overset-over->base');\n return next;\n }\n next.caret = {\n chainId: ownerLocated.chain.id,\n index: ownerLocated.index,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretVertical', 'overset-over-up-exit');\n return next;\n }\n\n if (\n located.relation.kind === 'baseExpr' &&\n ownerLocated &&\n ownerNode &&\n ownerNode.kind === 'overset' &&\n ownerNode.overExpr\n ) {\n if (direction === 'up') {\n next.caret = {\n chainId: ownerNode.overExpr.id,\n index: ownerNode.overExpr.nodes.length,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretVertical', 'overset-base->over');\n return next;\n }\n next.caret = {\n chainId: ownerLocated.chain.id,\n index: ownerLocated.index + 1,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretVertical', 'overset-base-down-exit');\n return next;\n }\n\n if (\n located.relation.kind === 'baseExpr' &&\n ownerLocated &&\n ownerNode &&\n ownerNode.kind === 'underset' &&\n ownerNode.underExpr\n ) {\n if (direction === 'down') {\n next.caret = {\n chainId: ownerNode.underExpr.id,\n index: ownerNode.underExpr.nodes.length,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretVertical', 'underset-base->under');\n return next;\n }\n next.caret = {\n chainId: ownerLocated.chain.id,\n index: ownerLocated.index,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretVertical', 'underset-base-up-exit');\n return next;\n }\n\n if (located.relation.kind === 'underExpr' && ownerLocated && ownerNode && ownerNode.baseExpr) {\n if (direction === 'up') {\n next.caret = {\n chainId: ownerNode.baseExpr.id,\n index: ownerNode.baseExpr.nodes.length,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretVertical', 'underset-under->base');\n return next;\n }\n next.caret = {\n chainId: ownerLocated.chain.id,\n index: ownerLocated.index + 1,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretVertical', 'underset-under-down-exit');\n return next;\n }\n\n if (\n located.relation.kind === 'baseExpr' &&\n ownerLocated &&\n ownerNode &&\n ownerNode.kind === 'accent'\n ) {\n if (direction === 'up') {\n next.caret = {\n chainId: ownerLocated.chain.id,\n index: ownerLocated.index,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretVertical', 'accent-base-up-exit');\n return next;\n }\n next.caret = {\n chainId: ownerLocated.chain.id,\n index: ownerLocated.index + 1,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretVertical', 'accent-base-down-exit');\n return next;\n }\n\n if (located.relation.kind === 'matrixCell' && ownerLocated && ownerNode?.matrixRows) {\n const rowIndex = located.relation.rowIndex ?? 0;\n const columnIndex = located.relation.columnIndex ?? 0;\n const nextRowIndex = direction === 'up' ? rowIndex - 1 : rowIndex + 1;\n if (nextRowIndex >= 0 && nextRowIndex < ownerNode.matrixRows.length) {\n const nextRow = ownerNode.matrixRows[nextRowIndex];\n const nextCell = nextRow[Math.min(columnIndex, nextRow.length - 1)];\n if (nextCell) {\n next.caret = {\n chainId: nextCell.id,\n index: nextCell.nodes.length,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretVertical', 'matrix-cell');\n return next;\n }\n }\n next.caret = {\n chainId: ownerLocated.chain.id,\n index: direction === 'up' ? ownerLocated.index : ownerLocated.index + 1,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretVertical', `matrix-${direction}-exit`);\n return next;\n }\n\n if (located.relation.kind === 'superscript' && ownerLocated && ownerNode) {\n if (direction === 'down') {\n if (ownerNode.subscript) {\n next.caret = {\n chainId: ownerNode.subscript.id,\n index: ownerNode.subscript.nodes.length,\n };\n } else {\n next.caret = {\n chainId: ownerLocated.chain.id,\n index: ownerLocated.index + 1,\n };\n }\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretVertical', 'sup->down');\n return next;\n }\n next.caret = {\n chainId: ownerLocated.chain.id,\n index: ownerLocated.index,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretVertical', 'sup->up-exit');\n return next;\n }\n\n if (located.relation.kind === 'subscript' && ownerLocated && ownerNode) {\n if (direction === 'up') {\n if (ownerNode.superscript) {\n next.caret = {\n chainId: ownerNode.superscript.id,\n index: ownerNode.superscript.nodes.length,\n };\n } else {\n next.caret = {\n chainId: ownerLocated.chain.id,\n index: ownerLocated.index,\n };\n }\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretVertical', 'sub->up');\n return next;\n }\n next.caret = {\n chainId: ownerLocated.chain.id,\n index: ownerLocated.index + 1,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretVertical', 'sub->down-exit');\n return next;\n }\n\n if (located.relation.kind !== 'root' && located.relation.kind !== 'inner') {\n return session;\n }\n\n const caretIdx = next.caret.index;\n if (caretIdx <= 0) {\n return session;\n }\n const nodeBeforeCaret = located.chain.nodes[caretIdx - 1];\n if (!nodeBeforeCaret) {\n return session;\n }\n\n const targetChain =\n direction === 'up'\n ? nodeBeforeCaret.superscript ?? nodeBeforeCaret.subscript\n : nodeBeforeCaret.subscript ?? nodeBeforeCaret.superscript;\n\n if (!targetChain) {\n return session;\n }\n next.caret = {\n chainId: targetChain.id,\n index: targetChain.nodes.length,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretVertical', `base->script:${direction}`);\n return next;\n}\n\nfunction insertLeaf(session: EditorSession, kind: 'char' | 'number' | 'operator', expr: string): EditorSession {\n const next = cloneEditorSession(session);\n const englishNode = createEditorNode(kind, expr);\n const arabicNode = createEditorNode(kind, expr);\n if (kind === 'char' && (next.currentCharacterFont ?? 'default') !== 'default') {\n englishNode.characterFont = next.currentCharacterFont;\n arabicNode.characterFont = next.currentCharacterFont;\n }\n arabicNode.id = englishNode.id;\n insertMirroredNode(next, next.caret.chainId, next.caret.index, englishNode, arabicNode);\n next.caret.index += 1;\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'insertLeaf', `${kind}:${expr}`);\n return next;\n}\n\n/** When Arabic active and flag on, number fragments prepend on both mirrored exprs (same printed string on EN/AR). */\nfunction shouldReverseArabicNumber(session: EditorSession): boolean {\n return session.activeSide === 'arabic' && session.arabicReverseNumberTyping;\n}\n\nfunction characterFontOf(node: EditorNode): CharacterFontId {\n return node.kind === 'char' ? node.characterFont ?? 'default' : 'default';\n}\n\n/** When split mode is off: merge into adjacent same-kind leaf (append after node at index-1, else prepend node at index). */\nfunction tryMergeLeafTyping(session: EditorSession, kind: 'char' | 'number', fragment: string): boolean {\n const engLocated = findChainById(session.englishTree, session.caret.chainId);\n if (!engLocated) {\n return false;\n }\n const nodes = engLocated.chain.nodes;\n const i = session.caret.index;\n let targetId: string | null = null;\n let prepend = false;\n if (i > 0) {\n const prev = nodes[i - 1];\n if (prev.kind === kind && (kind !== 'char' || characterFontOf(prev) === (session.currentCharacterFont ?? 'default'))) {\n targetId = prev.id;\n prepend = false;\n }\n }\n if (!targetId && i < nodes.length) {\n const fwd = nodes[i];\n if (fwd.kind === kind && (kind !== 'char' || characterFontOf(fwd) === (session.currentCharacterFont ?? 'default'))) {\n targetId = fwd.id;\n prepend = true;\n }\n }\n if (!targetId) {\n return false;\n }\n const englishHit = findNodeById(session.englishTree, targetId);\n const arabicHit = findNodeById(session.arabicTree, targetId);\n if (!englishHit || !arabicHit) {\n return false;\n }\n const prependBoth = kind === 'number' && shouldReverseArabicNumber(session) ? true : prepend;\n if (prependBoth) {\n englishHit.node.expr = `${fragment}${englishHit.node.expr}`;\n arabicHit.node.expr = `${fragment}${arabicHit.node.expr}`;\n } else {\n englishHit.node.expr = `${englishHit.node.expr}${fragment}`;\n arabicHit.node.expr = `${arabicHit.node.expr}${fragment}`;\n }\n markExprSync(session, targetId);\n return true;\n}\n\n/**\n * Replace any active selection with a freshly-cleared range, then return a base\n * session ready for the actual insert. Mutating helper so reducers stay short.\n */\nfunction replaceSelectionFirst(session: EditorSession): EditorSession {\n if (!isSelectionActive(session.selection)) {\n return session;\n }\n const next = cloneEditorSession(session);\n applyDeleteSelectionRange(next);\n syncSelectionToCaret(next);\n return next;\n}\n\n/** Returns true when the node before the caret is a pure-digit number leaf (no existing dot). */\nfunction precedingIsExtendableNumber(session: EditorSession): boolean {\n const located = findChainById(session.englishTree, session.caret.chainId);\n if (!located || session.caret.index <= 0) {\n return false;\n }\n const prev = located.chain.nodes[session.caret.index - 1];\n if (!prev || prev.kind !== 'number') {\n return false;\n }\n if (prev.expr.includes('.')) {\n return false;\n }\n return /^\\d+$/.test(prev.expr);\n}\n\n/** One-shot: forces the next insertChar/insertNumber to start a new leaf instead of merging. No-op in split mode. */\nexport function breakLeafTyping(session: EditorSession): EditorSession {\n if (session.splitLeafTyping) {\n return session;\n }\n const next = cloneEditorSession(session);\n next.forceSplitNextLeaf = true;\n appendDebug(next, 'breakLeafTyping', 'split-next');\n return next;\n}\n\nexport function setCurrentCharacterFont(session: EditorSession, fontId: CharacterFontId): EditorSession {\n const next = cloneEditorSession(session);\n next.currentCharacterFont = fontId;\n appendDebug(next, 'setCurrentCharacterFont', fontId);\n return next;\n}\n\nexport function toggleTakweenCharacterFont(session: EditorSession): EditorSession {\n return setCurrentCharacterFont(session, (session.currentCharacterFont ?? 'default') === 'takween' ? 'default' : 'takween');\n}\n\nexport function setCurrentDigitForm(session: EditorSession, digitForm: DigitFormId): EditorSession {\n const next = cloneEditorSession(session);\n next.currentDigitForm = digitForm;\n appendDebug(next, 'setCurrentDigitForm', digitForm);\n return next;\n}\n\nexport function insertChar(session: EditorSession, expr: string): EditorSession {\n const base = replaceSelectionFirst(session);\n if (!base.splitLeafTyping && !base.forceSplitNextLeaf) {\n const next = cloneEditorSession(base);\n if (tryMergeLeafTyping(next, 'char', expr)) {\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'mergeLeaf', `char:${expr}`);\n return next;\n }\n }\n const inserted = insertLeaf(base, 'char', expr);\n inserted.forceSplitNextLeaf = false;\n return inserted;\n}\n\nexport function insertNumber(session: EditorSession, expr: string): EditorSession {\n const base = replaceSelectionFirst(session);\n if (!base.splitLeafTyping && !base.forceSplitNextLeaf) {\n const next = cloneEditorSession(base);\n if (tryMergeLeafTyping(next, 'number', expr)) {\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'mergeLeaf', `number:${expr}`);\n return next;\n }\n }\n const inserted = insertLeaf(base, 'number', expr);\n inserted.forceSplitNextLeaf = false;\n return inserted;\n}\n\nexport function insertDivideOperator(session: EditorSession): EditorSession {\n const base = replaceSelectionFirst(session);\n const next = cloneEditorSession(base);\n const englishNode = createEditorNode('operator', DIVIDE_OPERATOR_EN);\n const arabicNode = createEditorNode('operator', DIVIDE_OPERATOR_AR);\n arabicNode.id = englishNode.id;\n insertMirroredNode(next, next.caret.chainId, next.caret.index, englishNode, arabicNode);\n markExprSync(next, englishNode.id);\n next.caret.index += 1;\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'insertDivideOperator', '');\n return next;\n}\n\nexport function insertOperator(session: EditorSession, expr: string): EditorSession {\n if (expr === '.' && !session.splitLeafTyping && precedingIsExtendableNumber(session)) {\n return insertNumber(session, '.');\n }\n if (expr === DIVIDE_OPERATOR_EN || expr === DIVIDE_OPERATOR_AR) {\n return insertDivideOperator(session);\n }\n const base = replaceSelectionFirst(session);\n return insertLeaf(base, 'operator', expr);\n}\n\nexport function insertAtomicCommand(session: EditorSession, commandId: AtomicCommandId): EditorSession {\n const base = replaceSelectionFirst(session);\n const next = cloneEditorSession(base);\n const englishNode = createAtomicCommandNode(commandId);\n const arabicNode = createAtomicCommandNode(commandId);\n arabicNode.id = englishNode.id;\n insertMirroredNode(next, next.caret.chainId, next.caret.index, englishNode, arabicNode);\n next.caret.index += 1;\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'insertAtomicCommand', commandId);\n return next;\n}\n\nexport function insertAtomicOperatorCommand(session: EditorSession, commandId: AtomicOperatorCommandId): EditorSession {\n const base = replaceSelectionFirst(session);\n const next = cloneEditorSession(base);\n const englishNode = createAtomicOperatorCommandNode(commandId);\n const arabicNode = createAtomicOperatorCommandNode(commandId);\n arabicNode.id = englishNode.id;\n insertMirroredNode(next, next.caret.chainId, next.caret.index, englishNode, arabicNode);\n next.caret.index += 1;\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'insertAtomicOperatorCommand', commandId);\n return next;\n}\n\nexport function insertDelimiterPair(session: EditorSession, leftDelimExpr: string, rightDelimExpr: string): EditorSession {\n const base = replaceSelectionFirst(session);\n const next = cloneEditorSession(base);\n const englishNode = createDelimiterNode(leftDelimExpr, rightDelimExpr);\n const arabicNode = createDelimiterNode(leftDelimExpr, rightDelimExpr);\n arabicNode.id = englishNode.id;\n if (arabicNode.innerExpr && englishNode.innerExpr) {\n arabicNode.innerExpr.id = englishNode.innerExpr.id;\n }\n insertMirroredNode(next, next.caret.chainId, next.caret.index, englishNode, arabicNode);\n next.caret = {\n chainId: englishNode.innerExpr ? englishNode.innerExpr.id : next.caret.chainId,\n index: 0,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'insertDelimiterPair', `${leftDelimExpr}${rightDelimExpr}`);\n return next;\n}\n\nexport function insertFraction(session: EditorSession): EditorSession {\n const base = replaceSelectionFirst(session);\n const next = cloneEditorSession(base);\n const englishNode = createFracNode();\n const arabicNode = createFracNode();\n arabicNode.id = englishNode.id;\n if (arabicNode.numerator && englishNode.numerator) {\n arabicNode.numerator.id = englishNode.numerator.id;\n }\n if (arabicNode.denominator && englishNode.denominator) {\n arabicNode.denominator.id = englishNode.denominator.id;\n }\n insertMirroredNode(next, next.caret.chainId, next.caret.index, englishNode, arabicNode);\n next.caret = {\n chainId: englishNode.numerator ? englishNode.numerator.id : next.caret.chainId,\n index: 0,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'insertFraction', '');\n return next;\n}\n\nfunction insertDerivativeFrac(\n session: EditorSession,\n build: () => { english: EditorNode; arabic: EditorNode },\n debugLabel: string,\n): EditorSession {\n const base = replaceSelectionFirst(session);\n const next = cloneEditorSession(base);\n const { english, arabic } = build();\n insertMirroredNode(next, next.caret.chainId, next.caret.index, english, arabic);\n syncSubtreeRecursive(next, english, arabic);\n next.caret = derivativeTemplateInitialCaret(english);\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, debugLabel, '');\n return next;\n}\n\nexport function insertFirstDerivative(session: EditorSession): EditorSession {\n return insertDerivativeFrac(session, buildFirstDerivativeFrac, 'insertFirstDerivative');\n}\n\nexport function insertSecondDerivative(session: EditorSession): EditorSession {\n return insertDerivativeFrac(session, buildSecondDerivativeFrac, 'insertSecondDerivative');\n}\n\nexport function insertSqrt(session: EditorSession): EditorSession {\n const base = replaceSelectionFirst(session);\n const next = cloneEditorSession(base);\n const englishNode = createSqrtNode();\n const arabicNode = createSqrtNode();\n arabicNode.id = englishNode.id;\n if (arabicNode.radicand && englishNode.radicand) {\n arabicNode.radicand.id = englishNode.radicand.id;\n }\n if (arabicNode.rootIndex && englishNode.rootIndex) {\n arabicNode.rootIndex.id = englishNode.rootIndex.id;\n }\n insertMirroredNode(next, next.caret.chainId, next.caret.index, englishNode, arabicNode);\n next.caret = {\n chainId: englishNode.radicand ? englishNode.radicand.id : next.caret.chainId,\n index: 0,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'insertSqrt', '');\n return next;\n}\n\nexport function insertOverset(session: EditorSession): EditorSession {\n const base = replaceSelectionFirst(session);\n const next = cloneEditorSession(base);\n const englishNode = createOversetNode();\n const arabicNode = createOversetNode();\n arabicNode.id = englishNode.id;\n if (arabicNode.overExpr && englishNode.overExpr) {\n arabicNode.overExpr.id = englishNode.overExpr.id;\n }\n if (arabicNode.baseExpr && englishNode.baseExpr) {\n arabicNode.baseExpr.id = englishNode.baseExpr.id;\n }\n insertMirroredNode(next, next.caret.chainId, next.caret.index, englishNode, arabicNode);\n next.caret = {\n chainId: englishNode.overExpr ? englishNode.overExpr.id : next.caret.chainId,\n index: 0,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'insertOverset', '');\n return next;\n}\n\nexport function insertUnderset(session: EditorSession): EditorSession {\n const base = replaceSelectionFirst(session);\n const next = cloneEditorSession(base);\n const englishNode = createUndersetNode();\n const arabicNode = createUndersetNode();\n arabicNode.id = englishNode.id;\n if (arabicNode.underExpr && englishNode.underExpr) {\n arabicNode.underExpr.id = englishNode.underExpr.id;\n }\n if (arabicNode.baseExpr && englishNode.baseExpr) {\n arabicNode.baseExpr.id = englishNode.baseExpr.id;\n }\n insertMirroredNode(next, next.caret.chainId, next.caret.index, englishNode, arabicNode);\n next.caret = {\n chainId: englishNode.underExpr ? englishNode.underExpr.id : next.caret.chainId,\n index: 0,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'insertUnderset', '');\n return next;\n}\n\nexport function insertLimitsSeriesTemplate(\n session: EditorSession,\n commandId: AtomicCommandId,\n): EditorSession {\n const base = replaceSelectionFirst(session);\n const next = cloneEditorSession(base);\n const { english, arabic } = buildLimitsSeriesTemplate(commandId);\n insertMirroredNode(next, next.caret.chainId, next.caret.index, english, arabic);\n syncSubtreeRecursive(next, english, arabic);\n next.caret = limitsSeriesTemplateInitialCaret(english);\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'insertLimitsSeriesTemplate', commandId);\n return next;\n}\n\nexport function insertAccentPair(session: EditorSession): EditorSession {\n const base = replaceSelectionFirst(session);\n const next = cloneEditorSession(base);\n const { english, arabic } = buildAccentPairTemplate();\n insertMirroredNode(next, next.caret.chainId, next.caret.index, english, arabic);\n syncSubtreeRecursive(next, english, arabic);\n next.caret = accentPairTemplateInitialCaret(english);\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'insertAccentPair', '');\n return next;\n}\n\n/**\n * Insert a one-argument math accent. When a selection is active in one chain,\n * wrap the selected nodes into the accent base; otherwise insert an empty base\n * and place the caret inside it.\n */\nexport function insertAccent(session: EditorSession, accentId: AccentCommandId): EditorSession {\n const next = cloneEditorSession(session);\n const englishNode = createAccentNode(accentId);\n const arabicNode = createAccentNode(accentId);\n arabicNode.id = englishNode.id;\n if (arabicNode.baseExpr && englishNode.baseExpr) {\n arabicNode.baseExpr.id = englishNode.baseExpr.id;\n }\n\n if (isSelectionActive(next.selection) && next.selection) {\n const sel = next.selection;\n const { start, end } = normalizeSelection(sel);\n const englishLocated = findChainById(next.englishTree, sel.chainId);\n const arabicLocated = findChainById(next.arabicTree, sel.chainId);\n if (englishLocated && arabicLocated && end > start) {\n const count = end - start;\n const englishWrapped = englishLocated.chain.nodes.splice(start, count);\n const arabicWrapped = arabicLocated.chain.nodes.splice(start, count);\n englishNode.baseExpr!.nodes = englishWrapped;\n arabicNode.baseExpr!.nodes = arabicWrapped;\n englishLocated.chain.nodes.splice(start, 0, englishNode);\n arabicLocated.chain.nodes.splice(start, 0, arabicNode);\n syncSubtreeRecursive(next, englishNode, arabicNode);\n next.caret = {\n chainId: englishNode.baseExpr!.id,\n index: englishWrapped.length,\n };\n next.selection = null;\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'insertAccent', `${accentId}:wrap`);\n return next;\n }\n }\n\n insertMirroredNode(next, next.caret.chainId, next.caret.index, englishNode, arabicNode);\n syncSubtreeRecursive(next, englishNode, arabicNode);\n next.caret = {\n chainId: englishNode.baseExpr ? englishNode.baseExpr.id : next.caret.chainId,\n index: 0,\n };\n next.selection = null;\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'insertAccent', `${accentId}:empty`);\n return next;\n}\n\nexport function insertMatrixEnv(\n session: EditorSession,\n style: MatrixEnvStyle,\n rows: number,\n columns: number,\n): EditorSession {\n return insertGridEnv(session, style, rows, columns);\n}\n\nexport function insertArrayEnv(\n session: EditorSession,\n rows: number,\n columns: number,\n columnAlignments?: EnvColumnAlignment[],\n): EditorSession {\n return insertGridEnv(session, 'array', rows, columns, columnAlignments);\n}\n\nexport function insertAlignedEnv(\n session: EditorSession,\n rows: number,\n columns: number,\n): EditorSession {\n return insertGridEnv(session, 'aligned', rows, columns);\n}\n\nfunction insertGridEnv(\n session: EditorSession,\n envName: GridEnvName,\n rows: number,\n columns: number,\n columnAlignments?: EnvColumnAlignment[],\n): EditorSession {\n const base = replaceSelectionFirst(session);\n const next = cloneEditorSession(base);\n const englishNode = createGridEnvNode(envName, rows, columns, columnAlignments);\n const arabicNode = createGridEnvNode(envName, rows, columns, columnAlignments);\n arabicNode.id = englishNode.id;\n syncMatrixCellChainIds(englishNode, arabicNode);\n insertMirroredNode(next, next.caret.chainId, next.caret.index, englishNode, arabicNode);\n next.caret = {\n chainId: englishNode.matrixRows?.[0]?.[0]?.id ?? next.caret.chainId,\n index: 0,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'insertGridEnv', `${envName}:${String(rows)}x${String(columns)}`);\n return next;\n}\n\nexport function setMatrixEnvStyle(session: EditorSession, style: MatrixEnvStyle): EditorSession {\n const next = cloneEditorSession(session);\n const pair = findSelectedMatrixPair(next);\n if (!pair) {\n return session;\n }\n pair.english.envName = style;\n pair.arabic.envName = style;\n pair.english.matrixStyle = style;\n pair.arabic.matrixStyle = style;\n pair.english.columnAlignments = null;\n pair.arabic.columnAlignments = null;\n appendDebug(next, 'setMatrixEnvStyle', style);\n return next;\n}\n\nexport function setArrayColumnAlignment(\n session: EditorSession,\n columnIndex: number,\n alignment: EnvColumnAlignment,\n): EditorSession {\n const next = cloneEditorSession(session);\n const pair = findSelectedMatrixPair(next);\n if (!pair || (pair.english.envName ?? pair.english.matrixStyle) !== 'array') {\n return session;\n }\n normalizeArrayAlignments(pair.english);\n normalizeArrayAlignments(pair.arabic);\n const columnCount = pair.english.columnAlignments?.length ?? 0;\n const safeIndex = Math.max(0, Math.min(columnIndex, Math.max(0, columnCount - 1)));\n if (pair.english.columnAlignments && pair.arabic.columnAlignments && columnCount > 0) {\n pair.english.columnAlignments[safeIndex] = alignment;\n pair.arabic.columnAlignments[safeIndex] = alignment;\n }\n appendDebug(next, 'setArrayColumnAlignment', `${String(safeIndex)}:${alignment}`);\n return next;\n}\n\nexport function addMatrixRow(session: EditorSession): EditorSession {\n const next = cloneEditorSession(session);\n const pair = findSelectedMatrixPair(next);\n if (!pair || !pair.english.matrixRows || !pair.arabic.matrixRows || pair.english.matrixRows.length >= 12) {\n return session;\n }\n const columnCount = Math.max(1, pair.english.matrixRows[0]?.length ?? 1);\n const englishRow = createMatrixRow(columnCount);\n const arabicRow = createMatrixRow(columnCount);\n for (let i = 0; i < columnCount; i += 1) {\n arabicRow[i].id = englishRow[i].id;\n }\n pair.english.matrixRows.push(englishRow);\n pair.arabic.matrixRows.push(arabicRow);\n normalizeArrayAlignments(pair.english);\n normalizeArrayAlignments(pair.arabic);\n appendDebug(next, 'addMatrixRow', pair.english.id);\n return next;\n}\n\nexport function removeMatrixRow(session: EditorSession): EditorSession {\n const next = cloneEditorSession(session);\n const pair = findSelectedMatrixPair(next);\n if (!pair || !pair.english.matrixRows || !pair.arabic.matrixRows || pair.english.matrixRows.length <= 1) {\n return session;\n }\n pair.english.matrixRows.pop();\n pair.arabic.matrixRows.pop();\n normalizeArrayAlignments(pair.english);\n normalizeArrayAlignments(pair.arabic);\n appendDebug(next, 'removeMatrixRow', pair.english.id);\n return next;\n}\n\nexport function addMatrixColumn(session: EditorSession): EditorSession {\n const next = cloneEditorSession(session);\n const pair = findSelectedMatrixPair(next);\n if (!pair || !pair.english.matrixRows || !pair.arabic.matrixRows) {\n return session;\n }\n const columnCount = pair.english.matrixRows[0]?.length ?? 0;\n if (columnCount >= 12) {\n return session;\n }\n for (let rowIndex = 0; rowIndex < pair.english.matrixRows.length; rowIndex += 1) {\n const englishCell = createEditorChain();\n const arabicCell = createEditorChain();\n arabicCell.id = englishCell.id;\n pair.english.matrixRows[rowIndex].push(englishCell);\n pair.arabic.matrixRows[rowIndex].push(arabicCell);\n }\n normalizeArrayAlignments(pair.english);\n normalizeArrayAlignments(pair.arabic);\n appendDebug(next, 'addMatrixColumn', pair.english.id);\n return next;\n}\n\nexport function removeMatrixColumn(session: EditorSession): EditorSession {\n const next = cloneEditorSession(session);\n const pair = findSelectedMatrixPair(next);\n if (!pair || !pair.english.matrixRows || !pair.arabic.matrixRows) {\n return session;\n }\n const columnCount = pair.english.matrixRows[0]?.length ?? 0;\n if (columnCount <= 1) {\n return session;\n }\n for (let rowIndex = 0; rowIndex < pair.english.matrixRows.length; rowIndex += 1) {\n pair.english.matrixRows[rowIndex].pop();\n pair.arabic.matrixRows[rowIndex].pop();\n }\n normalizeArrayAlignments(pair.english);\n normalizeArrayAlignments(pair.arabic);\n appendDebug(next, 'removeMatrixColumn', pair.english.id);\n return next;\n}\n\nfunction addScript(session: EditorSession, type: 'superscript' | 'subscript'): EditorSession {\n const targetNodeId = session.selectedNodeId;\n if (!targetNodeId) {\n return session;\n }\n const next = cloneEditorSession(session);\n const englishLocated = findNodeById(next.englishTree, targetNodeId);\n const arabicLocated = findNodeById(next.arabicTree, targetNodeId);\n if (!englishLocated || !arabicLocated) {\n return session;\n }\n const englishNode = englishLocated.node;\n const arabicNode = arabicLocated.node;\n if (!englishNode[type]) {\n englishNode[type] = createEditorChain();\n }\n if (!arabicNode[type]) {\n arabicNode[type] = createEditorChain();\n }\n if (englishNode[type] && arabicNode[type]) {\n arabicNode[type].id = englishNode[type].id;\n next.caret = {\n chainId: englishNode[type].id,\n index: englishNode[type].nodes.length,\n };\n }\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, `add${type === 'superscript' ? 'Sup' : 'Sub'}`, targetNodeId);\n return next;\n}\n\nfunction removeScript(session: EditorSession, type: 'superscript' | 'subscript'): EditorSession {\n const targetNodeId = session.selectedNodeId;\n if (!targetNodeId) {\n return session;\n }\n const next = cloneEditorSession(session);\n const englishLocated = findNodeById(next.englishTree, targetNodeId);\n const arabicLocated = findNodeById(next.arabicTree, targetNodeId);\n if (!englishLocated || !arabicLocated) {\n return session;\n }\n englishLocated.node[type] = null;\n arabicLocated.node[type] = null;\n next.caret = {\n chainId: englishLocated.chain.id,\n index: englishLocated.index + 1,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, `remove${type === 'superscript' ? 'Sup' : 'Sub'}`, targetNodeId);\n return next;\n}\n\nexport function addSup(session: EditorSession): EditorSession {\n return addScript(session, 'superscript');\n}\n\nexport function addSub(session: EditorSession): EditorSession {\n return addScript(session, 'subscript');\n}\n\nexport function removeSup(session: EditorSession): EditorSession {\n return removeScript(session, 'superscript');\n}\n\nexport function removeSub(session: EditorSession): EditorSession {\n return removeScript(session, 'subscript');\n}\n\nexport function selectNode(session: EditorSession, nodeId: string | null): EditorSession {\n const next = cloneEditorSession(session);\n next.selectedNodeId = nodeId;\n next.selectedStructureNodeId = null;\n return next;\n}\n\nexport function deleteStructure(session: EditorSession): EditorSession {\n const targetNodeId = session.selectedStructureNodeId ?? session.selectedNodeId;\n if (!targetNodeId) {\n return session;\n }\n const next = cloneEditorSession(session);\n const activeKey = activeTreeKey(next.activeSide);\n const located = findNodeById(next[activeKey], targetNodeId);\n if (!located) {\n return session;\n }\n const removed = removeMirroredNodeById(next, targetNodeId);\n if (!removed) {\n return session;\n }\n next.caret = {\n chainId: located.chain.id,\n index: located.index,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'deleteStructure', targetNodeId);\n return next;\n}\n\nexport function deleteBackward(session: EditorSession): EditorSession {\n if (isSelectionActive(session.selection)) {\n const next = cloneEditorSession(session);\n applyDeleteSelectionRange(next);\n syncSelectionToCaret(next);\n appendDebug(next, 'deleteBackward', 'deleted range');\n return next;\n }\n const next = cloneEditorSession(session);\n const activeKey = activeTreeKey(next.activeSide);\n const located = findChainById(next[activeKey], next.caret.chainId);\n if (!located) {\n return session;\n }\n if (next.caret.index <= 0) {\n return session;\n }\n const previousNode = located.chain.nodes[next.caret.index - 1];\n if (!previousNode) {\n return session;\n }\n if (\n (previousNode.kind === 'delimiter' || previousNode.kind === 'frac' || previousNode.kind === 'sqrt' || previousNode.kind === 'overset' || previousNode.kind === 'underset' || previousNode.kind === 'accent' || previousNode.kind === 'env') &&\n next.selectedStructureNodeId !== previousNode.id\n ) {\n next.selectedStructureNodeId = previousNode.id;\n next.selectedNodeId = previousNode.id;\n appendDebug(next, 'deleteBackward', 'selected structure');\n return next;\n }\n if (\n !next.splitLeafTyping &&\n (previousNode.kind === 'char' || previousNode.kind === 'number') &&\n previousNode.expr.length > 1\n ) {\n const id = previousNode.id;\n const englishHit = findNodeById(next.englishTree, id);\n const arabicHit = findNodeById(next.arabicTree, id);\n if (englishHit && arabicHit) {\n if (previousNode.kind === 'number' && shouldReverseArabicNumber(next)) {\n englishHit.node.expr = englishHit.node.expr.slice(1);\n arabicHit.node.expr = arabicHit.node.expr.slice(1);\n } else {\n englishHit.node.expr = englishHit.node.expr.slice(0, -1);\n arabicHit.node.expr = arabicHit.node.expr.slice(0, -1);\n }\n markExprSync(next, id);\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'deleteBackward', 'trimmed leaf');\n return next;\n }\n }\n const removed = removeMirroredNodeById(next, previousNode.id);\n if (!removed) {\n return session;\n }\n next.caret.index = Math.max(0, next.caret.index - 1);\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'deleteBackward', 'removed node');\n return next;\n}\n\nexport function deleteForward(session: EditorSession): EditorSession {\n if (isSelectionActive(session.selection)) {\n const next = cloneEditorSession(session);\n applyDeleteSelectionRange(next);\n syncSelectionToCaret(next);\n appendDebug(next, 'deleteForward', 'deleted range');\n return next;\n }\n const next = cloneEditorSession(session);\n const activeKey = activeTreeKey(next.activeSide);\n const located = findChainById(next[activeKey], next.caret.chainId);\n if (!located) {\n return session;\n }\n if (next.caret.index >= located.chain.nodes.length) {\n return session;\n }\n const node = located.chain.nodes[next.caret.index];\n if (!node) {\n return session;\n }\n if (!next.splitLeafTyping && (node.kind === 'char' || node.kind === 'number') && node.expr.length > 1) {\n const englishHit = findNodeById(next.englishTree, node.id);\n const arabicHit = findNodeById(next.arabicTree, node.id);\n if (englishHit && arabicHit) {\n if (node.kind === 'number' && shouldReverseArabicNumber(next)) {\n englishHit.node.expr = englishHit.node.expr.slice(0, -1);\n arabicHit.node.expr = arabicHit.node.expr.slice(0, -1);\n } else {\n englishHit.node.expr = englishHit.node.expr.slice(1);\n arabicHit.node.expr = arabicHit.node.expr.slice(1);\n }\n markExprSync(next, node.id);\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'deleteForward', 'trimmed leaf');\n return next;\n }\n }\n const removed = removeMirroredNodeById(next, node.id);\n if (!removed) {\n return session;\n }\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'deleteForward', 'removed node');\n return next;\n}\n\nexport function setExpr(session: EditorSession, nodeId: string, expr: string): EditorSession {\n const next = cloneEditorSession(session);\n const activeKey = activeTreeKey(next.activeSide);\n const passiveKey = passiveTreeKey(next.activeSide);\n const activeNode = findNodeById(next[activeKey], nodeId);\n const passiveNode = findNodeById(next[passiveKey], nodeId);\n if (!activeNode || !passiveNode) {\n return session;\n }\n activeNode.node.expr = expr;\n markExprSync(next, nodeId);\n appendDebug(next, 'setExpr', nodeId);\n return next;\n}\n\nexport function createStarterSession(): EditorSession {\n const englishRoot = createEditorChain([createEditorNode('char', 'x')]);\n const arabicRoot = createEditorChain([createEditorNode('char', 'س')]);\n arabicRoot.id = englishRoot.id;\n arabicRoot.nodes[0].id = englishRoot.nodes[0].id;\n const session: EditorSession = {\n englishTree: englishRoot,\n arabicTree: arabicRoot,\n activeSide: 'arabic',\n splitLeafTyping: false,\n forceSplitNextLeaf: false,\n arabicReverseNumberTyping: true,\n currentCharacterFont: 'default',\n currentDigitForm: 'western',\n caret: {\n chainId: englishRoot.id,\n index: 1,\n },\n selection: null,\n selectedNodeId: englishRoot.nodes[0].id,\n selectedStructureNodeId: null,\n sync: {\n [englishRoot.nodes[0].id]: { expr: 'diverged' },\n },\n debugLog: [],\n };\n appendDebug(session, 'createStarterSession', 'initialized');\n return session;\n}\n\nexport function syncStateSummary(session: EditorSession, uiLocale: ButexUiLocale = 'ar'): string {\n const messages = equationEditorMessages(uiLocale);\n const diverged = Object.values(session.sync).filter((entry) => entry.expr === 'diverged').length;\n if (diverged === 0) {\n return messages.synced;\n }\n return uiLocale === 'ar' ? `يوجد ${String(diverged)} ${messages.differentItems}` : `${String(diverged)} ${messages.differentItems}`;\n}\n\nexport function setRenderError(session: EditorSession, message: string | null): EditorSession {\n const next = cloneEditorSession(session);\n if (next.debugLog.length === 0) {\n appendDebug(next, 'render', 'init');\n }\n const last = next.debugLog[next.debugLog.length - 1];\n next.debugLog[next.debugLog.length - 1] = {\n ...last,\n renderOk: message === null,\n renderError: message,\n };\n return next;\n}\n\nexport function activeSideLabel(side: EditorSide, uiLocale: ButexUiLocale = 'ar'): string {\n const messages = equationEditorMessages(uiLocale);\n return side === 'arabic' ? messages.arabicSide : messages.englishSide;\n}\n\nconst PASTE_OPERATORS = new Set(['+', '-', '*', '/', '=', '<', '>', '.']);\n\n/** Read-only: build a fragment from the active selection (or null when collapsed). */\nexport function copySelection(session: EditorSession): EditorFragment | null {\n return serializeSelection(session);\n}\n\n/** Cut: removes the selection and returns both the cleaned session and the fragment. */\nexport function cutSelection(\n session: EditorSession,\n): { session: EditorSession; fragment: EditorFragment | null } {\n const fragment = serializeSelection(session);\n if (!fragment) {\n return { session, fragment: null };\n }\n const next = cloneEditorSession(session);\n applyDeleteSelectionRange(next);\n syncSelectionToCaret(next);\n appendDebug(next, 'cutSelection', `count=${String(fragment.english.length)}`);\n return { session: next, fragment };\n}\n\n/**\n * Insert a structured fragment at the caret in the active chain. The fragment\n * is re-id'd so it can't collide with the live tree, mirrored EN/AR ids are\n * preserved, and sync entries are populated for every nested node.\n */\nexport function pasteFragment(session: EditorSession, fragment: EditorFragment): EditorSession {\n if (!fragment || !fragment.english.length || !fragment.arabic.length) {\n return session;\n }\n const next = cloneEditorSession(session);\n applyDeleteSelectionRange(next);\n\n const fresh = regenerateFragmentIds(fragment);\n const limit = Math.min(fresh.english.length, fresh.arabic.length);\n for (let i = 0; i < limit; i += 1) {\n const eng = fresh.english[i];\n const ar = fresh.arabic[i];\n insertMirroredNode(next, next.caret.chainId, next.caret.index, eng, ar);\n syncSubtreeRecursive(next, eng, ar);\n next.caret = { chainId: next.caret.chainId, index: next.caret.index + 1 };\n }\n next.selection = null;\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'pasteFragment', `count=${String(limit)}`);\n return next;\n}\n\n/**\n * Plain-text fallback paste. Each character is dispatched through the existing\n * typing path so split/merge mode and selection-replace behave the same as\n * keyboard input. Whitespace is silently skipped in this MVP.\n */\nexport function pasteText(session: EditorSession, text: string): EditorSession {\n if (!text) {\n return session;\n }\n let s = session;\n let i = 0;\n while (i < text.length) {\n const ch = text[i]!;\n if (ch === '\\n' || ch === '\\r' || ch === '\\t' || ch === ' ') {\n if (!s.splitLeafTyping) {\n s = breakLeafTyping(s);\n }\n i += 1;\n continue;\n }\n if (/^[0-9]$/.test(ch)) {\n let j = i + 1;\n let sawDot = false;\n while (j < text.length) {\n const c = text[j]!;\n if (/^[0-9]$/.test(c)) {\n j += 1;\n continue;\n }\n if (c === '.' && !sawDot && j + 1 < text.length && /^[0-9]$/.test(text[j + 1]!)) {\n sawDot = true;\n j += 1;\n continue;\n }\n break;\n }\n s = insertNumber(s, text.slice(i, j));\n i = j;\n continue;\n }\n if (PASTE_OPERATORS.has(ch)) {\n s = insertOperator(s, ch);\n i += 1;\n continue;\n }\n if (ch === DIVIDE_OPERATOR_AR) {\n s = insertDivideOperator(s);\n i += 1;\n continue;\n }\n s = insertChar(s, ch);\n i += 1;\n }\n return s;\n}\n","import type { EditorChain, EditorNode } from '../types.js';\n\ntype BuildChain = (chain: EditorChain) => HTMLElement;\n\nexport const DELIMITER_CSS = `\n.delim-pair {\n display: inline-flex;\n align-items: stretch;\n min-height: 1.85em;\n}\n\n.delim-inner {\n display: inline-flex;\n align-items: center;\n}\n\n.delim {\n display: inline-flex;\n align-self: stretch;\n align-items: center;\n justify-content: center;\n color: var(--butex-delim-color, #475569);\n padding: 0 1px;\n min-height: 100%;\n}\n\n.delim-glyph {\n display: inline-flex;\n align-items: center;\n line-height: 1;\n font-size: clamp(20px, 1.08em + 0.8vh, 36px);\n transform: translateY(-20%) scaleY(var(--butex-delim-scale, 1));\n transform-origin: center;\n}\n`.trim();\n\nconst DELIMITER_BASE_HEIGHT_PX = 18;\nconst DELIMITER_MAX_SCALE = 4.8;\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, value));\n}\n\nfunction applyDelimiterScale(pair: HTMLElement, inner: HTMLElement): void {\n const innerHeight = Math.max(inner.getBoundingClientRect().height, DELIMITER_BASE_HEIGHT_PX);\n const scale = clamp((innerHeight / DELIMITER_BASE_HEIGHT_PX) * 1.18, 1.18, DELIMITER_MAX_SCALE);\n pair.style.setProperty('--butex-delim-scale', scale.toFixed(3));\n}\n\nfunction visibleDelimiter(expr: string): string {\n return expr\n .replace('\\\\left', '')\n .replace('\\\\right', '')\n .replace('\\\\{', '{')\n .replace('\\\\}', '}');\n}\n\nexport function buildDelimiterNodeBody(node: EditorNode, buildChain: BuildChain): HTMLElement {\n const pair = document.createElement('span');\n pair.className = 'delim-pair';\n\n const left = document.createElement('span');\n left.className = 'delim delim--left';\n const leftGlyph = document.createElement('span');\n leftGlyph.className = 'delim-glyph';\n leftGlyph.textContent = visibleDelimiter(node.leftDelimExpr);\n left.appendChild(leftGlyph);\n pair.appendChild(left);\n\n const inner = document.createElement('span');\n inner.className = 'delim-inner';\n if (node.innerExpr) {\n inner.appendChild(buildChain(node.innerExpr));\n }\n pair.appendChild(inner);\n\n const right = document.createElement('span');\n right.className = 'delim delim--right';\n const rightGlyph = document.createElement('span');\n rightGlyph.className = 'delim-glyph';\n rightGlyph.textContent = visibleDelimiter(node.rightDelimExpr);\n right.appendChild(rightGlyph);\n pair.appendChild(right);\n\n applyDelimiterScale(pair, inner);\n requestAnimationFrame(() => applyDelimiterScale(pair, inner));\n\n return pair;\n}\n","import type { EditorChain, EditorNode } from '../types.js';\n\ntype BuildChain = (chain: EditorChain) => HTMLElement;\n\nexport const FRAC_CSS = `\n.frac {\n display: inline-flex;\n flex-direction: column;\n align-items: stretch;\n justify-content: center;\n vertical-align: middle;\n margin: 0 3px;\n min-width: 1.5em;\n}\n\n.frac-num,\n.frac-den {\n display: inline-flex;\n justify-content: center;\n align-items: center;\n min-height: 1.1em;\n padding: 0 4px;\n}\n\n.frac-bar {\n align-self: stretch;\n height: 1px;\n background: var(--butex-frac-bar, currentColor);\n opacity: 0.88;\n}\n`.trim();\n\nexport function buildFracNodeBody(node: EditorNode, buildChain: BuildChain): HTMLElement {\n const wrap = document.createElement('span');\n wrap.className = 'frac';\n\n const num = document.createElement('span');\n num.className = 'frac-num';\n if (node.numerator) {\n num.appendChild(buildChain(node.numerator));\n }\n\n const bar = document.createElement('span');\n bar.className = 'frac-bar';\n bar.setAttribute('aria-hidden', 'true');\n\n const den = document.createElement('span');\n den.className = 'frac-den';\n if (node.denominator) {\n den.appendChild(buildChain(node.denominator));\n }\n\n wrap.appendChild(num);\n wrap.appendChild(bar);\n wrap.appendChild(den);\n\n return wrap;\n}\n","import type { EditorChain, EditorNode, EditorSide } from '../types.js';\n\ntype BuildChain = (chain: EditorChain) => HTMLElement;\n\nexport const SQRT_CSS = `\n.sqrt {\n display: inline-flex;\n align-items: stretch;\n position: relative;\n vertical-align: middle;\n margin: 0 2px;\n min-height: 2.1em;\n direction: ltr;\n --butex-sqrt-scale: 1;\n}\n\n.sqrt.sqrt--english .sqrt-root {\n order: 1;\n}\n\n.sqrt.sqrt--english .sqrt-sign {\n order: 2;\n}\n\n.sqrt.sqrt--english .sqrt-radicand {\n order: 3;\n}\n\n.sqrt.sqrt--arabic .sqrt-radicand {\n order: 1;\n}\n\n.sqrt.sqrt--arabic .sqrt-sign {\n order: 2;\n}\n\n.sqrt.sqrt--arabic .sqrt-root {\n order: 3;\n}\n\n.sqrt.sqrt--arabic .sqrt-root,\n.sqrt.sqrt--arabic .sqrt-radicand {\n direction: rtl;\n}\n\n.sqrt-root {\n align-self: flex-start;\n min-width: 0.9em;\n min-height: 1em;\n margin-inline-end: -0.18em;\n transform: translate(0.16em, 0.02em);\n font-size: 0.64em;\n line-height: 1;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n position: relative;\n z-index: 1;\n}\n\n.sqrt.sqrt--arabic .sqrt-root {\n margin-inline-start: -0.22em;\n margin-inline-end: 0;\n transform: translate(-0.16em, 0.02em);\n}\n\n.sqrt-root .chain {\n min-height: auto;\n}\n\n.sqrt-sign {\n display: inline-flex;\n align-items: flex-end;\n justify-content: center;\n align-self: stretch;\n line-height: 0.78;\n font-size: 2em;\n color: var(--butex-sqrt-color, currentColor);\n transform: scaleY(var(--butex-sqrt-scale));\n transform-origin: center bottom;\n margin-inline-end: -0.24em;\n min-height: 100%;\n position: relative;\n z-index: 1;\n}\n\n.sqrt.sqrt--arabic .sqrt-sign {\n transform: scaleX(-1) scaleY(var(--butex-sqrt-scale));\n margin-inline-start: -0.24em;\n margin-inline-end: 0;\n}\n\n.sqrt-radicand {\n display: inline-flex;\n align-items: center;\n min-width: 1.35em;\n min-height: 1.35em;\n padding: 0.06em 0.24em 0;\n border-top: 2px solid var(--butex-sqrt-bar, currentColor);\n transform: translateY(-0.08em);\n position: relative;\n}\n\n.sqrt-radicand .chain {\n min-height: auto;\n}\n`.trim();\n\nconst SQRT_BASE_HEIGHT_PX = 32;\nconst SQRT_MAX_SCALE = 3.8;\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, value));\n}\n\nfunction applySqrtScale(wrap: HTMLElement, radicand: HTMLElement): void {\n const radicandHeight = Math.max(radicand.getBoundingClientRect().height, SQRT_BASE_HEIGHT_PX);\n const scale = clamp(radicandHeight / SQRT_BASE_HEIGHT_PX, 1, SQRT_MAX_SCALE);\n wrap.style.setProperty('--butex-sqrt-scale', scale.toFixed(3));\n}\n\nexport function buildSqrtNodeBody(node: EditorNode, buildChain: BuildChain, side: EditorSide): HTMLElement {\n const wrap = document.createElement('span');\n wrap.className = `sqrt sqrt--${side}`;\n\n const root = document.createElement('span');\n root.className = 'sqrt-root';\n if (node.rootIndex) {\n root.appendChild(buildChain(node.rootIndex));\n }\n\n const sign = document.createElement('span');\n sign.className = 'sqrt-sign';\n sign.setAttribute('aria-hidden', 'true');\n sign.textContent = '\\u221a';\n\n const radicand = document.createElement('span');\n radicand.className = 'sqrt-radicand';\n if (node.radicand) {\n radicand.appendChild(buildChain(node.radicand));\n }\n\n wrap.appendChild(root);\n wrap.appendChild(sign);\n wrap.appendChild(radicand);\n\n applySqrtScale(wrap, radicand);\n requestAnimationFrame(() => applySqrtScale(wrap, radicand));\n\n return wrap;\n}\n","import type { EditorChain, EditorNode } from '../types.js';\n\ntype BuildChain = (chain: EditorChain) => HTMLElement;\n\nexport const OVERSET_CSS = `\n.overset {\n display: inline-flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n vertical-align: middle;\n margin: 0 2px;\n min-width: 1.2em;\n}\n\n.overset-over {\n display: inline-flex;\n justify-content: center;\n align-items: center;\n min-height: 0.85em;\n padding: 0 2px;\n font-size: 0.72em;\n line-height: 1.1;\n}\n\n.overset-base {\n display: inline-flex;\n justify-content: center;\n align-items: center;\n min-height: 1.05em;\n padding: 0 2px;\n}\n`.trim();\n\nexport function buildOversetNodeBody(node: EditorNode, buildChain: BuildChain): HTMLElement {\n const wrap = document.createElement('span');\n wrap.className = 'overset';\n\n const over = document.createElement('span');\n over.className = 'overset-over';\n if (node.overExpr) {\n over.appendChild(buildChain(node.overExpr));\n }\n\n const base = document.createElement('span');\n base.className = 'overset-base';\n if (node.baseExpr) {\n base.appendChild(buildChain(node.baseExpr));\n }\n\n wrap.appendChild(over);\n wrap.appendChild(base);\n return wrap;\n}\n","import type { EditorChain, EditorNode } from '../types.js';\n\ntype BuildChain = (chain: EditorChain) => HTMLElement;\n\nexport const UNDERSET_CSS = `\n.underset {\n display: inline-flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n vertical-align: middle;\n margin: 0 2px;\n min-width: 1.2em;\n}\n\n.underset-base {\n display: inline-flex;\n justify-content: center;\n align-items: center;\n min-height: 1.05em;\n padding: 0 2px;\n}\n\n.underset-under {\n display: inline-flex;\n justify-content: center;\n align-items: center;\n min-height: 0.85em;\n padding: 0 2px;\n font-size: 0.72em;\n line-height: 1.1;\n}\n`.trim();\n\nexport function buildUndersetNodeBody(node: EditorNode, buildChain: BuildChain): HTMLElement {\n const wrap = document.createElement('span');\n wrap.className = 'underset';\n\n const base = document.createElement('span');\n base.className = 'underset-base';\n if (node.baseExpr) {\n base.appendChild(buildChain(node.baseExpr));\n }\n\n const under = document.createElement('span');\n under.className = 'underset-under';\n if (node.underExpr) {\n under.appendChild(buildChain(node.underExpr));\n }\n\n wrap.appendChild(base);\n wrap.appendChild(under);\n return wrap;\n}\n","import { accentCommandSpec } from '../accentCommands.js';\nimport type { EditorChain, EditorNode } from '../types.js';\n\ntype BuildChain = (chain: EditorChain) => HTMLElement;\n\nexport const ACCENT_CSS = `\n.math-accent {\n display: inline-flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n vertical-align: middle;\n margin: 0 2px;\n min-width: 1.1em;\n}\n\n.math-accent-chrome {\n display: inline-flex;\n justify-content: center;\n align-items: center;\n min-height: 0.7em;\n padding: 0 2px;\n font-size: 0.85em;\n line-height: 1;\n color: var(--butex-script-color, #475569);\n user-select: none;\n}\n\n.math-accent-base {\n display: inline-flex;\n justify-content: center;\n align-items: center;\n min-height: 1.05em;\n padding: 0 2px;\n}\n\n.math-accent--under .math-accent-chrome {\n min-height: 0.45em;\n border-top: 1.5px solid currentColor;\n width: 100%;\n font-size: 0;\n color: var(--butex-surface-fg, #0f172a);\n}\n`.trim();\n\nexport function buildAccentNodeBody(node: EditorNode, buildChain: BuildChain): HTMLElement {\n const wrap = document.createElement('span');\n const spec = accentCommandSpec(node.expr);\n const placement = spec?.placement ?? 'over';\n wrap.className = placement === 'under' ? 'math-accent math-accent--under' : 'math-accent math-accent--over';\n\n const chrome = document.createElement('span');\n chrome.className = 'math-accent-chrome';\n chrome.setAttribute('aria-hidden', 'true');\n if (placement === 'over') {\n chrome.textContent = spec?.label ?? 'ˆ';\n }\n\n const base = document.createElement('span');\n base.className = 'math-accent-base';\n if (node.baseExpr) {\n base.appendChild(buildChain(node.baseExpr));\n }\n\n if (placement === 'under') {\n wrap.appendChild(base);\n wrap.appendChild(chrome);\n } else {\n wrap.appendChild(chrome);\n wrap.appendChild(base);\n }\n return wrap;\n}\n","import type { EditorChain, EditorNode, EditorSide, MatrixEnvStyle } from '../types.js';\n\ntype BuildChain = (chain: EditorChain) => HTMLElement;\n\nconst WRAPPERS: Record<MatrixEnvStyle, { left: string; right: string }> = {\n matrix: { left: '', right: '' },\n pmatrix: { left: '(', right: ')' },\n bmatrix: { left: '[', right: ']' },\n Bmatrix: { left: '{', right: '}' },\n vmatrix: { left: '|', right: '|' },\n Vmatrix: { left: '||', right: '||' },\n};\n\nexport const MATRIX_ENV_CSS = `\n.matrix-env {\n display: inline-flex;\n align-items: stretch;\n vertical-align: middle;\n margin: 0 3px;\n --butex-matrix-delim-scale: 1.25;\n}\n\n.matrix-env__wrapper {\n display: inline-flex;\n align-self: stretch;\n align-items: center;\n justify-content: center;\n min-width: 0.42em;\n padding: 0 2px;\n color: var(--butex-delim-color, currentColor);\n font-family: ui-serif, \"Cambria Math\", \"Times New Roman\", serif;\n font-size: clamp(22px, 1.35em + 0.8vh, 42px);\n line-height: 1;\n transform: scaleY(var(--butex-matrix-delim-scale));\n transform-origin: center;\n}\n\n.matrix-env__grid {\n display: inline-grid;\n direction: ltr;\n gap: 2px 5px;\n align-items: center;\n justify-items: center;\n padding: 2px 3px;\n}\n\n.matrix-env__cell {\n min-width: 1.35em;\n min-height: 1.45em;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border-radius: 5px;\n border: 1px dashed rgba(148, 163, 184, 0.48);\n padding: 1px 3px;\n}\n\n.matrix-env__cell .chain {\n min-height: auto;\n}\n\n.matrix-env--arabic .matrix-env__cell {\n direction: rtl;\n}\n\n.matrix-env--english .matrix-env__cell {\n direction: ltr;\n}\n`.trim();\n\nconst MATRIX_DELIMITER_BASE_HEIGHT_PX = 20;\nconst MATRIX_DELIMITER_MAX_SCALE = 5.2;\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, value));\n}\n\nfunction applyMatrixDelimiterScale(wrap: HTMLElement, grid: HTMLElement): void {\n const gridHeight = Math.max(grid.getBoundingClientRect().height, MATRIX_DELIMITER_BASE_HEIGHT_PX);\n const scale = clamp((gridHeight / MATRIX_DELIMITER_BASE_HEIGHT_PX) * 1.22, 1.25, MATRIX_DELIMITER_MAX_SCALE);\n wrap.style.setProperty('--butex-matrix-delim-scale', scale.toFixed(3));\n}\n\nexport function buildMatrixEnvNodeBody(node: EditorNode, buildChain: BuildChain, side: EditorSide): HTMLElement {\n const wrap = document.createElement('span');\n wrap.className = `matrix-env matrix-env--${side}`;\n\n const style = node.envName ?? node.matrixStyle ?? 'matrix';\n const glyphs = style === 'array' || style === 'aligned' ? undefined : WRAPPERS[style];\n\n const left = document.createElement('span');\n left.className = 'matrix-env__wrapper matrix-env__wrapper--left';\n left.textContent = glyphs?.left ?? '';\n\n const grid = document.createElement('span');\n grid.className = 'matrix-env__grid';\n\n const rows = node.matrixRows ?? [];\n const columnCount = Math.max(1, ...rows.map((row) => row.length));\n grid.style.gridTemplateColumns = `repeat(${String(columnCount)}, minmax(1.35em, auto))`;\n\n const displayRows = side === 'arabic' ? rows.map((row) => row.slice().reverse()) : rows;\n for (const row of displayRows) {\n for (const cellChain of row) {\n const cell = document.createElement('span');\n cell.className = 'matrix-env__cell';\n cell.dir = side === 'arabic' ? 'rtl' : 'ltr';\n cell.appendChild(buildChain(cellChain));\n grid.appendChild(cell);\n }\n }\n\n const right = document.createElement('span');\n right.className = 'matrix-env__wrapper matrix-env__wrapper--right';\n right.textContent = glyphs?.right ?? '';\n\n wrap.appendChild(left);\n wrap.appendChild(grid);\n wrap.appendChild(right);\n\n applyMatrixDelimiterScale(wrap, grid);\n requestAnimationFrame(() => applyMatrixDelimiterScale(wrap, grid));\n\n return wrap;\n}\n","import diwaniLetterUrl from './fonts/Diwani Letter Regular.ttf';\nimport diwaniOutlineUrl from './fonts/DWNOUTSH.TTF';\nimport maghribiUrl from './fonts/Almaghribi-Warsh-Quran.otf';\nimport takweenUrl from './fonts/Takween.otf';\n\n\nexport const BUTEX_DIWANI_FONT_FAMILY = 'Diwani Letter';\nexport const BUTEX_DIWANI_OUTLINE_FONT_FAMILY = 'BuTeX Diwani Outline';\nexport const BUTEX_MAGHRIBI_FONT_FAMILY = 'Almaghribi Warsh Quran';\nexport const BUTEX_TAKWEEN_FONT_FAMILY = 'BuTeX Takween';\n\nexport const BUTEX_DIWANI_FONT_STACK = `\"${BUTEX_DIWANI_FONT_FAMILY}\", Amiri, \"Segoe UI\", Tahoma, sans-serif`;\nexport const BUTEX_DIWANI_OUTLINE_FONT_STACK = `\"${BUTEX_DIWANI_OUTLINE_FONT_FAMILY}\", \"${BUTEX_DIWANI_FONT_FAMILY}\", Amiri, \"Segoe UI\", Tahoma, sans-serif`;\nexport const BUTEX_MAGHRIBI_FONT_STACK = `\"${BUTEX_MAGHRIBI_FONT_FAMILY}\", Amiri, \"Segoe UI\", Tahoma, sans-serif`;\nexport const BUTEX_TAKWEEN_FONT_STACK = `\"${BUTEX_TAKWEEN_FONT_FAMILY}\", Amiri, \"Segoe UI\", Tahoma, sans-serif`;\n\nexport const BUTEX_DIWANI_FONT_FACE_CSS = `\n@font-face {\n font-family: \"${BUTEX_DIWANI_FONT_FAMILY}\";\n src: url(\"${diwaniLetterUrl}\") format(\"truetype\");\n font-weight: 400;\n font-style: normal;\n font-display: swap;\n}\n`.trim();\n\nexport const BUTEX_TAKWEEN_FONT_FACE_CSS = `\n@font-face {\n font-family: \"${BUTEX_TAKWEEN_FONT_FAMILY}\";\n src: url(\"${takweenUrl}\") format(\"opentype\");\n font-weight: 400;\n font-style: normal;\n font-display: swap;\n}\n`.trim();\n\nexport const BUTEX_DIWANI_OUTLINE_FONT_FACE_CSS = `\n@font-face {\n font-family: \"${BUTEX_DIWANI_OUTLINE_FONT_FAMILY}\";\n src: url(\"${diwaniOutlineUrl}\") format(\"truetype\");\n font-weight: 400;\n font-style: normal;\n font-display: swap;\n}\n`.trim();\n\nexport const BUTEX_MAGHRIBI_FONT_FACE_CSS = `\n@font-face {\n font-family: \"${BUTEX_MAGHRIBI_FONT_FAMILY}\";\n src: url(\"${maghribiUrl}\") format(\"opentype\");\n font-weight: 400;\n font-style: normal;\n font-display: swap;\n}\n`.trim();\n\nexport const BUTEX_FONT_FACE_CSS = `\n${BUTEX_DIWANI_FONT_FACE_CSS}\n\n${BUTEX_DIWANI_OUTLINE_FONT_FACE_CSS}\n\n${BUTEX_TAKWEEN_FONT_FACE_CSS}\n\n${BUTEX_MAGHRIBI_FONT_FACE_CSS}\n`.trim();\n","import { atomicCommandSpec, isSpacingCommandSpec, type AtomicCommandSpec, type SpacingCommandSpec } from '../atomicCommands.js';\nimport { BUTEX_DIWANI_FONT_STACK, BUTEX_DIWANI_OUTLINE_FONT_STACK } from '../../diwani-font.js';\nimport type { EditorNode, EditorSide } from '../types.js';\nimport type { ButexUiLocale } from '../../uiLocale.js';\nimport { atomicCommandTitle } from '../uiLocale.js';\n\nexport const ATOMIC_COMMAND_CSS = `\n/* Shared atomic-command display */\n.atomic-command {\n display: inline-flex;\n align-items: center;\n font-weight: 600;\n line-height: 1;\n}\n\n/* Function-style commands: sin/cos/tan families. */\n.atomic-command--arabic {\n font-family: ${BUTEX_DIWANI_FONT_STACK};\n font-size: 1.15em;\n direction: rtl;\n}\n\n.atomic-command--diwani-outline {\n font-family: ${BUTEX_DIWANI_OUTLINE_FONT_STACK};\n}\n\n.atomic-command--english {\n font-family: \"Cambria Math\", \"Times New Roman\", serif;\n font-size: 0.96em;\n}\n\n.atomic-command-label-with-sub {\n position: relative;\n display: inline-block;\n padding-inline-end: 0.45em;\n padding-block-end: 0.22em;\n line-height: 1;\n}\n\n.atomic-command-label-with-sub__sub {\n position: absolute;\n inset-inline-end: 0;\n inset-block-end: 0;\n font-size: 0.62em;\n line-height: 1;\n}\n\n/* Spacing commands: tiny selectable marker, real spacing remains in LaTeX preview. */\n.atomic-spacing {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 3px;\n min-width: 3px;\n height: 1em;\n color: var(--butex-accent, currentColor);\n opacity: 0.62;\n}\n\n.atomic-spacing__marker {\n display: inline-block;\n width: 3px;\n height: 0.85em;\n border-radius: 999px;\n background: currentColor;\n}\n\n.atomic-spacing--negative {\n color: var(--butex-danger, #dc2626);\n}\n`.trim();\n\nfunction spacingArrowForSide(spec: SpacingCommandSpec, side: EditorSide): string {\n const pointsWithFlow = spec.spacing.direction === 'positive';\n if (pointsWithFlow) {\n return side === 'arabic' ? '\\u2190' : '\\u2192';\n }\n return side === 'arabic' ? '\\u2192' : '\\u2190';\n}\n\nexport function spacingTooltipForSide(spec: SpacingCommandSpec, side: EditorSide, uiLocale: ButexUiLocale = 'ar'): string {\n return `${atomicCommandTitle(spec, uiLocale)} ${spacingArrowForSide(spec, side).repeat(spec.spacing.level)}`;\n}\n\nfunction buildFunctionAtomicCommandBody(node: EditorNode, side: EditorSide, spec: AtomicCommandSpec | null): HTMLElement {\n const value = document.createElement('span');\n value.className = `atomic-command atomic-command--${side}`;\n if (side === 'arabic' && spec?.category === 'groups') {\n value.classList.add('atomic-command--diwani-outline');\n }\n if (side === 'arabic' && node.expr === 'ln') {\n const label = document.createElement('span');\n label.className = 'atomic-command-label-with-sub';\n const base = document.createElement('span');\n base.className = 'atomic-command-label-with-sub__base';\n base.textContent = spec?.arabicLabel ?? node.expr;\n const sub = document.createElement('span');\n sub.className = 'atomic-command-label-with-sub__sub';\n sub.textContent = 'هـ';\n label.append(base, sub);\n value.appendChild(label);\n return value;\n }\n value.textContent = side === 'arabic'\n ? spec?.arabicLabel ?? node.expr\n : spec?.englishLabel ?? spec?.englishTex.replace(/^\\\\/, '') ?? node.expr;\n return value;\n}\n\nfunction buildSpacingAtomicCommandBody(spec: SpacingCommandSpec, side: EditorSide, uiLocale: ButexUiLocale): HTMLElement {\n const value = document.createElement('span');\n value.className = `atomic-spacing atomic-spacing--${spec.spacing.direction} atomic-spacing--level-${String(spec.spacing.level)}`;\n value.title = spacingTooltipForSide(spec, side, uiLocale);\n const marker = document.createElement('span');\n marker.className = 'atomic-spacing__marker';\n value.appendChild(marker);\n return value;\n}\n\nexport function buildAtomicCommandNodeBody(node: EditorNode, side: EditorSide, uiLocale: ButexUiLocale = 'ar'): HTMLElement {\n const spec = atomicCommandSpec(node.expr);\n if (isSpacingCommandSpec(spec)) {\n return buildSpacingAtomicCommandBody(spec, side, uiLocale);\n }\n return buildFunctionAtomicCommandBody(node, side, spec);\n}\n","import { atomicOperatorCommandSpec, shouldMirrorOperatorDisplay, type AtomicOperatorCommandSpec } from '../atomicCommandsOperators.js';\nimport type { EditorNode, EditorSide } from '../types.js';\nimport type { ButexUiLocale } from '../../uiLocale.js';\nimport { atomicOperatorCommandTitle } from '../uiLocale.js';\n\nexport const ATOMIC_OPERATOR_COMMAND_CSS = `\n.atomic-operator-command {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 0.9em;\n font-family: \"Cambria Math\", \"Times New Roman\", serif;\n font-size: 1.05em;\n font-weight: 600;\n line-height: 1;\n}\n\n.atomic-operator-command--mirrored {\n transform: scaleX(-1);\n}\n\n.atomic-operator-command__svg {\n width: 1em;\n height: 1em;\n background: currentColor;\n}\n`.trim();\n\nfunction buildOperatorLabel(spec: AtomicOperatorCommandSpec): HTMLElement {\n const value = document.createElement('span');\n value.className = 'atomic-operator-command__label';\n value.textContent = spec.Label;\n return value;\n}\n\nexport function buildAtomicOperatorCommandNodeBody(node: EditorNode, side: EditorSide, uiLocale: ButexUiLocale = 'ar'): HTMLElement {\n const spec = atomicOperatorCommandSpec(node.expr);\n const value = document.createElement('span');\n value.className = 'atomic-operator-command';\n value.title = spec ? atomicOperatorCommandTitle(spec, uiLocale) : node.expr;\n if (side === 'arabic' && shouldMirrorOperatorDisplay(spec)) {\n value.classList.add('atomic-operator-command--mirrored');\n }\n\n if (spec?.svg_path) {\n const icon = document.createElement('span');\n icon.className = 'atomic-operator-command__svg';\n icon.style.mask = `url(\"${spec.svg_path}\") center / contain no-repeat`;\n icon.style.webkitMask = `url(\"${spec.svg_path}\") center / contain no-repeat`;\n value.appendChild(icon);\n return value;\n }\n\n if (spec) {\n value.appendChild(buildOperatorLabel(spec));\n } else {\n const label = document.createElement('span');\n label.className = 'atomic-operator-command__label';\n label.textContent = node.expr;\n value.appendChild(label);\n }\n return value;\n}\n","import { DELIMITER_CSS } from './display/delimiter.js';\nimport { FRAC_CSS } from './display/frac.js';\nimport { SQRT_CSS } from './display/sqrt.js';\nimport { OVERSET_CSS } from './display/overset.js';\nimport { UNDERSET_CSS } from './display/underset.js';\nimport { ACCENT_CSS } from './display/accent.js';\nimport { MATRIX_ENV_CSS } from './display/env.js';\nimport { ATOMIC_COMMAND_CSS } from './display/atomicCommand.js';\nimport { ATOMIC_OPERATOR_COMMAND_CSS } from './display/atomicCommandsOperators.js';\nimport { BUTEX_FONT_FACE_CSS } from '../diwani-font.js';\nimport { NON_DEFAULT_CHARACTER_FONT_SPECS } from './characterFonts.js';\n\nconst CHARACTER_FONT_CSS = NON_DEFAULT_CHARACTER_FONT_SPECS\n .filter((font) => font.cssClass && font.browserFontStack)\n .map((font) => `.${font.cssClass} {\\n font-family: ${font.browserFontStack};\\n}`)\n .join('\\n\\n');\n\nexport const BUTEX_EDITOR_CSS = `\n${BUTEX_FONT_FACE_CSS}\n\n.surface {\n border: 1px solid var(--butex-border, #e2e8f0);\n border-radius: 12px;\n min-height: 100px;\n padding: 8px 10px;\n background: var(--butex-surface-bg, linear-gradient(180deg, #ffffff 0%, #fafbfc 100%));\n color: var(--butex-surface-fg, #0f172a);\n outline: none;\n cursor: text;\n transition: box-shadow 0.15s ease, border-color 0.15s ease;\n}\n\n.surface:focus,\n.surface.surface--typing-focus {\n border-color: var(--butex-focus-border, rgba(13, 148, 136, 0.45));\n box-shadow: 0 0 0 3px var(--butex-focus-shadow, rgba(13, 148, 136, 0.12));\n}\n\n.surface.surface--arabic {\n direction: rtl;\n}\n\n.surface.surface--english {\n direction: ltr;\n}\n\n${CHARACTER_FONT_CSS}\n\n.chain {\n display: inline-flex;\n align-items: center;\n gap: 0;\n min-height: 28px;\n flex-wrap: wrap;\n row-gap: 2px;\n}\n\n.slot {\n width: 5px;\n min-height: 28px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n border-radius: 3px;\n}\n\n.slot:hover {\n background: var(--butex-slot-hover, rgba(13, 148, 136, 0.08));\n}\n\n.slot.range-highlight {\n background: var(--butex-selection-bg, rgba(13, 148, 136, 0.34));\n width: 11px;\n min-height: 42px;\n border: 2px solid var(--butex-selection-border, rgba(15, 118, 110, 0.9));\n position: relative;\n z-index: 1;\n}\n\n.caret {\n display: inline-block;\n width: 2px;\n height: 20px;\n background: var(--butex-caret, #0f172a);\n border-radius: 1px;\n animation: butex-editor-blink 1s step-end infinite;\n}\n\n@keyframes butex-editor-blink {\n 50% { opacity: 0; }\n}\n\n.node {\n display: inline-flex;\n align-items: stretch;\n gap: 3px;\n border-radius: 8px;\n padding: 2px 4px;\n cursor: pointer;\n border: 1px solid transparent;\n user-select: none;\n}\n\n.node.node--atomic-spacing {\n padding-inline: 0;\n margin-inline: -2px;\n border-color: transparent;\n}\n\n.node:hover {\n border-color: var(--butex-border, #e2e8f0);\n background: var(--butex-node-hover, rgba(148, 163, 184, 0.08));\n}\n\n.node.selected {\n background: var(--butex-node-selected-bg, rgba(13, 148, 136, 0.14));\n border-color: var(--butex-node-selected-border, rgba(13, 148, 136, 0.45));\n}\n\n.node.range-highlight {\n background: var(--butex-selection-bg, rgba(13, 148, 136, 0.34));\n border-color: var(--butex-selection-border, rgba(15, 118, 110, 0.9));\n box-shadow: inset 0 0 0 3px var(--butex-selection-border, rgba(15, 118, 110, 0.9)),\n 0 0 0 1px var(--butex-selection-border, rgba(15, 118, 110, 0.9));\n position: relative;\n z-index: 2;\n}\n\n.chain .slot.range-highlight + .node.range-highlight,\n.chain .node.range-highlight + .slot.range-highlight {\n margin-inline: -1px;\n}\n\n.node-body {\n display: inline-flex;\n align-items: stretch;\n gap: 0;\n min-height: 1.6em;\n}\n\n.node-value {\n font-size: 16px;\n font-weight: 500;\n line-height: 1.25;\n display: inline-flex;\n align-items: center;\n}\n\n.scripts {\n display: flex;\n flex-direction: column;\n flex-shrink: 0;\n justify-content: space-between;\n align-items: center;\n padding: 1px 0;\n min-width: 0.75em;\n}\n\n.scripts.scripts--sup-only {\n justify-content: flex-start;\n padding-bottom: 2px;\n}\n\n.scripts.scripts--sub-only {\n justify-content: flex-end;\n padding-top: 2px;\n}\n\n.script-box {\n min-height: 12px;\n min-width: 10px;\n border-radius: 4px;\n border: 1px dashed var(--butex-script-border, #cbd5e1);\n padding: 0 2px;\n font-size: 0.68em;\n line-height: 1.15;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n background: var(--butex-script-bg, rgba(248, 250, 252, 0.95));\n color: var(--butex-script-color, #475569);\n}\n\n.script-box .chain {\n min-height: auto;\n}\n\n${DELIMITER_CSS}\n\n${FRAC_CSS}\n\n${SQRT_CSS}\n\n${OVERSET_CSS}\n\n${UNDERSET_CSS}\n\n${ACCENT_CSS}\n\n${MATRIX_ENV_CSS}\n\n${ATOMIC_COMMAND_CSS}\n\n${ATOMIC_OPERATOR_COMMAND_CSS}\n`.trim();\n\n/**\n * Injects BuTeX editor surface styles into `document.head` if not already present.\n * Browser-only; no-op if `document` is undefined (Node).\n */\nexport function injectBuTeXEditorStyles(doc?: Document): void {\n const d = doc ?? (typeof document !== 'undefined' ? document : undefined);\n if (!d) {\n return;\n }\n const id = 'butex-editor-styles';\n const existing = d.getElementById(id);\n if (existing) {\n existing.textContent = BUTEX_EDITOR_CSS;\n return;\n }\n const style = d.createElement('style');\n style.id = id;\n style.textContent = BUTEX_EDITOR_CSS;\n d.head.appendChild(style);\n}\n","import type { CharacterFontId } from '../editor/types.js';\nimport { NON_DEFAULT_CHARACTER_FONT_SPECS } from '../editor/characterFonts.js';\n\nexport type NormalizedCharImport = {\n expr: string;\n characterFont: CharacterFontId;\n};\n\ntype WrapperSpec = {\n prefix: string;\n font?: CharacterFontId;\n};\n\nconst WRAPPER_SPECS: WrapperSpec[] = [\n ...NON_DEFAULT_CHARACTER_FONT_SPECS.flatMap((font) => [\n { prefix: font.macro, font: font.id },\n ...(font.importAliases ?? []).map((alias) => ({ prefix: alias, font: font.id })),\n ]),\n { prefix: '\\\\text' },\n];\n\nfunction readBracedArg(source: string, openBraceIndex: number): { inner: string; end: number } | null {\n if (source[openBraceIndex] !== '{') {\n return null;\n }\n\n let depth = 0;\n for (let index = openBraceIndex; index < source.length; index += 1) {\n const char = source[index];\n if (char === '{') {\n depth += 1;\n } else if (char === '}') {\n depth -= 1;\n if (depth === 0) {\n return { inner: source.slice(openBraceIndex + 1, index), end: index + 1 };\n }\n }\n }\n\n return null;\n}\n\nfunction peelWrapper(source: string): { inner: string; font?: CharacterFontId } | null {\n for (const wrapper of WRAPPER_SPECS) {\n if (!source.startsWith(wrapper.prefix)) {\n continue;\n }\n\n const braced = readBracedArg(source, wrapper.prefix.length);\n if (!braced || braced.end !== source.length) {\n continue;\n }\n\n return { inner: braced.inner, font: wrapper.font };\n }\n\n return null;\n}\n\nexport function normalizeCharImportExpr(expr: string): NormalizedCharImport {\n const original = expr;\n let current = expr;\n let characterFont: CharacterFontId = 'default';\n let changed = false;\n\n while (true) {\n const peeled = peelWrapper(current);\n if (!peeled) {\n break;\n }\n\n current = peeled.inner;\n if (peeled.font) {\n characterFont = peeled.font;\n }\n changed = true;\n }\n\n if (!changed) {\n return { expr: original, characterFont: 'default' };\n }\n\n if (current.includes('\\\\')) {\n return { expr: original, characterFont: 'default' };\n }\n\n return { expr: current, characterFont };\n}\n","import {\n BaseAstNode,\n ChainNode,\n CharNode,\n CommandNode,\n DelimiterNode,\n EnvNode,\n NumberNode,\n OperatorNode,\n} from '../ast/arabic_ast.js';\nimport {\n accentCommandIdFromTex,\n accentCommandSpec,\n} from '../editor/accentCommands.js';\nimport {\n ATOMIC_COMMANDS,\n atomicCommandSpec,\n type AtomicCommandId,\n} from '../editor/atomicCommands.js';\nimport {\n ATOMIC_OPERATOR_COMMANDS,\n atomicOperatorCommandSpec,\n type AtomicOperatorCommandId,\n} from '../editor/atomicCommandsOperators.js';\nimport {\n buildInitialSyncMap,\n cloneEditorSession,\n createAccentNode,\n createDelimiterNode,\n createEditorChain,\n createEditorNode,\n createEditorSession,\n createFracNode,\n createGridEnvNode,\n createSqrtNode,\n createOversetNode,\n createUndersetNode,\n renderArabicLatexFromSession,\n} from '../editor/index.js';\nimport { NON_DEFAULT_CHARACTER_FONT_SPECS } from '../editor/characterFonts.js';\nimport type {\n CharacterFontId,\n EditorChain,\n EditorNode,\n EditorSession,\n EnvColumnAlignment,\n GridEnvName,\n MatrixEnvStyle,\n} from '../editor/index.js';\nimport { normalizeCharImportExpr } from './normalizeCharImport.js';\nimport type { MathNode } from './types.js';\n\ntype CommandFontPolicy = CharacterFontId | 'infer';\n\nconst COMMAND_FONT_MAP: Record<string, CommandFontPolicy> = Object.fromEntries([\n ['\\\\text', 'infer'],\n ...NON_DEFAULT_CHARACTER_FONT_SPECS.flatMap((font) => [\n [font.macro, font.id],\n ...(font.importAliases ?? []).map((alias) => [alias, font.id]),\n ]),\n]) as Record<string, CommandFontPolicy>;\n\nconst CHAR_FONT_EXPORT_TEX: Record<Exclude<CharacterFontId, 'default'>, string> = Object.fromEntries(\n NON_DEFAULT_CHARACTER_FONT_SPECS.map((font) => [font.id, font.macro]),\n) as Record<Exclude<CharacterFontId, 'default'>, string>;\n\nfunction charEditorNodeToAstNode(node: EditorNode): BaseAstNode {\n const font = node.characterFont ?? 'default';\n const charNode = new CharNode(node.expr);\n if (font === 'default') {\n return charNode;\n }\n return new CommandNode(CHAR_FONT_EXPORT_TEX[font], [], [new ChainNode([charNode])]);\n}\n\nexport type MathEditorAdapterResult =\n | { editable: true; session: EditorSession }\n | { editable: false; reason: string };\n\ntype NodeAdapterResult =\n | { editable: true; node: EditorNode }\n | { editable: false; reason: string };\n\ntype UnsupportedAdapterResult = { editable: false; reason: string };\n\nexport type MathNodeFromEditorResult =\n | { ok: true; math: MathNode }\n | { ok: false; reason: string };\n\nfunction commandIdForTex(tex: string): AtomicCommandId | null {\n for (const spec of Object.values(ATOMIC_COMMANDS)) {\n const renderTex = (spec as { arabicRenderTex?: string }).arabicRenderTex;\n if (spec.englishTex === tex || spec.arabicTex === tex || renderTex === tex) {\n return spec.id as AtomicCommandId;\n }\n }\n return null;\n}\n\nfunction operatorCommandIdForTex(tex: string): AtomicOperatorCommandId | null {\n for (const spec of Object.values(ATOMIC_OPERATOR_COMMANDS)) {\n if (spec.Tex === tex) {\n return spec.id as AtomicOperatorCommandId;\n }\n }\n return null;\n}\n\nfunction cloneChainWithFreshIds(chain: EditorChain): EditorChain {\n return structuredClone(chain);\n}\n\nfunction attachScripts(astNode: { superscript: ChainNode | null; subscript: ChainNode | null }, editorNode: EditorNode): UnsupportedAdapterResult | null {\n if (astNode.superscript) {\n const sup = chainToEditorChain(astNode.superscript);\n if (!sup.editable) {\n return sup;\n }\n editorNode.superscript = sup.chain;\n }\n if (astNode.subscript) {\n const sub = chainToEditorChain(astNode.subscript);\n if (!sub.editable) {\n return sub;\n }\n editorNode.subscript = sub.chain;\n }\n return null;\n}\n\ntype ChainAdapterResult =\n | { editable: true; chain: EditorChain }\n | { editable: false; reason: string };\n\nconst MATRIX_ENV_NAMES = new Set<GridEnvName>(['matrix', 'pmatrix', 'bmatrix', 'Bmatrix', 'vmatrix', 'Vmatrix']);\n\nfunction isGridEnvName(value: string): value is GridEnvName {\n return MATRIX_ENV_NAMES.has(value as GridEnvName) || value === 'array' || value === 'aligned';\n}\n\nfunction isMatrixEnvName(value: GridEnvName): value is MatrixEnvStyle {\n return MATRIX_ENV_NAMES.has(value);\n}\n\nfunction parseEnvOpening(opening: string): { envName: GridEnvName; alignments?: EnvColumnAlignment[] } | null {\n const match = /^\\\\begin\\{([^}]+)\\}(?:\\{([lcr]+)\\})?$/.exec(opening);\n if (!match) {\n return null;\n }\n\n const envName = match[1] ?? '';\n if (!isGridEnvName(envName)) {\n return null;\n }\n\n if (envName === 'array') {\n const spec = match[2] ?? 'c';\n return {\n envName,\n alignments: spec.split('').map((alignment) => alignment as EnvColumnAlignment),\n };\n }\n\n return { envName };\n}\n\nfunction splitEnvLine(line: ChainNode): ChainNode[] {\n const cells: ChainNode[] = [];\n let current: BaseAstNode[] = [];\n for (const node of line.chain) {\n if (node instanceof OperatorNode && node.expr === '&') {\n cells.push(new ChainNode(current));\n current = [];\n } else {\n current.push(node);\n }\n }\n cells.push(new ChainNode(current));\n return cells;\n}\n\nfunction envToEditorNode(node: EnvNode): NodeAdapterResult {\n const parsed = parseEnvOpening(node.opening);\n if (!parsed) {\n return { editable: false, reason: `بيئة رياضية غير مدعومة حاليا: ${node.opening}` };\n }\n\n const expectedClosing = `\\\\end{${parsed.envName}}`;\n if (node.closing !== expectedClosing) {\n return { editable: false, reason: `إغلاق بيئة رياضية غير مدعوم حاليا: ${node.closing}` };\n }\n\n const rowCells = node.lines.map(splitEnvLine);\n const rows = Math.max(1, rowCells.length);\n const columns = Math.max(1, ...rowCells.map((row) => row.length));\n const env = createGridEnvNode(parsed.envName, rows, columns, parsed.alignments);\n\n for (let rowIndex = 0; rowIndex < rows; rowIndex += 1) {\n const row = rowCells[rowIndex] ?? [];\n for (let columnIndex = 0; columnIndex < columns; columnIndex += 1) {\n const cell = chainToEditorChain(row[columnIndex] ?? new ChainNode());\n if (!cell.editable) {\n return cell;\n }\n env.matrixRows![rowIndex]![columnIndex] = cell.chain;\n }\n }\n\n if (parsed.envName === 'array') {\n env.columnAlignments = Array.from(\n { length: columns },\n (_, index) => parsed.alignments?.[index] ?? 'c',\n );\n }\n if (isMatrixEnvName(parsed.envName)) {\n env.matrixStyle = parsed.envName;\n }\n\n const scripts = attachScripts(node, env);\n return scripts ?? { editable: true, node: env };\n}\n\nfunction charFromTextLikeCommand(node: CommandNode): NodeAdapterResult | null {\n const commandFont = COMMAND_FONT_MAP[node.name];\n if (commandFont === undefined) {\n return null;\n }\n if (node.optionalArgs.length > 0 || node.mandatoryArgs.length !== 1) {\n return null;\n }\n\n const arg = node.mandatoryArgs[0]!;\n if (arg.chain.length !== 1) {\n return null;\n }\n\n const child = arg.chain[0]!;\n if (child instanceof CommandNode) {\n const nested = charFromTextLikeCommand(child);\n if (!nested?.editable) {\n return null;\n }\n if (commandFont !== 'infer') {\n nested.node.characterFont = commandFont;\n }\n const scripts = attachScripts(node, nested.node);\n return scripts ?? nested;\n }\n\n if (!(child instanceof CharNode)) {\n return null;\n }\n\n const normalized = normalizeCharImportExpr(child.expr);\n const characterFont = commandFont === 'infer' ? normalized.characterFont : commandFont;\n const editorNode = createEditorNode('char', normalized.expr);\n if (characterFont !== 'default') {\n editorNode.characterFont = characterFont;\n }\n const scripts = attachScripts(node, editorNode);\n return scripts ?? { editable: true, node: editorNode };\n}\n\nfunction commandToEditorNode(node: CommandNode): NodeAdapterResult {\n if (node.name === '\\\\frac' && node.mandatoryArgs.length >= 2) {\n const frac = createFracNode();\n const numerator = chainToEditorChain(node.mandatoryArgs[0]!);\n const denominator = chainToEditorChain(node.mandatoryArgs[1]!);\n if (!numerator.editable) {\n return numerator;\n }\n if (!denominator.editable) {\n return denominator;\n }\n frac.numerator = numerator.chain;\n frac.denominator = denominator.chain;\n const scripts = attachScripts(node, frac);\n if (scripts) {\n return scripts;\n }\n return { editable: true, node: frac };\n }\n\n if (\n (node.name === '\\\\sqrt' || node.name === '\\\\arabsqrt' || node.name === '\\\\arsqrt') &&\n node.mandatoryArgs.length >= 1\n ) {\n const sqrt = createSqrtNode();\n const radicand = chainToEditorChain(node.mandatoryArgs[0]!);\n if (!radicand.editable) {\n return radicand;\n }\n sqrt.radicand = radicand.chain;\n if (node.optionalArgs[0]) {\n const rootIndex = chainToEditorChain(node.optionalArgs[0]);\n if (!rootIndex.editable) {\n return rootIndex;\n }\n sqrt.rootIndex = rootIndex.chain;\n }\n const scripts = attachScripts(node, sqrt);\n if (scripts) {\n return scripts;\n }\n return { editable: true, node: sqrt };\n }\n\n if (node.name === '\\\\overset' && node.mandatoryArgs.length >= 2) {\n const overset = createOversetNode();\n const overExpr = chainToEditorChain(node.mandatoryArgs[0]!);\n const baseExpr = chainToEditorChain(node.mandatoryArgs[1]!);\n if (!overExpr.editable) {\n return overExpr;\n }\n if (!baseExpr.editable) {\n return baseExpr;\n }\n overset.overExpr = overExpr.chain;\n overset.baseExpr = baseExpr.chain;\n const scripts = attachScripts(node, overset);\n if (scripts) {\n return scripts;\n }\n return { editable: true, node: overset };\n }\n\n if (node.name === '\\\\underset' && node.mandatoryArgs.length >= 2) {\n const underset = createUndersetNode();\n const underExpr = chainToEditorChain(node.mandatoryArgs[0]!);\n const baseExpr = chainToEditorChain(node.mandatoryArgs[1]!);\n if (!underExpr.editable) {\n return underExpr;\n }\n if (!baseExpr.editable) {\n return baseExpr;\n }\n underset.underExpr = underExpr.chain;\n underset.baseExpr = baseExpr.chain;\n const scripts = attachScripts(node, underset);\n if (scripts) {\n return scripts;\n }\n return { editable: true, node: underset };\n }\n\n const accentId = accentCommandIdFromTex(node.name);\n if (accentId && node.mandatoryArgs.length >= 1) {\n const accent = createAccentNode(accentId);\n const baseExpr = chainToEditorChain(node.mandatoryArgs[0]!);\n if (!baseExpr.editable) {\n return baseExpr;\n }\n accent.baseExpr = baseExpr.chain;\n const scripts = attachScripts(node, accent);\n if (scripts) {\n return scripts;\n }\n return { editable: true, node: accent };\n }\n\n const atomicId = commandIdForTex(node.name);\n if (atomicId && node.optionalArgs.length === 0 && node.mandatoryArgs.length === 0) {\n const atomic = createEditorNode('atomicCommand', atomicId);\n const scripts = attachScripts(node, atomic);\n if (scripts) {\n return scripts;\n }\n return { editable: true, node: atomic };\n }\n\n const operatorId = operatorCommandIdForTex(node.name);\n if (operatorId && node.optionalArgs.length === 0 && node.mandatoryArgs.length === 0) {\n const atomicOperator = createEditorNode('atomicOperatorCommand', operatorId);\n const scripts = attachScripts(node, atomicOperator);\n if (scripts) {\n return scripts;\n }\n return { editable: true, node: atomicOperator };\n }\n\n const textLike = charFromTextLikeCommand(node);\n if (textLike) {\n return textLike;\n }\n\n return { editable: false, reason: `أمر رياضي غير مدعوم حاليا: ${node.name}` };\n}\n\nfunction astNodeToEditorNode(node: ChainNode['chain'][number]): NodeAdapterResult {\n if (node instanceof CharNode) {\n const normalized = normalizeCharImportExpr(node.expr);\n const editorNode = createEditorNode('char', normalized.expr);\n if (normalized.characterFont !== 'default') {\n editorNode.characterFont = normalized.characterFont;\n }\n const scripts = attachScripts(node, editorNode);\n return scripts ?? { editable: true, node: editorNode };\n }\n if (node instanceof NumberNode) {\n const editorNode = createEditorNode('number', node.expr);\n const scripts = attachScripts(node, editorNode);\n return scripts ?? { editable: true, node: editorNode };\n }\n if (node instanceof OperatorNode) {\n return { editable: true, node: createEditorNode('operator', node.expr) };\n }\n if (node instanceof DelimiterNode) {\n const editorNode = createDelimiterNode(node.leftDelimExpr, node.rightDelimExpr);\n const inner = chainToEditorChain(node.innerExpr);\n if (!inner.editable) {\n return inner;\n }\n editorNode.innerExpr = inner.chain;\n const scripts = attachScripts(node, editorNode);\n return scripts ?? { editable: true, node: editorNode };\n }\n if (node instanceof CommandNode) {\n return commandToEditorNode(node);\n }\n if (node instanceof EnvNode) {\n return envToEditorNode(node);\n }\n return { editable: false, reason: `عقدة رياضية غير مدعومة حاليا: ${node.nodeType}` };\n}\n\nfunction chainToEditorChain(chain: ChainNode): ChainAdapterResult {\n const nodes: EditorNode[] = [];\n for (const astNode of chain.chain) {\n const converted = astNodeToEditorNode(astNode);\n if (!converted.editable) {\n return converted;\n }\n nodes.push(converted.node);\n }\n return { editable: true, chain: createEditorChain(nodes) };\n}\n\nexport function mathObjectToEditorSession(math: MathNode): MathEditorAdapterResult {\n if (math.lines.length !== 1) {\n return { editable: false, reason: 'تحرير المعادلات متعددة الأسطر داخل المستند غير مدعوم بعد' };\n }\n\n const english = chainToEditorChain(math.lines[0]!);\n if (!english.editable) {\n return english;\n }\n\n const arabic = cloneChainWithFreshIds(english.chain);\n const session = createEditorSession(english.chain, arabic, 'english');\n session.sync = buildInitialSyncMap(session.englishTree, session.arabicTree);\n return { editable: true, session: cloneEditorSession(session) };\n}\n\ntype AstNodeResult =\n | { ok: true; node: BaseAstNode }\n | { ok: false; reason: string };\n\ntype AstChainResult =\n | { ok: true; chain: ChainNode }\n | { ok: false; reason: string };\n\nfunction attachAstScripts(editorNode: EditorNode, astNode: BaseAstNode): AstNodeResult | null {\n if (editorNode.superscript) {\n const sup = editorChainToAstChain(editorNode.superscript);\n if (!sup.ok) {\n return sup;\n }\n astNode.superscript = sup.chain;\n }\n if (editorNode.subscript) {\n const sub = editorChainToAstChain(editorNode.subscript);\n if (!sub.ok) {\n return sub;\n }\n astNode.subscript = sub.chain;\n }\n return null;\n}\n\nfunction editorEnvOpening(node: EditorNode): { opening: string; closing: string } | null {\n const envName = node.envName ?? node.matrixStyle;\n if (!envName) {\n return null;\n }\n if (envName === 'array') {\n const spec = (node.columnAlignments ?? []).slice(0, node.matrixRows?.[0]?.length ?? 0).join('') || 'c';\n return { opening: `\\\\begin{array}{${spec}}`, closing: '\\\\end{array}' };\n }\n return { opening: `\\\\begin{${envName}}`, closing: `\\\\end{${envName}}` };\n}\n\nfunction editorEnvToAstNode(node: EditorNode): AstNodeResult {\n const wrapper = editorEnvOpening(node);\n if (!wrapper || !node.matrixRows) {\n return { ok: false, reason: 'بيئة رياضية غير مدعومة حاليا' };\n }\n const lines: ChainNode[] = [];\n for (const row of node.matrixRows) {\n const lineNodes: BaseAstNode[] = [];\n for (let columnIndex = 0; columnIndex < row.length; columnIndex += 1) {\n if (columnIndex > 0) {\n lineNodes.push(new OperatorNode('&'));\n }\n const cell = editorChainToAstChain(row[columnIndex]!);\n if (!cell.ok) {\n return cell;\n }\n lineNodes.push(...cell.chain.chain);\n }\n lines.push(new ChainNode(lineNodes));\n }\n const env = new EnvNode(wrapper.opening, lines, wrapper.closing);\n const scripts = attachAstScripts(node, env);\n return scripts ?? { ok: true, node: env };\n}\n\nfunction accentChainForExport(accent: EditorChain | null): AstChainResult {\n if (!accent) {\n return { ok: true, chain: new ChainNode([]) };\n }\n return editorChainToAstChain(accent);\n}\n\n/** When accent is empty, unwrap to base (single node or invisible group). */\nfunction nodeFromAccentBase(\n command: '\\\\overset' | '\\\\underset',\n accent: ChainNode,\n base: ChainNode,\n): BaseAstNode {\n if (accent.chain.length > 0) {\n return new CommandNode(command, [], [accent, base]);\n }\n if (base.chain.length === 1) {\n return base.chain[0]!;\n }\n return new DelimiterNode('', base, '');\n}\n\nfunction editorNodeToAstNode(node: EditorNode): AstNodeResult {\n let astNode: BaseAstNode;\n\n if (node.kind === 'char') {\n astNode = charEditorNodeToAstNode(node);\n } else if (node.kind === 'number') {\n astNode = new NumberNode(node.expr);\n } else if (node.kind === 'operator') {\n astNode = new OperatorNode(node.expr);\n } else if (node.kind === 'delimiter' && node.innerExpr) {\n const inner = editorChainToAstChain(node.innerExpr);\n if (!inner.ok) {\n return inner;\n }\n astNode = new DelimiterNode(node.leftDelimExpr, inner.chain, node.rightDelimExpr);\n } else if (node.kind === 'frac' && node.numerator && node.denominator) {\n const numerator = editorChainToAstChain(node.numerator);\n const denominator = editorChainToAstChain(node.denominator);\n if (!numerator.ok) {\n return numerator;\n }\n if (!denominator.ok) {\n return denominator;\n }\n astNode = new CommandNode('\\\\frac', [], [numerator.chain, denominator.chain]);\n } else if (node.kind === 'sqrt' && node.radicand) {\n const radicand = editorChainToAstChain(node.radicand);\n if (!radicand.ok) {\n return radicand;\n }\n const optionalArgs: ChainNode[] = [];\n if (node.rootIndex && node.rootIndex.nodes.length > 0) {\n const rootIndex = editorChainToAstChain(node.rootIndex);\n if (!rootIndex.ok) {\n return rootIndex;\n }\n optionalArgs.push(rootIndex.chain);\n }\n astNode = new CommandNode('\\\\sqrt', optionalArgs, [radicand.chain]);\n } else if (node.kind === 'overset' && node.baseExpr) {\n const accent = accentChainForExport(node.overExpr);\n if (!accent.ok) {\n return accent;\n }\n const baseExpr = editorChainToAstChain(node.baseExpr);\n if (!baseExpr.ok) {\n return baseExpr;\n }\n astNode = nodeFromAccentBase('\\\\overset', accent.chain, baseExpr.chain);\n } else if (node.kind === 'underset' && node.baseExpr) {\n const accent = accentChainForExport(node.underExpr);\n if (!accent.ok) {\n return accent;\n }\n const baseExpr = editorChainToAstChain(node.baseExpr);\n if (!baseExpr.ok) {\n return baseExpr;\n }\n astNode = nodeFromAccentBase('\\\\underset', accent.chain, baseExpr.chain);\n } else if (node.kind === 'accent' && node.baseExpr) {\n const tex = accentCommandSpec(node.expr)?.englishTex;\n if (!tex) {\n return { ok: false, reason: `لكنة رياضية غير مدعومة حاليا: ${node.expr}` };\n }\n const baseExpr = editorChainToAstChain(node.baseExpr);\n if (!baseExpr.ok) {\n return baseExpr;\n }\n astNode = new CommandNode(tex, [], [baseExpr.chain]);\n } else if (node.kind === 'atomicCommand') {\n const tex = atomicCommandSpec(node.expr)?.englishTex;\n if (!tex) {\n return { ok: false, reason: `أمر رياضي غير مدعوم حاليا: ${node.expr}` };\n }\n astNode = new CommandNode(tex);\n } else if (node.kind === 'atomicOperatorCommand') {\n const tex = atomicOperatorCommandSpec(node.expr)?.Tex;\n if (!tex) {\n return { ok: false, reason: `رمز رياضي غير مدعوم حاليا: ${node.expr}` };\n }\n astNode = new CommandNode(tex);\n } else if (node.kind === 'env') {\n return editorEnvToAstNode(node);\n } else {\n return { ok: false, reason: `عقدة رياضية غير مدعومة حاليا: ${node.kind}` };\n }\n\n const scripts = attachAstScripts(node, astNode);\n return scripts ?? { ok: true, node: astNode };\n}\n\nfunction editorChainToAstChain(chain: EditorChain): AstChainResult {\n const nodes: BaseAstNode[] = [];\n for (const editorNode of chain.nodes) {\n const converted = editorNodeToAstNode(editorNode);\n if (!converted.ok) {\n return converted;\n }\n nodes.push(converted.node);\n }\n return { ok: true, chain: new ChainNode(nodes) };\n}\n\nexport function mathNodeFromEditorSession(\n session: EditorSession,\n mathMode = '$',\n closing = '$',\n): MathNodeFromEditorResult {\n const converted = editorChainToAstChain(session.englishTree);\n if (!converted.ok) {\n return converted;\n }\n return {\n ok: true,\n math: {\n nodeType: 'MathObject',\n mathMode,\n lines: [converted.chain],\n closing,\n },\n };\n}\n\n/** Delimited Arabic TeX for document text/preview — matches `<ButexEditor />` arabic output. */\nexport function mathSourceFromEditorSession(\n session: EditorSession,\n mathMode = '$',\n closing = '$',\n): string {\n const inner = renderArabicLatexFromSession(session);\n if (mathMode === '$' || mathMode === '\\\\(') {\n return mathMode + inner + closing;\n }\n if (mathMode === '$$' || mathMode === '\\\\[') {\n if (!inner.includes('\\n')) {\n return `${mathMode}\\n${inner}\\n${closing}`;\n }\n return `${mathMode}\\n${inner.split('\\n').map((line) => ` ${line}`).join(' \\\\\\\\\\n')}\\n${closing}`;\n }\n return `${mathMode}\\n ${inner}\\n${closing}`;\n}\n\nexport function mathSourceWithReplacement(source: string, replacementInnerLatex: string): string {\n if (source.startsWith('$$') && source.endsWith('$$')) {\n return `$$${replacementInnerLatex}$$`;\n }\n if (source.startsWith('$') && source.endsWith('$')) {\n return `$${replacementInnerLatex}$`;\n }\n if (source.startsWith('\\\\(') && source.endsWith('\\\\)')) {\n return `\\\\(${replacementInnerLatex}\\\\)`;\n }\n if (source.startsWith('\\\\[') && source.endsWith('\\\\]')) {\n return `\\\\[${replacementInnerLatex}\\\\]`;\n }\n const begin = /^\\\\begin\\{([A-Za-z*]+)\\}/.exec(source);\n if (begin) {\n const opening = begin[0] ?? '';\n const closing = `\\\\end{${begin[1] ?? ''}}`;\n if (source.endsWith(closing)) {\n return `${opening}${replacementInnerLatex}${closing}`;\n }\n }\n return replacementInnerLatex;\n}\n","import { mathNodeFromEditorSession, mathObjectToEditorSession } from '../document/mathEditorAdapter.js';\nimport type { MathNode } from '../document/types.js';\nimport {\n buildInitialSyncMap,\n createEditorChain,\n createEditorSession,\n renderArabicLatexFromSession,\n renderEnglishLatexFromSession,\n setCurrentDigitForm,\n type DigitFormId,\n type EditorSide,\n type EditorSession,\n} from '../editor/index.js';\nimport type { MathToken2 } from './types.js';\n\nexport type Document2MathBridgeResult =\n | { editable: true; session: EditorSession }\n | { editable: false; reason: string };\n\nexport function createEmptyEquationSession(side: EditorSide = 'arabic'): EditorSession {\n const english = createEditorChain();\n const arabic = createEditorChain();\n arabic.id = english.id;\n const session = createEditorSession(english, arabic, side);\n session.sync = buildInitialSyncMap(session.englishTree, session.arabicTree);\n return session;\n}\n\nexport function createEmptyArabicEquationSession(): EditorSession {\n return createEmptyEquationSession('arabic');\n}\n\nexport function mathTokenToEditorSession(math: MathNode | null, side: EditorSide = 'arabic'): Document2MathBridgeResult {\n if (!math) {\n return { editable: false, reason: 'هذه المعادلة محفوظة كنص خام فقط حاليا' };\n }\n const result = mathObjectToEditorSession(math);\n if (!result.editable) {\n return result;\n }\n result.session.activeSide = side;\n result.session.sync = buildInitialSyncMap(result.session.englishTree, result.session.arabicTree);\n return result;\n}\n\nexport function mathTokenToArabicEditorSession(math: MathNode | null): Document2MathBridgeResult {\n return mathTokenToEditorSession(math, 'arabic');\n}\n\nexport function mathSourceFromSession(\n session: EditorSession,\n side: EditorSide,\n opening = '$',\n closing = '$',\n): string {\n const inner = side === 'english'\n ? renderEnglishLatexFromSession(session)\n : renderArabicLatexFromSession(session);\n if (opening === '$' || opening === '\\\\(') {\n return opening + inner + closing;\n }\n if (opening === '$$' || opening === '\\\\[') {\n return `${opening}\\n${inner}\\n${closing}`;\n }\n return `${opening}\\n ${inner}\\n${closing}`;\n}\n\nexport function mathSourceFromArabicSession(session: EditorSession, opening = '$', closing = '$'): string {\n return mathSourceFromSession(session, 'arabic', opening, closing);\n}\n\nexport function mathNodeFromSession(session: EditorSession, opening = '$', closing = '$'): MathNode {\n const converted = mathNodeFromEditorSession(session, opening, closing);\n if (converted.ok) {\n return converted.math;\n }\n return { nodeType: 'MathObject', mathMode: opening, lines: [], closing };\n}\n\nexport function mathNodeFromArabicSession(session: EditorSession, opening = '$', closing = '$'): MathNode {\n return mathNodeFromSession(session, opening, closing);\n}\n\nexport function mathTokenSourceForSide(token: MathToken2, side: EditorSide, digitForm?: DigitFormId): string {\n if (!token.math || token.sourceOwner === 'raw') {\n return token.source;\n }\n if (token.sourceSide === side && digitForm === undefined) {\n return token.source;\n }\n const result = mathTokenToEditorSession(token.math, side);\n if (!result.editable) {\n return token.source;\n }\n const session = digitForm === undefined\n ? result.session\n : setCurrentDigitForm(result.session, digitForm);\n return mathSourceFromSession(session, side, token.opening, token.closing);\n}\n","import { document2Id } from './ids.js';\nimport { cloneDocument2Meta, emptyDocument2Meta, normalizeDocument2HijriDate } from './articleMeta.js';\nimport { createEmptyReference2 } from './citations.js';\nimport { createInlineField2 } from './importJson.js';\nimport { applyFloatMetaPatch, defaultFloatMeta, type FloatMetaPatch } from './labels.js';\nimport { mathNodeFromSession, mathSourceFromSession } from './mathBridge.js';\nimport type {\n BibliographyBlock2,\n CiteToken2,\n Document2Block,\n Document2Node,\n ImageBlock2,\n InlineField2,\n InlineToken2,\n ListBlock2,\n MathToken2,\n Reference2,\n Reference2Json,\n RefToken2,\n TableBlock2,\n TextStyle2,\n TextToken2,\n} from './types.js';\nimport type { Document2MetaProp } from './articleMeta.js';\nimport type { EditorSession, EditorSide } from '../editor/index.js';\n\nfunction cloneToken(token: InlineToken2): InlineToken2 {\n return token.kind === 'text' ? { ...token } : { ...token };\n}\n\nfunction cloneField(field: InlineField2): InlineField2 {\n return { id: field.id, tokens: field.tokens.map(cloneToken) };\n}\n\nfunction cloneBlock(block: Document2Block): Document2Block {\n if (block.kind === 'textBlock') {\n return { ...block, field: cloneField(block.field) };\n }\n if (block.kind === 'list') {\n return {\n ...block,\n items: block.items.map((item) => ({\n ...item,\n field: cloneField(item.field),\n blocks: item.blocks.map(cloneBlock),\n })),\n };\n }\n if (block.kind === 'table') {\n return { ...block, rows: block.rows.map((row) => row.map(cloneField)) };\n }\n if (block.kind === 'image') {\n return { ...block, options: { ...block.options } };\n }\n return { ...block };\n}\n\nfunction cloneDocument(document: Document2Node): Document2Node {\n return {\n nodeType: 'DocumentObject',\n meta: cloneDocument2Meta(document.meta ?? emptyDocument2Meta()),\n references: document.references.map((reference) => ({ ...reference })),\n blocks: document.blocks.map(cloneBlock),\n diagnostics: document.diagnostics.map((diagnostic) => ({ ...diagnostic })),\n };\n}\n\nfunction visitFields(blocks: Document2Block[], visitor: (field: InlineField2) => boolean): boolean {\n for (const block of blocks) {\n if (block.kind === 'textBlock') {\n if (visitor(block.field)) {\n return true;\n }\n } else if (block.kind === 'list') {\n for (const item of block.items) {\n if (visitor(item.field) || visitFields(item.blocks, visitor)) {\n return true;\n }\n }\n } else if (block.kind === 'table') {\n for (const row of block.rows) {\n for (const cell of row) {\n if (visitor(cell)) {\n return true;\n }\n }\n }\n }\n }\n return false;\n}\n\nexport function findFirstInlineField(document: Document2Node): InlineField2 | null {\n let found: InlineField2 | null = null;\n visitFields(document.blocks, (field) => {\n found = field;\n return true;\n });\n return found;\n}\n\nexport function updateTextToken(document: Document2Node, fieldId: string, tokenId: string, text: string): Document2Node {\n const next = cloneDocument(document);\n visitFields(next.blocks, (field) => {\n if (field.id !== fieldId) {\n return false;\n }\n const token = field.tokens.find((entry): entry is TextToken2 => entry.id === tokenId && entry.kind === 'text');\n if (!token) {\n return true;\n }\n token.text = text;\n return true;\n });\n return next;\n}\n\nfunction mathTokenFromSession(session: EditorSession, opening = '$', closing = '$', side: EditorSide = 'arabic'): MathToken2 {\n return {\n id: document2Id('math'),\n kind: 'math',\n display: opening === '$$' || opening === '\\\\[' || opening.startsWith('\\\\begin{'),\n opening,\n closing,\n source: mathSourceFromSession(session, side, opening, closing),\n sourceSide: side,\n math: mathNodeFromSession(session, opening, closing),\n editable: true,\n sourceOwner: 'editor',\n };\n}\n\nfunction splitTextForInsertion(token: TextToken2): InlineToken2[] | null {\n const gap = token.text.indexOf(' ');\n if (gap < 0) {\n return null;\n }\n return [\n { id: token.id, kind: 'text', text: token.text.slice(0, gap + 1) },\n { id: document2Id('text'), kind: 'text', text: token.text.slice(gap + 1) },\n ];\n}\n\nexport function cloneDocument2Node(document: Document2Node): Document2Node {\n return cloneDocument(document);\n}\n\nfunction insertBlockAfter(blocks: Document2Block[], afterBlockId: string | null | undefined, block: Document2Block): void {\n if (!afterBlockId) {\n blocks.push(block);\n return;\n }\n const index = blocks.findIndex((entry) => entry.id === afterBlockId);\n if (index < 0) {\n blocks.push(block);\n return;\n }\n blocks.splice(index + 1, 0, block);\n}\n\nexport function insertDocument2BlockAfter(\n document: Document2Node,\n afterBlockId: string | null | undefined,\n block: Document2Block,\n): Document2Node {\n const next = cloneDocument(document);\n insertBlockAfter(next.blocks, afterBlockId, block);\n return next;\n}\n\nexport function moveDocument2BlockById(document: Document2Node, blockId: string, direction: -1 | 1): Document2Node {\n const next = cloneDocument(document);\n const index = next.blocks.findIndex((block) => block.id === blockId);\n const targetIndex = index + direction;\n if (index < 0 || targetIndex < 0 || targetIndex >= next.blocks.length) {\n return document;\n }\n const [block] = next.blocks.splice(index, 1);\n if (!block) {\n return document;\n }\n next.blocks.splice(targetIndex, 0, block);\n return next;\n}\n\nexport function moveDocument2BlockRange(\n document: Document2Node,\n from: number,\n to: number,\n direction: -1 | 1,\n): Document2Node {\n const count = document.blocks.length;\n if (from < 0 || to < 0 || from >= count || to >= count || from > to) {\n return document;\n }\n const insertAt = from + direction;\n if (insertAt < 0 || to + direction >= count) {\n return document;\n }\n const next = cloneDocument(document);\n const slice = next.blocks.splice(from, to - from + 1);\n next.blocks.splice(insertAt, 0, ...slice);\n return next;\n}\n\nexport function removeDocument2BlockRange(document: Document2Node, from: number, to: number): Document2Node {\n const count = document.blocks.length;\n if (from < 0 || to < 0 || from >= count || to >= count || from > to) {\n return document;\n }\n const next = cloneDocument(document);\n next.blocks = [...next.blocks.slice(0, from), ...next.blocks.slice(to + 1)];\n return next;\n}\n\nfunction normalizeFieldTokens(tokens: InlineToken2[]): InlineToken2[] {\n if (tokens.length === 0) {\n return [{ id: document2Id('text'), kind: 'text', text: '' }];\n }\n return tokens;\n}\n\nfunction textStylesEqual(a: TextStyle2 | undefined, b: TextStyle2 | undefined): boolean {\n return Boolean(a?.bold) === Boolean(b?.bold) && Boolean(a?.italic) === Boolean(b?.italic) && Boolean(a?.underline) === Boolean(b?.underline);\n}\n\nfunction compactAdjacentTextTokens(tokens: InlineToken2[]): InlineToken2[] {\n const compacted: InlineToken2[] = [];\n for (const token of tokens) {\n const previous = compacted[compacted.length - 1];\n if (previous?.kind === 'text' && token.kind === 'text' && textStylesEqual(previous.style, token.style)) {\n previous.text += token.text;\n } else {\n compacted.push(token);\n }\n }\n return normalizeFieldTokens(compacted);\n}\n\nfunction withoutEmptyStyle(style: TextStyle2): TextStyle2 | undefined {\n const next: TextStyle2 = {};\n if (style.bold) {\n next.bold = true;\n }\n if (style.italic) {\n next.italic = true;\n }\n if (style.underline) {\n next.underline = true;\n }\n return next.bold || next.italic || next.underline ? next : undefined;\n}\n\nfunction textTokenPart(text: string, style: TextStyle2 | undefined, id = document2Id('text')): TextToken2 {\n return { id, kind: 'text', text, ...(style ? { style } : {}) };\n}\n\nexport function toggleTextTokenStyle(\n document: Document2Node,\n fieldId: string,\n tokenId: string,\n selectionStart: number,\n selectionEnd: number,\n styleName: keyof TextStyle2,\n): Document2Node {\n if (selectionEnd <= selectionStart) {\n return document;\n }\n const next = cloneDocument(document);\n visitFields(next.blocks, (field) => {\n if (field.id !== fieldId) {\n return false;\n }\n const tokenIndex = field.tokens.findIndex((entry) => entry.id === tokenId && entry.kind === 'text');\n if (tokenIndex < 0) {\n return true;\n }\n const token = field.tokens[tokenIndex] as TextToken2;\n const start = Math.max(0, Math.min(token.text.length, selectionStart));\n const end = Math.max(0, Math.min(token.text.length, selectionEnd));\n if (end <= start) {\n return true;\n }\n const selectedStyle = token.style ?? {};\n const enabled = selectedStyle[styleName] === true;\n const nextStyle = withoutEmptyStyle({ ...selectedStyle, [styleName]: enabled ? undefined : true });\n const parts: InlineToken2[] = [];\n const before = token.text.slice(0, start);\n const selected = token.text.slice(start, end);\n const after = token.text.slice(end);\n if (before.length > 0) {\n parts.push(textTokenPart(before, token.style, token.id));\n }\n parts.push(textTokenPart(selected, nextStyle, before.length > 0 ? document2Id('text') : token.id));\n if (after.length > 0) {\n parts.push(textTokenPart(after, token.style));\n }\n field.tokens = compactAdjacentTextTokens([\n ...field.tokens.slice(0, tokenIndex),\n ...parts,\n ...field.tokens.slice(tokenIndex + 1),\n ]);\n return true;\n });\n return next;\n}\n\nfunction stitchTextAroundRemovedToken(tokens: InlineToken2[], index: number): InlineToken2[] {\n const before = tokens[index - 1];\n const after = tokens[index + 1];\n if (before?.kind === 'text' && after?.kind === 'text') {\n return [\n ...tokens.slice(0, index - 1),\n { ...before, text: before.text + after.text },\n ...tokens.slice(index + 2),\n ];\n }\n return [...tokens.slice(0, index), ...tokens.slice(index + 1)];\n}\n\nexport function removeMathTokenById(document: Document2Node, tokenId: string): Document2Node {\n const next = cloneDocument(document);\n visitFields(next.blocks, (field) => {\n const index = field.tokens.findIndex((token) => token.id === tokenId && token.kind === 'math');\n if (index < 0) {\n return false;\n }\n field.tokens = normalizeFieldTokens(stitchTextAroundRemovedToken(field.tokens, index));\n return true;\n });\n return next;\n}\n\nfunction splitTextTokenAt(token: TextToken2, offset: number): [TextToken2, TextToken2] {\n const safeOffset = Math.max(0, Math.min(offset, token.text.length));\n return [\n { id: token.id, kind: 'text', text: token.text.slice(0, safeOffset), ...(token.style ? { style: token.style } : {}) },\n { id: document2Id('text'), kind: 'text', text: token.text.slice(safeOffset), ...(token.style ? { style: token.style } : {}) },\n ];\n}\n\nexport function insertMathTokenAtCaret(\n document: Document2Node,\n fieldId: string,\n textTokenId: string | null,\n caretOffset: number,\n session: EditorSession,\n opening = '$',\n closing = '$',\n side: EditorSide = 'arabic',\n): Document2Node {\n const next = cloneDocument(document);\n const mathToken = mathTokenFromSession(session, opening, closing, side);\n visitFields(next.blocks, (field) => {\n if (field.id !== fieldId) {\n return false;\n }\n\n const textIndex = textTokenId\n ? field.tokens.findIndex((token) => token.id === textTokenId && token.kind === 'text')\n : field.tokens.findIndex((token) => token.kind === 'text');\n\n if (textIndex < 0) {\n field.tokens.push(mathToken);\n field.tokens.push({ id: document2Id('text'), kind: 'text', text: '' });\n return true;\n }\n\n const current = field.tokens[textIndex] as TextToken2;\n const [before, after] = splitTextTokenAt(current, caretOffset);\n const parts: InlineToken2[] = [...field.tokens.slice(0, textIndex)];\n if (before.text.length > 0) {\n parts.push(before);\n }\n parts.push(mathToken);\n parts.push(after);\n parts.push(...field.tokens.slice(textIndex + 1));\n field.tokens = normalizeFieldTokens(parts);\n return true;\n });\n return next;\n}\n\nexport function insertMathToken(\n document: Document2Node,\n fieldId: string,\n insertIndex: number,\n session: EditorSession,\n opening = '$',\n closing = '$',\n side: EditorSide = 'arabic',\n): Document2Node {\n const next = cloneDocument(document);\n const mathToken = mathTokenFromSession(session, opening, closing, side);\n visitFields(next.blocks, (field) => {\n if (field.id !== fieldId) {\n return false;\n }\n\n if (field.tokens.length === 1 && field.tokens[0]?.kind === 'text') {\n const split = splitTextForInsertion(field.tokens[0]);\n if (split) {\n field.tokens = [split[0]!, mathToken, split[1]!];\n return true;\n }\n }\n\n const safeIndex = Math.max(0, Math.min(insertIndex, field.tokens.length));\n field.tokens.splice(safeIndex, 0, mathToken);\n return true;\n });\n return next;\n}\n\nexport function replaceMathTokenFromSession(\n document: Document2Node,\n tokenId: string,\n session: EditorSession,\n opening?: string,\n closing?: string,\n side: EditorSide = 'arabic',\n): Document2Node {\n const next = cloneDocument(document);\n visitFields(next.blocks, (field) => {\n const index = field.tokens.findIndex((token) => token.id === tokenId && token.kind === 'math');\n if (index < 0) {\n return false;\n }\n const current = field.tokens[index] as MathToken2;\n const open = opening ?? current.opening;\n const close = closing ?? current.closing;\n const replaced = mathTokenFromSession(session, open, close, side);\n replaced.id = current.id;\n if (current.labelEnabled !== undefined) {\n replaced.labelEnabled = current.labelEnabled;\n }\n if (current.label !== undefined) {\n replaced.label = current.label;\n }\n field.tokens[index] = replaced;\n return true;\n });\n return next;\n}\n\nexport function addDocument2TextBlock(\n document: Document2Node,\n command: '\\\\section' | '\\\\subsection' | '\\\\subsubsection' | '\\\\paragraph' = '\\\\paragraph',\n afterBlockId?: string | null,\n): Document2Node {\n const block = {\n id: document2Id('block'),\n kind: 'textBlock' as const,\n command,\n field: createInlineField2(''),\n ...(command === '\\\\paragraph' ? { centered: false } : {}),\n };\n return insertDocument2BlockAfter(document, afterBlockId, block);\n}\n\nexport function updateDocument2TextBlockCentered(\n document: Document2Node,\n blockId: string,\n centered: boolean,\n): Document2Node {\n const next = cloneDocument(document);\n function visit(blocks: Document2Block[]): boolean {\n for (const block of blocks) {\n if (block.id === blockId && block.kind === 'textBlock' && block.command === '\\\\paragraph') {\n block.centered = centered;\n return true;\n }\n if (block.kind === 'list') {\n for (const item of block.items) {\n if (visit(item.blocks)) {\n return true;\n }\n }\n }\n }\n return false;\n }\n visit(next.blocks);\n return next;\n}\n\nexport function removeDocument2BlockById(document: Document2Node, blockId: string): Document2Node {\n const next = cloneDocument(document);\n next.blocks = next.blocks.filter((block) => block.id !== blockId);\n return next;\n}\n\nfunction newListBlock(ordered: boolean): ListBlock2 {\n const command: ListBlock2['command'] = ordered ? '\\\\begin{enumerate}' : '\\\\begin{itemize}';\n const closing = ordered ? '\\\\end{enumerate}' : '\\\\end{itemize}';\n return {\n id: document2Id('block'),\n kind: 'list',\n command,\n closing,\n items: [{ id: document2Id('item'), field: createInlineField2(''), blocks: [] }],\n };\n}\n\nexport function addDocument2ListBlock(document: Document2Node, ordered: boolean, afterBlockId?: string | null): Document2Node {\n return insertDocument2BlockAfter(document, afterBlockId, newListBlock(ordered));\n}\n\nexport function addDocument2TableBlock(\n document: Document2Node,\n columns = 'lll',\n rowCount = 3,\n colCount = 3,\n afterBlockId?: string | null,\n): Document2Node {\n const rows = Math.max(1, rowCount);\n const cols = Math.max(1, colCount);\n const tableRows: InlineField2[][] = [];\n for (let r = 0; r < rows; r += 1) {\n const row: InlineField2[] = [];\n for (let c = 0; c < cols; c += 1) {\n row.push(createInlineField2(''));\n }\n tableRows.push(row);\n }\n const block: TableBlock2 = {\n id: document2Id('block'),\n kind: 'table',\n command: '\\\\begin{tabular}',\n closing: '\\\\end{tabular}',\n columns: columns || 'l'.repeat(cols),\n rows: tableRows,\n ...defaultFloatMeta(),\n };\n return insertDocument2BlockAfter(document, afterBlockId, block);\n}\n\nexport function addDocument2ImageBlock(document: Document2Node, src = '', afterBlockId?: string | null): Document2Node {\n const block: ImageBlock2 = {\n id: document2Id('block'),\n kind: 'image',\n command: '\\\\includegraphics',\n value: src,\n options: { width: '0.8\\\\columnwidth' },\n ...defaultFloatMeta(),\n };\n return insertDocument2BlockAfter(document, afterBlockId, block);\n}\n\nexport function updateDocument2ImageValue(document: Document2Node, blockId: string, value: string): Document2Node {\n const next = cloneDocument(document);\n function visit(blocks: Document2Block[]): boolean {\n for (const block of blocks) {\n if (block.id === blockId && block.kind === 'image') {\n block.value = value;\n return true;\n }\n if (block.kind === 'list') {\n for (const item of block.items) {\n if (visit(item.blocks)) {\n return true;\n }\n }\n }\n }\n return false;\n }\n visit(next.blocks);\n return next;\n}\n\nexport function updateDocument2ImageMeta(document: Document2Node, blockId: string, patch: FloatMetaPatch): Document2Node {\n const next = cloneDocument(document);\n function visit(blocks: Document2Block[]): boolean {\n for (const block of blocks) {\n if (block.id === blockId && block.kind === 'image') {\n applyFloatMetaPatch(block, patch);\n return true;\n }\n if (block.kind === 'list') {\n for (const item of block.items) {\n if (visit(item.blocks)) {\n return true;\n }\n }\n }\n }\n return false;\n }\n visit(next.blocks);\n return next;\n}\n\nexport function updateDocument2TableMeta(document: Document2Node, blockId: string, patch: FloatMetaPatch): Document2Node {\n const next = cloneDocument(document);\n function visit(blocks: Document2Block[]): boolean {\n for (const block of blocks) {\n if (block.id === blockId && block.kind === 'table') {\n applyFloatMetaPatch(block, patch);\n return true;\n }\n if (block.kind === 'list') {\n for (const item of block.items) {\n if (visit(item.blocks)) {\n return true;\n }\n }\n }\n }\n return false;\n }\n visit(next.blocks);\n return next;\n}\n\nexport function updateMathTokenLabel(\n document: Document2Node,\n tokenId: string,\n patch: { labelEnabled?: boolean; label?: string },\n): Document2Node {\n const next = cloneDocument(document);\n visitFields(next.blocks, (field) => {\n const token = field.tokens.find((entry): entry is MathToken2 => entry.id === tokenId && entry.kind === 'math');\n if (!token) {\n return false;\n }\n if (typeof patch.labelEnabled === 'boolean') {\n token.labelEnabled = patch.labelEnabled;\n }\n if (typeof patch.label === 'string') {\n token.label = patch.label;\n }\n return true;\n });\n return next;\n}\n\nfunction refTokenFromKeys(keys: string[], refCommand: 'ref' | 'eqref'): RefToken2 {\n return { id: document2Id('ref'), kind: 'ref', keys: [...keys], refCommand };\n}\n\nexport function insertRefTokenAtCaret(\n document: Document2Node,\n fieldId: string,\n textTokenId: string | null,\n caretOffset: number,\n keys: string[],\n refCommand: 'ref' | 'eqref' = 'ref',\n): Document2Node {\n if (keys.length === 0) {\n return document;\n }\n const next = cloneDocument(document);\n const refToken = refTokenFromKeys(keys, refCommand);\n visitFields(next.blocks, (field) => {\n if (field.id !== fieldId) {\n return false;\n }\n\n const textIndex = textTokenId\n ? field.tokens.findIndex((token) => token.id === textTokenId && token.kind === 'text')\n : field.tokens.findIndex((token) => token.kind === 'text');\n\n if (textIndex < 0) {\n field.tokens.push(refToken);\n field.tokens.push({ id: document2Id('text'), kind: 'text', text: '' });\n return true;\n }\n\n const current = field.tokens[textIndex] as TextToken2;\n const [before, after] = splitTextTokenAt(current, caretOffset);\n const parts: InlineToken2[] = [...field.tokens.slice(0, textIndex)];\n if (before.text.length > 0) {\n parts.push(before);\n }\n parts.push(refToken);\n parts.push(after);\n parts.push(...field.tokens.slice(textIndex + 1));\n field.tokens = normalizeFieldTokens(parts);\n return true;\n });\n return next;\n}\n\nexport function updateRefTokenKeys(\n document: Document2Node,\n tokenId: string,\n keys: string[],\n refCommand?: 'ref' | 'eqref',\n): Document2Node {\n if (keys.length === 0) {\n return document;\n }\n const next = cloneDocument(document);\n visitFields(next.blocks, (field) => {\n const token = field.tokens.find((entry): entry is RefToken2 => entry.id === tokenId && entry.kind === 'ref');\n if (!token) {\n return false;\n }\n token.keys = [...keys];\n if (refCommand) {\n token.refCommand = refCommand;\n }\n return true;\n });\n return next;\n}\n\nexport function removeRefTokenById(document: Document2Node, tokenId: string): Document2Node {\n const next = cloneDocument(document);\n visitFields(next.blocks, (field) => {\n const index = field.tokens.findIndex((token) => token.id === tokenId && token.kind === 'ref');\n if (index < 0) {\n return false;\n }\n field.tokens = normalizeFieldTokens(stitchTextAroundRemovedToken(field.tokens, index));\n return true;\n });\n return next;\n}\n\nfunction mutateListBlockById(blocks: Document2Block[], listBlockId: string, mutator: (list: ListBlock2) => void): boolean {\n for (const block of blocks) {\n if (block.id === listBlockId && block.kind === 'list') {\n mutator(block);\n return true;\n }\n if (block.kind === 'list') {\n for (const item of block.items) {\n if (mutateListBlockById(item.blocks, listBlockId, mutator)) {\n return true;\n }\n }\n }\n }\n return false;\n}\n\nexport function addDocument2ListItem(document: Document2Node, listBlockId: string): Document2Node {\n const next = cloneDocument(document);\n mutateListBlockById(next.blocks, listBlockId, (list) => {\n list.items.push({ id: document2Id('item'), field: createInlineField2(''), blocks: [] });\n });\n return next;\n}\n\nexport function removeDocument2ListItem(document: Document2Node, listBlockId: string, itemId: string): Document2Node {\n const next = cloneDocument(document);\n mutateListBlockById(next.blocks, listBlockId, (list) => {\n if (list.items.length < 2) {\n return;\n }\n const index = list.items.findIndex((item) => item.id === itemId);\n if (index >= 0) {\n list.items.splice(index, 1);\n }\n });\n return next;\n}\n\nfunction citeTokenFromKeys(keys: string[]): CiteToken2 {\n return { id: document2Id('cite'), kind: 'cite', keys: [...keys] };\n}\n\nexport function insertCiteTokenAtCaret(\n document: Document2Node,\n fieldId: string,\n textTokenId: string | null,\n caretOffset: number,\n keys: string[],\n): Document2Node {\n if (keys.length === 0) {\n return document;\n }\n const next = cloneDocument(document);\n const citeToken = citeTokenFromKeys(keys);\n visitFields(next.blocks, (field) => {\n if (field.id !== fieldId) {\n return false;\n }\n\n const textIndex = textTokenId\n ? field.tokens.findIndex((token) => token.id === textTokenId && token.kind === 'text')\n : field.tokens.findIndex((token) => token.kind === 'text');\n\n if (textIndex < 0) {\n field.tokens.push(citeToken);\n field.tokens.push({ id: document2Id('text'), kind: 'text', text: '' });\n return true;\n }\n\n const current = field.tokens[textIndex] as TextToken2;\n const [before, after] = splitTextTokenAt(current, caretOffset);\n const parts: InlineToken2[] = [...field.tokens.slice(0, textIndex)];\n if (before.text.length > 0) {\n parts.push(before);\n }\n parts.push(citeToken);\n parts.push(after);\n parts.push(...field.tokens.slice(textIndex + 1));\n field.tokens = normalizeFieldTokens(parts);\n return true;\n });\n return next;\n}\n\nexport function updateCiteTokenKeys(document: Document2Node, tokenId: string, keys: string[]): Document2Node {\n if (keys.length === 0) {\n return document;\n }\n const next = cloneDocument(document);\n visitFields(next.blocks, (field) => {\n const token = field.tokens.find((entry): entry is CiteToken2 => entry.id === tokenId && entry.kind === 'cite');\n if (!token) {\n return false;\n }\n token.keys = [...keys];\n return true;\n });\n return next;\n}\n\nexport function removeCiteTokenById(document: Document2Node, tokenId: string): Document2Node {\n const next = cloneDocument(document);\n visitFields(next.blocks, (field) => {\n const index = field.tokens.findIndex((token) => token.id === tokenId && token.kind === 'cite');\n if (index < 0) {\n return false;\n }\n field.tokens = normalizeFieldTokens(stitchTextAroundRemovedToken(field.tokens, index));\n return true;\n });\n return next;\n}\n\nexport function ensureDocument2BibliographyBlock(document: Document2Node, afterBlockId?: string | null): Document2Node {\n if (document.blocks.some((block) => block.kind === 'bibliography')) {\n return document;\n }\n const block: BibliographyBlock2 = {\n id: document2Id('block'),\n kind: 'bibliography',\n command: '\\\\begin{thebibliography}',\n closing: '\\\\end{thebibliography}',\n };\n return insertDocument2BlockAfter(document, afterBlockId ?? null, block);\n}\n\nexport function addDocument2Reference(document: Document2Node, partial: Partial<Reference2Json> = {}): Document2Node {\n const next = cloneDocument(document);\n next.references.push(createEmptyReference2(partial));\n return next;\n}\n\nexport function updateDocument2Reference(document: Document2Node, referenceId: string, patch: Partial<Reference2Json>): Document2Node {\n const next = cloneDocument(document);\n const reference = next.references.find((entry) => entry.id === referenceId);\n if (!reference) {\n return document;\n }\n if (typeof patch.key === 'string' && patch.key.trim().length > 0) {\n reference.key = patch.key.trim();\n }\n if (typeof patch.authors === 'string') {\n reference.authors = patch.authors;\n }\n if (typeof patch.title === 'string') {\n reference.title = patch.title;\n }\n if (typeof patch.year === 'string') {\n reference.year = patch.year;\n }\n if (typeof patch.url === 'string') {\n reference.url = patch.url;\n }\n if (typeof patch.venue === 'string') {\n reference.venue = patch.venue;\n }\n if (patch.field_separator === ',' || patch.field_separator === '،') {\n reference.fieldSeparator = patch.field_separator;\n }\n return next;\n}\n\nexport function removeDocument2Reference(document: Document2Node, referenceId: string): Document2Node {\n const next = cloneDocument(document);\n next.references = next.references.filter((reference) => reference.id !== referenceId);\n return next;\n}\n\nexport function moveDocument2Reference(document: Document2Node, referenceId: string, direction: -1 | 1): Document2Node {\n const next = cloneDocument(document);\n const index = next.references.findIndex((reference) => reference.id === referenceId);\n const targetIndex = index + direction;\n if (index < 0 || targetIndex < 0 || targetIndex >= next.references.length) {\n return document;\n }\n const [reference] = next.references.splice(index, 1);\n if (!reference) {\n return document;\n }\n next.references.splice(targetIndex, 0, reference);\n return next;\n}\n\nexport function setDocument2References(document: Document2Node, references: Reference2[]): Document2Node {\n const next = cloneDocument(document);\n next.references = references.map((reference) => ({ ...reference }));\n return next;\n}\n\nexport function updateDocument2Meta(document: Document2Node, patch: Document2MetaProp): Document2Node {\n const next = cloneDocument(document);\n const current = next.meta ?? emptyDocument2Meta();\n next.meta = {\n title: typeof patch.title === 'string' ? patch.title : current.title,\n authors: typeof patch.authors === 'string' ? patch.authors : current.authors,\n abstract: typeof patch.abstract === 'string' ? patch.abstract : current.abstract,\n date: patch.date\n ? normalizeDocument2HijriDate({ ...current.date, ...patch.date })\n : { ...current.date },\n };\n return next;\n}\n","import type { Document2LabelEntry } from './labels.js';\nimport type { Reference2 } from './types.js';\n\nexport type Document2KeyError = 'empty' | 'invalid' | 'duplicate';\n\nconst DOCUMENT2_KEY_PATTERN = /^[\\p{L}\\p{M}0-9:._-]+$/u;\n\n/** NFC-normalize and trim a document key (label or bibliography). */\nexport function normalizeDocument2Key(key: string): string {\n return key.normalize('NFC').trim();\n}\n\n/** True when key matches Unicode letters/marks, ASCII digits, and :._- with no spaces. */\nexport function isValidDocument2Key(key: string): boolean {\n const normalized = normalizeDocument2Key(key);\n return normalized.length > 0 && DOCUMENT2_KEY_PATTERN.test(normalized);\n}\n\nexport type Document2KeyNamespace = {\n references?: Array<Pick<Reference2, 'id' | 'key'>>;\n labels?: Array<Pick<Document2LabelEntry, 'ownerId' | 'key'>>;\n /** Skip this reference id when checking (editing that entry). */\n excludeReferenceId?: string;\n /** Skip this label owner id when checking (editing that float/eq). */\n excludeOwnerId?: string;\n};\n\n/** Returns true if another reference or label already uses this key (NFC match). */\nexport function isDuplicateDocument2Key(key: string, namespace: Document2KeyNamespace): boolean {\n const normalized = normalizeDocument2Key(key);\n if (normalized.length === 0) {\n return false;\n }\n for (const reference of namespace.references ?? []) {\n if (namespace.excludeReferenceId && reference.id === namespace.excludeReferenceId) {\n continue;\n }\n if (normalizeDocument2Key(reference.key) === normalized) {\n return true;\n }\n }\n for (const label of namespace.labels ?? []) {\n if (namespace.excludeOwnerId && label.ownerId === namespace.excludeOwnerId) {\n continue;\n }\n if (normalizeDocument2Key(label.key) === normalized) {\n return true;\n }\n }\n return false;\n}\n\n/** Classify a key for UI messaging: empty, invalid charset, or duplicate. */\nexport function document2KeyError(key: string, namespace: Document2KeyNamespace = {}): Document2KeyError | null {\n const normalized = normalizeDocument2Key(key);\n if (normalized.length === 0) {\n return 'empty';\n }\n if (!DOCUMENT2_KEY_PATTERN.test(normalized)) {\n return 'invalid';\n }\n if (isDuplicateDocument2Key(normalized, namespace)) {\n return 'duplicate';\n }\n return null;\n}\n","/** Arabic XeLaTeX preamble fragments for full-document export. */\nimport { NON_DEFAULT_CHARACTER_FONT_SPECS } from '../editor/characterFonts.js';\n\nexport type ArabicDigitsMapping = 'arabicdigits' | 'farsidigits' | 'digits';\n\nexport type ArabicXeLatexPreambleOptions = {\n digitsMapping?: ArabicDigitsMapping;\n /** When true, add the article class twocolumn option. Default false. */\n twocolumn?: boolean;\n};\n\nfunction fontOptions(digitsMapping: ArabicDigitsMapping, includeScript = true): string {\n const parts: string[] = [];\n if (includeScript) {\n parts.push('Script=Arabic');\n }\n if (digitsMapping !== 'digits') {\n parts.push(`Mapping=${digitsMapping}`);\n }\n if (parts.length === 0) {\n return '';\n }\n return `[${parts.join(',')}]`;\n}\n\nexport function arabicXeLatexPreamblePkg(twocolumn = false): string {\n const classOptions = twocolumn\n ? '12pt,a4paper,notitlepage,twocolumn'\n : '12pt,a4paper,notitlepage';\n return (\n `\n\\\\documentclass[${classOptions}]{article}\n` +\n String.raw`\\usepackage{amsmath,amsfonts,amssymb,mathrsfs,tikz,fancyhdr, mathtools}\n\\usepackage{fontspec} % For loading OpenType fonts\n\\usepackage{unicode-math} % For setting the math font\n\\usepackage{polyglossia} % For Arabic support\n\\usepackage{array}\n\\usepackage{cancel}\n\\usepackage{bidi}\n\\usepackage{multirow}\n\\usepackage{booktabs}\n\\usepackage{graphicx} % For \\reflectbox\n\\usepackage{xcolor}\n\\usepackage{tikz}\n\\usepackage{tcolorbox} % For tcolorbox environment\n\\usepackage{textcomp} % For \\textrightarrow command\n\\usepackage{url}\n\n\n% visit : https://www.symbolcopy.com/punctuation-symbol.html\n% for inversed punctuation\n\n% save inverted comma for use - copy paste -> ،\n% save back tick for use - copy paste -> ` + '`'\n );\n}\n\nexport function arabicXeLatexPreambleFont(digitsMapping: ArabicDigitsMapping = 'arabicdigits'): string {\n const customFonts = NON_DEFAULT_CHARACTER_FONT_SPECS\n .filter((font) => font.latexFontCommand && font.latexFontFamily)\n .map((font) => `\\\\newfontfamily${font.latexFontCommand}${fontOptions(digitsMapping)}{${font.latexFontFamily}}`)\n .join('\\n');\n const mathFontOptions = fontOptions(digitsMapping, false);\n return `\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n% Persian digits: Mapping=farsidigits\n% Arabic-Indic digits: Mapping=arabicdigits\n% Western digits: omit Mapping entirely\n\\\\setdefaultlanguage[calendar=gregorian]{arabic} % from polyglossia\n\\\\setmainfont${fontOptions(digitsMapping)}{Amiri}\n${customFonts}\n\\\\newfontfamily\\\\boldarabic${fontOptions(digitsMapping)}{Amiri Bold}\n\\\\newfontfamily\\\\italicarabic${fontOptions(digitsMapping)}{Amiri Italic}\n\n% for polyglossia url I dont know, sugggested by cursor\n\\\\newfontfamily\\\\arabicfonttt${fontOptions(digitsMapping)}{Amiri}\n\\\\newfontfamily\\\\arabicfontsf${fontOptions(digitsMapping)}{Amiri}\n\n\n% Explicitly set math font to XITS Math\n\\\\setmathfont${mathFontOptions}{XITS Math} % Ensure XITS Math is correctly installed and available\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n`;\n}\n\nexport function arabicXeLatexPreambleCmd(): string {\n const fontCommands = NON_DEFAULT_CHARACTER_FONT_SPECS\n .filter((font) => font.macro && font.latexFontCommand)\n .map((font) => `\\\\newcommand{${font.macro}}[1]{\\\\text{${font.latexFontCommand}{#1}}}`)\n .join('\\n');\n return String.raw`\n% Run with XeLaTeX compiler\n${fontCommands}\n\\newcommand{\\butexmirror}[1]{\\reflectbox{\\(#1\\)}}\n\n\\newcommand{\\arabN}{\\text{\\diwanioutlineshaded{ط}}}\n\\newcommand{\\arabZ}{\\text{\\diwanioutlineshaded{ص}}}\n\\newcommand{\\arabQ}{\\text{\\diwanioutlineshaded{ن}}}\n\\newcommand{\\arabR}{\\text{\\diwanioutlineshaded{ح}}}\n\\newcommand{\\arabC}{\\text{\\diwanioutlineshaded{ع}}}\n\\newcommand{\\arabH}{\\text{\\diwanioutlineshaded{ر}}}\n\n\n\\newcommand{\\lowerscript}[1]{\\raisebox{-4pt}{\\scriptsize #1}}\n\\newcommand{\\llowerscript}[1]{\\raisebox{-8pt}{\\scriptsize #1}}\n\\newcommand{\\lllowerscript}[2]{\\raisebox{#2pt}{\\scriptsize #1}}\n\n\\newcommand{\\arabdsub}[3]{\\prescript{}{#1}{\\prescript{}{#2}{#3}}} % arabic double subscript\n\\newcommand{\\arabsub}[2]{\\prescript{}{#1}{#2}} % arabic single subscript\n\n\n\n\\newcommand{\\upperscript}[1]{\\raisebox{8pt}{\\scriptsize #1}}\n\\newcommand{\\uupperscript}[2]{\\raisebox{#2pt}{\\scriptsize #1}}\n\\newcommand{\\vertbar}{\\rule[-1ex]{0.5pt}{2.5ex}}\n\\newcommand{\\horzbar}{\\rule[.5ex]{2.5ex}{0.5pt}}\n\n\n\\newcommand{\\arsqrt}[2][]{\\reflectbox{\\(\\sqrt[\\reflectbox{\\(#1\\)}]{\\reflectbox{\\(#2\\)}}\\)}}\n\\newcommand{\\arabsqrt}[2][]{\\arsqrt[#1]{#2}}\n\\newcommand{\\arabvec}[1]{\\reflectbox{$\\vec{\\reflectbox{$#1$}}$}}\n\n\\newcommand{\\arabexp}[1]{{}^{#1}\\!\\raisebox{-4.5pt}{\\text{\\diwani{ه}}}}\n\\newcommand{\\arablog}[2]{\\left(\\text{#2}\\right)\\!\\prescript{}{\\text{#1}}{\\text{\\diwani{لو}}}}\n\\newcommand{\\arabnlog}[1]{\\left(\\text{#1}\\right)\\!\\prescript{}{\\text{\\diwani{ه}}}{\\text{\\diwani{لو}}}}\n\n\\newcommand{\\arabcos}[1]{\\left(#1\\right)\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{جتا}}}}\n\\newcommand{\\arabsin}[1]{\\left(#1\\right)\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{جا}}}}\n\\newcommand{\\arabtan}[1]{\\left(#1\\right)\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{ظا}}}}\n\\newcommand{\\arabcot}[1]{\\left(#1\\right)\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{ظتا}}}}\n\\newcommand{\\arabsec}[1]{\\left(#1\\right)\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{قا}}}}\n\\newcommand{\\arabcsc}[1]{\\left(#1\\right)\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{قتا}}}}\n\n\\newcommand{\\arabacos}[1]{\\left(#1\\right)\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{قجتا}}}}\n\\newcommand{\\arabasin}[1]{\\left(#1\\right)\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{قجا}}}}\n\\newcommand{\\arabatan}[1]{\\left(#1\\right)\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{قظا}}}}\n\\newcommand{\\arabacot}[1]{\\left(#1\\right)\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{قظتا}}}}\n\\newcommand{\\arabasec}[1]{\\left(#1\\right)\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{ققا}}}}\n\\newcommand{\\arabacsc}[1]{\\left(#1\\right)\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{ققتا}}}}\n\n\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n% summation\n\\newcommand{\\arablim}[2]{\\underset{#2 \\leftarrow #1}{\\text{نـــــها}}}\n\\newcommand{\\arabsum}[2]{\\underset{#1}{\\overset{#2}{\\text{مجـــ}}}}\n\\newcommand{\\arabprod}[2]{\\underset{#1}{\\overset{#2}{\\text{جـــذ}}}}\n\\newcommand{\\arabint}[2]{\\prescript{#2}{#1\\!\\!\\!}\\int}\n\n\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n% we define this command to make it ease for change of notation later\n\\newcommand{\\ad}[0]{\\text{ء}} % \"ad\" for arabic differentiation or derivative (ء\" لإشتقاق\")\n\\newcommand{\\arpi}[0]{\\!\\text{\\diwani{ط}}}\n\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n% differentials\n\n\\newcommand{\\arabdiff}[2]{\\frac{#1\\ad}{#2\\ad}} % arabic differential\n\\newcommand{\\arabddiff}[2]{\\frac{#1{}^{2}\\ad}{{}^{2}#2\\ad}} % arabic second differential\n\n\\newcommand{\\arabode}[2][-5pt]{\\stackrel{\\raisebox{#1}{$\\cdot$}}{\\text{#2}}}\n\\newcommand{\\arabodde}[2][-5pt]{\\stackrel{\\raisebox{#1}{$\\vcenter{\\hbox{$\\cdot\\!\\cdot$}}$}}{\\text{#2}}}\n\\newcommand{\\araboddde}[2][-5pt]{\\stackrel{\\raisebox{#1}{$\\vcenter{\\hbox{$\\cdot\\!\\cdot\\!\\cdot$}}$}}{\\text{#2}}}\n\\newcommand{\\arabpde}[1]{\\prescript{}{#1\\!\\!}{\\nabla}} % arabic partial differential equation (PDE)\n\n\\newcommand{\\arabprime}[0]{\\reflectbox{$\\prime$}\\!} % arabic prime notation\n\\newcommand{\\arabpprime}[0]{\\reflectbox{$\\prime$}\\reflectbox{$\\prime$}\\!} % arabic prime notation\n\\newcommand{\\arabppprime}[0]{\\reflectbox{$\\prime$}\\reflectbox{$\\prime$}\\reflectbox{$\\prime$}\\!} % arabic prime notation\n\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n% probability\n\\newcommand{\\ap}[0]{\\!\\text{\\diwani{حـ}}} % arabic Probability - used a lot so short form\n\\newcommand{\\arabExpct}[0]{\\text{\\diwani{توقـ}}} % arabic Expectation\n\\newcommand{\\arabVar}[0]{\\!\\text{\\diwani{با}}} % arabic Variance\n\\newcommand{\\arabCov}[0]{\\!\\text{\\diwani{ت}}} % arabic Covariance\n\n\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n% custom commands specific to lesson\n\\newcommand{\\lagrange}[2]{\\left(#2\\right)\\!\\prescript{}{#1}{\\text{\\diwani{لا}}}}\n\\newcommand{\\xii}[0]{\\left(\\prescript{}{\\text{يـ}}{\\text{س}}\\right)\\!}\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n\n\n\\newcommand{\\arexp}[0]{\\!\\raisebox{-4.5pt}{\\text{\\diwani{ه}}}}\n\\newcommand{\\arlog}[0]{\\!\\!\\text{\\diwani{لو}}}\n\\newcommand{\\arln}[0]{\\!\\!\\prescript{}{\\text{\\diwani{ه}}}{\\text{\\diwani{لو}}}}\n\\newcommand{\\ardet}[0]{\\!\\!\\text{\\diwani{محدد}}}\n\n\\newcommand{\\arsum}[0]{\\text{مجـــ}}\n\\newcommand{\\arprod}[0]{\\text{جـــذ}}\n\n\\newcommand{\\arlim}[0]{\\text{نـــــها}}\n\\newcommand{\\armax}[0]{\\text{أكبر}}\n\\newcommand{\\armin}[0]{\\text{أصغر}}\n\\newcommand{\\arsup}[0]{\\text{أعلى}}\n\\newcommand{\\arinf}[0]{\\text{أدنى}}\n\n\\newcommand{\\arsin}[0]{\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{جا}}}}\n\\newcommand{\\arcos}[0]{\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{جتا}}}}\n\\newcommand{\\artan}[0]{\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{ظا}}}}\n\\newcommand{\\arcot}[0]{\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{ظتا}}}}\n\\newcommand{\\arsec}[0]{\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{قا}}}}\n\\newcommand{\\arcsc}[0]{\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{قتا}}}} \n\n\\newcommand{\\arasin}[0]{\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{قجا}}}}\n\\newcommand{\\aracos}[0]{\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{قجتا}}}}\n\\newcommand{\\aratan}[0]{\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{قظا}}}}\n\\newcommand{\\aracot}[0]{\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{قظتا}}}}\n\\newcommand{\\arasec}[0]{\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{ققا}}}}\n\\newcommand{\\aracsc}[0]{\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{ققتا}}}}\n\n\\newcommand{\\arsinh}[0]{\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{جزا}}}}\n\\newcommand{\\arcosh}[0]{\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{جتزا}}}}\n\\newcommand{\\artanh}[0]{\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{ظزا}}}}\n\\newcommand{\\arcoth}[0]{\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{ظتزا}}}}\n\\newcommand{\\arsech}[0]{\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{قزا}}}}\n\\newcommand{\\arcsch}[0]{\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{قتزا}}}}\n\n\\newcommand{\\arasinh}[0]{\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{قجزا}}}}\n\\newcommand{\\aracosh}[0]{\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{قجتزا}}}} \n\\newcommand{\\aratanh}[0]{\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{قظزا}}}}\n\\newcommand{\\aracoth}[0]{\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{قظتزا}}}}\n\\newcommand{\\arasech}[0]{\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{ققزا}}}}\n\\newcommand{\\aracsch}[0]{\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{ققتزا}}}}\n\n\\newcommand{\\unit}[1]{\\text{#1}}\n\\newcommand{\\idx}[1]{#1}\n\\newcommand{\\arbinom}[2]{\\left(\\begin{array}{c} #1 \\\\ #2 \\end{array} \\right)}\n`;\n}\n\nexport function getArabicXeLatexPreamble(\n digitsMappingOrOptions: ArabicDigitsMapping | ArabicXeLatexPreambleOptions = 'arabicdigits',\n): string {\n const options: ArabicXeLatexPreambleOptions =\n typeof digitsMappingOrOptions === 'string'\n ? { digitsMapping: digitsMappingOrOptions }\n : digitsMappingOrOptions;\n const digitsMapping = options.digitsMapping ?? 'arabicdigits';\n const twocolumn = options.twocolumn === true;\n return (\n arabicXeLatexPreamblePkg(twocolumn) +\n arabicXeLatexPreambleFont(digitsMapping) +\n arabicXeLatexPreambleCmd()\n );\n}\n","import { renderMathNodeLatex } from '../document/mathObject.js';\nimport { mirrorBuTeXOperatorsInTex } from '../editor/atomicCommandsOperators.js';\nimport type { DigitFormId } from '../editor/types.js';\nimport {\n getArabicXeLatexPreamble,\n type ArabicDigitsMapping,\n} from './arabicPreamble.js';\nimport {\n BUTEX_CLOSING_HAMDALA,\n butexBasmalaDisplayLatex,\n butexBasmalaTitlingPreamble,\n butexMaghribiDisplayLatex,\n document2HasAbstract,\n document2HasMaketitle,\n emptyDocument2Meta,\n formatHijriDate,\n} from './articleMeta.js';\nimport { bibliographyEntryLatex, citeTokenLatex } from './citations.js';\nimport { refTokenLatex, stripDisplayMathDelimiters } from './labels.js';\nimport type {\n Document2Block,\n Document2Meta,\n Document2Node,\n ImageBlock2,\n InlineField2,\n InlineToken2,\n ListBlock2,\n MathToken2,\n TableBlock2,\n TextStyle2,\n TextBlock2,\n} from './types.js';\n\nexport type Document2LatexOptions = {\n /**\n * When true (default), emit a complete Arabic XeLaTeX file:\n * preamble + \\\\begin{document} + body + \\\\end{document}.\n * Pass false for body-only blocks.\n */\n wrapDocument?: boolean;\n /** Font digit Mapping when wrapping. Default 'arabicdigits'. */\n digitsMapping?: ArabicDigitsMapping;\n /** Document-level digit form for XeLaTeX font Mapping. Ignored when digitsMapping is set. */\n digitForm?: DigitFormId;\n /** When true, use article class option twocolumn. Default false. */\n twocolumn?: boolean;\n};\n\nfunction digitsMappingFromDigitForm(digitForm: DigitFormId | undefined): ArabicDigitsMapping {\n if (digitForm === 'western') {\n return 'digits';\n }\n if (digitForm === 'persianIndic') {\n return 'farsidigits';\n }\n return 'arabicdigits';\n}\n\nfunction mathBodyLatex(token: MathToken2): string {\n if (token.sourceOwner === 'editor') {\n return stripDisplayMathDelimiters(mirrorBuTeXOperatorsInTex(token.source, { target: 'compile' }));\n }\n if (!token.math || token.sourceOwner === 'raw') {\n return stripDisplayMathDelimiters(token.source);\n }\n const rendered = renderMathNodeLatex(token.math);\n return stripDisplayMathDelimiters(rendered);\n}\n\nfunction styledTextLatex(text: string, style: TextStyle2 | undefined): string {\n let output = text;\n if (style?.bold) {\n output = `\\\\textbf{${output}}`;\n }\n if (style?.italic) {\n output = `\\\\textit{${output}}`;\n }\n if (style?.underline) {\n output = `\\\\underline{${output}}`;\n }\n return output;\n}\n\nfunction tokenLatex(token: InlineToken2): string {\n if (token.kind === 'text') {\n return styledTextLatex(token.text, token.style);\n }\n if (token.kind === 'cite') {\n return citeTokenLatex(token.keys);\n }\n if (token.kind === 'ref') {\n return refTokenLatex(token.keys, token.refCommand);\n }\n if (token.display && token.labelEnabled && token.label && token.label.trim().length > 0) {\n const body = mathBodyLatex(token);\n return `\\\\begin{equation}\\n${body}\\n\\\\label{${token.label.trim()}}\\n\\\\end{equation}`;\n }\n if (token.sourceOwner === 'editor') {\n return mirrorBuTeXOperatorsInTex(token.source, { target: 'compile' });\n }\n if (!token.math || token.sourceOwner === 'raw') {\n return token.source;\n }\n return renderMathNodeLatex(token.math);\n}\n\nexport function inlineFieldLatex(field: InlineField2): string {\n return field.tokens.map((token) => tokenLatex(token)).join('');\n}\n\nfunction textBlockLatex(block: TextBlock2): string {\n const content = inlineFieldLatex(block.field);\n const body = block.command === '\\\\paragraph' ? `\\\\par\\n${content}` : `${block.command}{${content}}`;\n if (block.command === '\\\\paragraph' && block.centered) {\n return `\\\\begin{center}\\n${body}\\n\\\\end{center}`;\n }\n return body;\n}\n\nfunction indent(value: string): string {\n return value\n .split('\\n')\n .map((line) => ` ${line}`)\n .join('\\n');\n}\n\nfunction listBlockLatex(block: ListBlock2, references: Document2Node['references']): string {\n const items = block.items\n .map((item) => {\n const nested = item.blocks.map((child) => '\\n' + indent(blockLatex(child, references))).join('');\n return ` \\\\item ${inlineFieldLatex(item.field)}${nested}`;\n })\n .join('\\n');\n return `${block.command}\\n${items}\\n${block.closing}`;\n}\n\nfunction tabularInnerLatex(block: TableBlock2): string {\n const rows = block.rows\n .map((row) => ` ${row.map((cell) => inlineFieldLatex(cell)).join(' & ')}`)\n .join(' \\\\\\\\\\n');\n return `${block.command}{${block.columns}}\\n${rows}\\n${block.closing}`;\n}\n\nfunction floatCaptionLabelLines(block: ImageBlock2 | TableBlock2): string[] {\n const lines: string[] = [];\n if (block.captionEnabled && block.caption.trim().length > 0) {\n lines.push(` \\\\caption{${block.caption.trim()}}`);\n }\n if (block.labelEnabled && block.label.trim().length > 0) {\n lines.push(` \\\\label{${block.label.trim()}}`);\n }\n return lines;\n}\n\nfunction tableBlockLatex(block: TableBlock2): string {\n const lines = ['\\\\begin{table}[htbp]'];\n if (block.centered) {\n lines.push(' \\\\centering');\n }\n lines.push(...floatCaptionLabelLines(block));\n lines.push(indent(tabularInnerLatex(block)));\n lines.push('\\\\end{table}');\n return lines.join('\\n');\n}\n\n/** Prefer \\\\columnwidth so figures fit a column (equals \\\\textwidth in one-column). */\nfunction remapImageWidthForColumns(value: string): string {\n return value.replace(/\\\\textwidth\\b/g, '\\\\columnwidth');\n}\n\nfunction imageOptionsLatex(block: ImageBlock2, constrainToColumn: boolean): string {\n const entries = Object.entries(block.options).map(([key, value]) => {\n if (constrainToColumn && key === 'width') {\n return [key, remapImageWidthForColumns(value)] as const;\n }\n return [key, value] as const;\n });\n if (entries.length === 0) {\n return '';\n }\n return `[${entries.map(([key, value]) => `${key}=${value}`).join(',')}]`;\n}\n\nfunction imageBlockLatex(block: ImageBlock2): string {\n const lines = ['\\\\begin{figure}[htbp]'];\n if (block.centered) {\n lines.push(' \\\\centering');\n }\n // Remap textwidth→columnwidth: safe in one-column, required in twocolumn.\n lines.push(` ${block.command}${imageOptionsLatex(block, true)}{${block.value}}`);\n lines.push(...floatCaptionLabelLines(block));\n lines.push('\\\\end{figure}');\n return lines.join('\\n');\n}\n\nfunction blockLatex(block: Document2Block, references: Document2Node['references']): string {\n if (block.kind === 'textBlock') {\n return textBlockLatex(block);\n }\n if (block.kind === 'list') {\n return listBlockLatex(block, references);\n }\n if (block.kind === 'table') {\n return tableBlockLatex(block);\n }\n if (block.kind === 'image') {\n return imageBlockLatex(block);\n }\n if (block.kind === 'bibliography') {\n const width = String(Math.max(references.length, 9));\n const items = references.map((reference) => ` ${bibliographyEntryLatex(reference)}`).join('\\n');\n return `${block.command}{${width}}\\n${items}\\n${block.closing}`;\n }\n return block.value;\n}\n\nfunction authorLatex(authors: string): string {\n return authors\n .split(/\\n+/)\n .map((line) => line.trim())\n .filter((line) => line.length > 0)\n .join(' \\\\\\\\ ');\n}\n\n/** Title metadata + titling hooks for the XeLaTeX preamble (before \\\\begin{document}). */\nfunction articleMaketitlePreamble(meta: Document2Meta, twocolumn = false): string {\n if (!document2HasMaketitle(meta)) {\n return '';\n }\n const parts: string[] = [butexBasmalaTitlingPreamble({ twocolumn })];\n if (meta.title.trim().length > 0) {\n parts.push(`\\\\title{${meta.title.trim()}}`);\n }\n if (meta.authors.trim().length > 0) {\n parts.push(`\\\\author{${authorLatex(meta.authors)}}`);\n }\n parts.push(`\\\\date{${formatHijriDate(meta.date, { locale: 'ar', digitForm: 'western' })}}`);\n return parts.join('\\n');\n}\n\nfunction articleFrontMatterLatex(meta: Document2Meta): string[] {\n const parts: string[] = [];\n if (document2HasMaketitle(meta)) {\n parts.push('\\\\maketitle');\n } else {\n parts.push(butexBasmalaDisplayLatex());\n }\n if (document2HasAbstract(meta)) {\n parts.push(`\\\\begin{abstract}\\n${meta.abstract.trim()}\\n\\\\end{abstract}`);\n }\n return parts;\n}\n\nexport function document2Latex(\n document: Document2Node,\n options: Document2LatexOptions = {},\n): string {\n const meta = document.meta ?? emptyDocument2Meta();\n const twocolumn = options.twocolumn === true;\n const front = articleFrontMatterLatex(meta);\n const bodyBlocks = document.blocks.map((block) => blockLatex(block, document.references));\n const closing = butexMaghribiDisplayLatex(BUTEX_CLOSING_HAMDALA);\n const body = [...front, ...bodyBlocks, closing].filter((part) => part.length > 0).join('\\n\\n');\n const wrapDocument = options.wrapDocument !== false;\n if (!wrapDocument) {\n // Body-only: include title metadata so callers still see \\\\title / titling when present.\n const metaPreamble = articleMaketitlePreamble(meta, twocolumn);\n return metaPreamble.length > 0 ? `${metaPreamble}\\n\\n${body}` : body;\n }\n const preamble =\n getArabicXeLatexPreamble({\n digitsMapping: options.digitsMapping ?? digitsMappingFromDigitForm(options.digitForm),\n twocolumn,\n }) +\n '\\n' +\n articleMaketitlePreamble(meta, twocolumn);\n return `${preamble}\\n\\\\begin{document}\\n\\n${body}\\n\\n\\\\end{document}\\n`;\n}\n","import { toMathObjectJson } from '../document/mathObject.js';\nimport { citeTokenLatex } from './citations.js';\nimport { refTokenLatex } from './labels.js';\nimport type {\n Document2Block,\n Document2BlockJson,\n Document2Json,\n Document2ListItemJson,\n Document2MathObjectJson,\n Document2Node,\n InlineField2,\n Reference2Json,\n TextFormatSpan2Json,\n} from './types.js';\n\ntype SerializedField2 = {\n value: string;\n formats: TextFormatSpan2Json[];\n mathObjects: Array<Document2MathObjectJson | null>;\n hasPersistedMath: boolean;\n};\n\nfunction serializeField(field: InlineField2): SerializedField2 {\n let value = '';\n let hasPersistedMath = false;\n const formats: TextFormatSpan2Json[] = [];\n const mathObjects: Array<Document2MathObjectJson | null> = [];\n\n for (const token of field.tokens) {\n if (token.kind === 'text') {\n const start = value.length;\n value += token.text;\n if (token.text.length > 0 && (token.style?.bold || token.style?.italic || token.style?.underline)) {\n formats.push({\n start,\n end: value.length,\n ...(token.style.bold ? { bold: true } : {}),\n ...(token.style.italic ? { italic: true } : {}),\n ...(token.style.underline ? { underline: true } : {}),\n });\n }\n continue;\n }\n if (token.kind === 'cite') {\n value += citeTokenLatex(token.keys);\n continue;\n }\n if (token.kind === 'ref') {\n value += refTokenLatex(token.keys, token.refCommand);\n continue;\n }\n\n value += token.source;\n if (!token.math || token.sourceOwner === 'raw') {\n if (token.labelEnabled !== undefined || token.label !== undefined) {\n hasPersistedMath = true;\n mathObjects.push({\n node_type: 'RawMathObject',\n ...(token.labelEnabled !== undefined ? { label_enabled: token.labelEnabled } : {}),\n ...(token.label !== undefined ? { label: token.label } : {}),\n });\n } else {\n mathObjects.push(null);\n }\n continue;\n }\n\n hasPersistedMath = true;\n mathObjects.push({\n ...toMathObjectJson(token.math),\n ...(token.sourceSide ? { source_side: token.sourceSide } : {}),\n source_owner: token.sourceOwner,\n ...(token.labelEnabled !== undefined ? { label_enabled: token.labelEnabled } : {}),\n ...(token.label !== undefined ? { label: token.label } : {}),\n });\n }\n\n return { value, formats, mathObjects, hasPersistedMath };\n}\n\nfunction fieldJson(field: InlineField2): Pick<Document2BlockJson, 'value' | 'formats' | 'math_objects'> {\n const serialized = serializeField(field);\n return {\n value: serialized.value,\n ...(serialized.formats.length > 0 ? { formats: serialized.formats } : {}),\n ...(serialized.hasPersistedMath ? { math_objects: serialized.mathObjects } : {}),\n };\n}\n\nfunction listItemJson(item: Extract<Document2Block, { kind: 'list' }>['items'][number]): Document2ListItemJson {\n const field = fieldJson(item.field);\n return {\n value: field.value ?? '',\n ...(field.formats ? { formats: field.formats } : {}),\n ...(field.math_objects ? { math_objects: field.math_objects } : {}),\n ...(item.blocks.length > 0 ? { blocks: item.blocks.map(blockJson) } : {}),\n };\n}\n\nfunction blockJson(block: Document2Block): Document2BlockJson {\n if (block.kind === 'textBlock') {\n return {\n command: block.command,\n ...fieldJson(block.field),\n ...(block.command === '\\\\paragraph' ? { centered: block.centered === true } : {}),\n };\n }\n if (block.kind === 'list') {\n return {\n command: block.command,\n closing: block.closing,\n items: block.items.map(listItemJson),\n };\n }\n if (block.kind === 'table') {\n const fields = block.rows.map((row) => row.map(serializeField));\n const hasPersistedMath = fields.some((row) => row.some((field) => field.hasPersistedMath));\n return {\n command: block.command,\n closing: block.closing,\n columns: block.columns,\n rows: fields.map((row) => row.map((field) => field.value)),\n ...(fields.some((row) => row.some((field) => field.formats.length > 0))\n ? { cell_formats: fields.map((row) => row.map((field) => field.formats)) }\n : {}),\n ...(hasPersistedMath\n ? { math_objects: fields.flatMap((row) => row.flatMap((field) => field.mathObjects)) }\n : {}),\n centered: block.centered,\n caption_enabled: block.captionEnabled,\n caption: block.caption,\n label_enabled: block.labelEnabled,\n label: block.label,\n };\n }\n if (block.kind === 'image') {\n return {\n command: block.command,\n value: block.value,\n ...(block.assetId !== undefined ? { asset_id: block.assetId } : {}),\n options: { ...block.options },\n centered: block.centered,\n caption_enabled: block.captionEnabled,\n caption: block.caption,\n label_enabled: block.labelEnabled,\n label: block.label,\n };\n }\n if (block.kind === 'bibliography') {\n return { command: block.command, closing: block.closing };\n }\n return { command: block.command, value: block.value };\n}\n\nfunction referenceJson(reference: Document2Node['references'][number]): Reference2Json {\n return {\n key: reference.key,\n authors: reference.authors,\n title: reference.title,\n year: reference.year,\n url: reference.url,\n venue: reference.venue,\n field_separator: reference.fieldSeparator,\n };\n}\n\n/** Convert the live editor AST to the canonical JSON wire format. */\nexport function toDocumentJson2(document: Document2Node): Document2Json {\n if (document.nodeType !== 'DocumentObject' || !Array.isArray(document.blocks)) {\n throw new Error('toDocumentJson2 requires a live Document2Node');\n }\n return {\n node_type: 'DocumentObject',\n meta: {\n title: document.meta.title,\n authors: document.meta.authors,\n date: { ...document.meta.date },\n abstract: document.meta.abstract,\n },\n references: document.references.map(referenceJson),\n blocks: document.blocks.map(blockJson),\n };\n}\n","import type { Document2Node } from './types.js';\nimport { cloneDocument2Node } from './commands.js';\n\nexport const DEFAULT_DOCUMENT2_HISTORY_MAX_DEPTH = 100;\n\nexport type Document2HistoryStacks = {\n past: Document2Node[];\n future: Document2Node[];\n maxDepth: number;\n};\n\nexport function createDocument2History(maxDepth: number = DEFAULT_DOCUMENT2_HISTORY_MAX_DEPTH): Document2HistoryStacks {\n return { past: [], future: [], maxDepth };\n}\n\nexport function pushDocument2Snapshot(stacks: Document2HistoryStacks, documentBeforeEdit: Document2Node): void {\n stacks.past.push(cloneDocument2Node(documentBeforeEdit));\n if (stacks.past.length > stacks.maxDepth) {\n stacks.past.splice(0, stacks.past.length - stacks.maxDepth);\n }\n stacks.future = [];\n}\n\nexport function restoreDocument2Undo(stacks: Document2HistoryStacks, documentNow: Document2Node): Document2Node | null {\n if (stacks.past.length === 0) {\n return null;\n }\n stacks.future.push(cloneDocument2Node(documentNow));\n return stacks.past.pop() ?? null;\n}\n\nexport function restoreDocument2Redo(stacks: Document2HistoryStacks, documentNow: Document2Node): Document2Node | null {\n if (stacks.future.length === 0) {\n return null;\n }\n stacks.past.push(cloneDocument2Node(documentNow));\n return stacks.future.pop() ?? null;\n}\n\nexport function document2HistoryCanUndo(stacks: Document2HistoryStacks): boolean {\n return stacks.past.length > 0;\n}\n\nexport function document2HistoryCanRedo(stacks: Document2HistoryStacks): boolean {\n return stacks.future.length > 0;\n}\n","export type BlockSelectionRange = { from: number; to: number };\n\nexport type BlockSelectionState = {\n selection: BlockSelectionRange | null;\n anchor: number | null;\n};\n\nexport function emptyBlockSelection(): BlockSelectionState {\n return { selection: null, anchor: null };\n}\n\nexport function normalizeBlockSelection(\n selection: BlockSelectionRange | null,\n blockCount: number,\n): BlockSelectionRange | null {\n if (!selection) {\n return null;\n }\n const { from, to } = selection;\n if (\n blockCount <= 0 ||\n from < 0 ||\n to < 0 ||\n from >= blockCount ||\n to >= blockCount ||\n from > to\n ) {\n return null;\n }\n return { from, to };\n}\n\nfunction inRange(selection: BlockSelectionRange, index: number): boolean {\n return index >= selection.from && index <= selection.to;\n}\n\n/** Checkbox click without Shift */\nexport function toggleBlockInSelection(\n state: BlockSelectionState,\n index: number,\n blockCount: number,\n): BlockSelectionState {\n if (index < 0 || index >= blockCount) {\n return state;\n }\n\n const selection = normalizeBlockSelection(state.selection, blockCount);\n if (!selection) {\n return { selection: { from: index, to: index }, anchor: index };\n }\n\n if (inRange(selection, index)) {\n if (selection.from === selection.to) {\n return emptyBlockSelection();\n }\n if (index === selection.from) {\n return { selection: { from: selection.from + 1, to: selection.to }, anchor: state.anchor };\n }\n if (index === selection.to) {\n return { selection: { from: selection.from, to: selection.to - 1 }, anchor: state.anchor };\n }\n return emptyBlockSelection();\n }\n\n if (index === selection.from - 1) {\n return { selection: { from: index, to: selection.to }, anchor: state.anchor ?? index };\n }\n if (index === selection.to + 1) {\n return { selection: { from: selection.from, to: index }, anchor: state.anchor ?? index };\n }\n\n return { selection: { from: index, to: index }, anchor: index };\n}\n\n/** Shift+click on checkbox or header label */\nexport function extendBlockSelectionFromAnchor(\n state: BlockSelectionState,\n index: number,\n blockCount: number,\n): BlockSelectionState {\n if (index < 0 || index >= blockCount) {\n return state;\n }\n\n const anchor = state.anchor ?? index;\n const from = Math.min(anchor, index);\n const to = Math.max(anchor, index);\n return {\n selection: { from, to },\n anchor: state.anchor ?? index,\n };\n}\n\nexport function remapSelectionAfterRangeMove(\n selection: BlockSelectionRange,\n direction: -1 | 1,\n): BlockSelectionRange {\n return { from: selection.from + direction, to: selection.to + direction };\n}\n","import { formatBibliographyNumber, formatCiteLabel } from './citations.js';\nimport {\n BUTEX_BASMALA,\n BUTEX_CLOSING_HAMDALA,\n butexBasmalaDisplayTex,\n butexMaghribiDisplayTex,\n document2HasAbstract,\n document2HasMaketitle,\n emptyDocument2Meta,\n formatHijriDate,\n} from './articleMeta.js';\nimport { formatFloatCaptionTitle, formatRefLabel, labelNumberMap } from './labels.js';\nimport { mathTokenSourceForSide } from './mathBridge.js';\nimport type { DigitFormId } from '../editor/types.js';\nimport type { EditorSide } from '../editor/index.js';\nimport type { ButexUiLocale } from '../uiLocale.js';\nimport type {\n Document2Block,\n Document2Direction,\n Document2MathOutput,\n Document2Node,\n Document2Preview,\n InlineField2,\n MathIsland2,\n PreviewBlock2,\n PreviewInline2,\n TextBlock2,\n} from './types.js';\n\nexport type Document2PreviewOptions = {\n documentDirection?: Document2Direction;\n digitForm?: DigitFormId;\n uiLocale?: ButexUiLocale;\n};\n\nfunction mathTex(\n token: Extract<InlineField2['tokens'][number], { kind: 'math' }>,\n equationSide: EditorSide,\n digitForm: DigitFormId | undefined,\n): string {\n return mathTokenSourceForSide(token, equationSide, digitForm);\n}\n\nfunction previewInlines(\n field: InlineField2,\n islands: MathIsland2[],\n output: Document2MathOutput,\n equationSide: EditorSide,\n document: Document2Node,\n previewOptions: Document2PreviewOptions,\n): PreviewInline2[] {\n return field.tokens.map((token) => {\n if (token.kind === 'text') {\n return { kind: 'text', text: token.text, ...(token.style ? { style: token.style } : {}) };\n }\n if (token.kind === 'cite') {\n return {\n kind: 'cite',\n id: token.id,\n keys: [...token.keys],\n label: formatCiteLabel(token.keys, document.references, {\n documentDirection: previewOptions.documentDirection,\n digitForm: previewOptions.digitForm,\n }),\n };\n }\n if (token.kind === 'ref') {\n return {\n kind: 'ref',\n id: token.id,\n keys: [...token.keys],\n refCommand: token.refCommand,\n label: formatRefLabel(token.keys, document, token.refCommand, {\n documentDirection: previewOptions.documentDirection,\n digitForm: previewOptions.digitForm,\n }),\n };\n }\n const island = {\n id: token.id,\n tex: mathTex(token, equationSide, previewOptions.digitForm),\n display: token.display,\n output,\n editable: token.editable,\n };\n islands.push(island);\n return { kind: 'math', ...island };\n });\n}\n\nfunction textBlockPreview(\n block: TextBlock2,\n islands: MathIsland2[],\n output: Document2MathOutput,\n equationSide: EditorSide,\n document: Document2Node,\n previewOptions: Document2PreviewOptions,\n): PreviewBlock2 {\n const inlines = previewInlines(block.field, islands, output, equationSide, document, previewOptions);\n if (block.command === '\\\\section') {\n return { kind: 'heading', id: block.id, level: 1, inlines };\n }\n if (block.command === '\\\\subsection') {\n return { kind: 'heading', id: block.id, level: 2, inlines };\n }\n if (block.command === '\\\\subsubsection') {\n return { kind: 'heading', id: block.id, level: 3, inlines };\n }\n return {\n kind: 'paragraph',\n id: block.id,\n inlines,\n ...(block.centered ? { centered: true } : {}),\n };\n}\n\nfunction floatNumberLabel(\n document: Document2Node,\n key: string | undefined,\n previewOptions: Document2PreviewOptions,\n): string | undefined {\n if (!key || key.trim().length === 0) {\n return undefined;\n }\n const hit = labelNumberMap(document).get(key.trim());\n if (!hit || (hit.kind !== 'fig' && hit.kind !== 'tab')) {\n return undefined;\n }\n return formatFloatCaptionTitle(hit.kind, hit.number, {\n uiLocale: previewOptions.uiLocale ?? 'ar',\n documentDirection: previewOptions.documentDirection,\n digitForm: previewOptions.digitForm,\n });\n}\n\nfunction blockPreview(\n block: Document2Block,\n islands: MathIsland2[],\n output: Document2MathOutput,\n equationSide: EditorSide,\n document: Document2Node,\n previewOptions: Document2PreviewOptions,\n): PreviewBlock2 {\n if (block.kind === 'textBlock') {\n return textBlockPreview(block, islands, output, equationSide, document, previewOptions);\n }\n if (block.kind === 'list') {\n return {\n kind: 'list',\n id: block.id,\n ordered: block.command === '\\\\begin{enumerate}',\n items: block.items.map((item) => ({\n id: item.id,\n inlines: previewInlines(item.field, islands, output, equationSide, document, previewOptions),\n blocks: item.blocks.map((child) => blockPreview(child, islands, output, equationSide, document, previewOptions)),\n })),\n };\n }\n if (block.kind === 'table') {\n const label = block.labelEnabled ? block.label.trim() : '';\n return {\n kind: 'table',\n id: block.id,\n rows: block.rows.map((row) => row.map((cell) => previewInlines(cell, islands, output, equationSide, document, previewOptions))),\n ...(block.captionEnabled && block.caption.trim().length > 0 ? { caption: block.caption.trim() } : {}),\n ...(label.length > 0 ? { label, numberLabel: floatNumberLabel(document, label, previewOptions) } : {}),\n };\n }\n if (block.kind === 'image') {\n const label = block.labelEnabled ? block.label.trim() : '';\n return {\n kind: 'image',\n id: block.id,\n src: block.value,\n ...(block.assetId !== undefined ? { assetId: block.assetId } : {}),\n options: block.options,\n ...(block.captionEnabled && block.caption.trim().length > 0 ? { caption: block.caption.trim() } : {}),\n ...(label.length > 0 ? { label, numberLabel: floatNumberLabel(document, label, previewOptions) } : {}),\n };\n }\n if (block.kind === 'bibliography') {\n return {\n kind: 'bibliography',\n id: block.id,\n items: document.references.map((reference, index) => ({\n id: reference.id,\n numberLabel: formatBibliographyNumber(index + 1, {\n documentDirection: previewOptions.documentDirection,\n digitForm: previewOptions.digitForm,\n }),\n key: reference.key,\n authors: reference.authors,\n title: reference.title,\n year: reference.year,\n url: reference.url,\n venue: reference.venue,\n fieldSeparator: reference.fieldSeparator,\n })),\n };\n }\n return { kind: 'omit', id: block.id };\n}\n\nfunction articleChromePreview(\n document: Document2Node,\n uiLocale: ButexUiLocale,\n previewOptions: Document2PreviewOptions,\n): PreviewBlock2[] {\n const meta = document.meta ?? emptyDocument2Meta();\n const blocks: PreviewBlock2[] = [\n { kind: 'basmala', id: 'article-basmala', text: BUTEX_BASMALA, tex: butexBasmalaDisplayTex() },\n ];\n if (document2HasMaketitle(meta)) {\n blocks.push({\n kind: 'titleBlock',\n id: 'article-title',\n ...(meta.title.trim().length > 0 ? { title: meta.title.trim() } : {}),\n ...(meta.authors.trim().length > 0 ? { authors: meta.authors.trim() } : {}),\n date: formatHijriDate(meta.date, {\n locale: uiLocale,\n digitForm: previewOptions.digitForm,\n }),\n });\n }\n if (document2HasAbstract(meta)) {\n blocks.push({ kind: 'abstract', id: 'article-abstract', text: meta.abstract.trim() });\n }\n return blocks;\n}\n\nexport function document2Preview(\n document: Document2Node,\n output: Document2MathOutput = 'svg',\n equationSide: EditorSide = 'arabic',\n previewOptions: Document2PreviewOptions = {},\n): Document2Preview {\n const mathIslands: MathIsland2[] = [];\n const options: Document2PreviewOptions = {\n documentDirection: previewOptions.documentDirection ?? 'rtl',\n digitForm:\n previewOptions.digitForm ??\n (previewOptions.documentDirection === 'ltr' ? 'western' : 'arabicIndic'),\n uiLocale: previewOptions.uiLocale ?? 'ar',\n };\n const body = document.blocks.map((block) => blockPreview(block, mathIslands, output, equationSide, document, options));\n return {\n blocks: [\n ...articleChromePreview(document, options.uiLocale ?? 'ar', options),\n ...body,\n { kind: 'closing', id: 'article-closing', text: BUTEX_CLOSING_HAMDALA, tex: butexMaghribiDisplayTex(BUTEX_CLOSING_HAMDALA) },\n ],\n mathIslands,\n };\n}\n"],"mappings":"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","names":["value","node","parseChain","document","isObject","nextId","scripts","document","block","textStylesEqual","reference","document","document","document"]}
1
+ {"version":3,"sources":["../src/document2/ids.ts","../src/editor/digits.ts","../src/document2/articleMeta.ts","../src/document2/citations.ts","../src/ast/commands/index.ts","../src/ast/arabic_ast.ts","../src/document/mathObject.ts","../src/document2/labels.ts","../src/document2/inlineScanner.ts","../src/document2/importJson.ts","../src/editor/accentCommands.ts","../src/editor/atomicCommands.ts","../src/editor/atomicCommandsOperators.ts","../src/editor/factory.ts","../src/editor/characterFonts.ts","../src/editor/divideOperator.ts","../src/editor/render.ts","../src/editor/state.ts","../src/editor/display/delimiter.ts","../src/editor/display/frac.ts","../src/editor/display/sqrt.ts","../src/editor/display/overset.ts","../src/editor/display/underset.ts","../src/editor/display/accent.ts","../src/editor/display/env.ts","../src/diwani-font.ts","../src/editor/display/atomicCommand.ts","../src/editor/display/atomicCommandsOperators.ts","../src/editor/styles.ts","../src/document/normalizeCharImport.ts","../src/document/mathEditorAdapter.ts","../src/document2/mathBridge.ts","../src/document2/commands.ts","../src/document2/exportJson.ts","../src/document2/jsonCommands.ts","../src/document2/outline.ts","../src/document2/keys.ts","../src/document2/arabicPreamble.ts","../src/document2/exportLatex.ts","../src/document2/history.ts","../src/document2/blockSelection.ts","../src/document2/previewModel.ts"],"sourcesContent":["let nextId = 1;\nconst instanceId = `${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;\n\nexport function document2Id(prefix: string): string {\n const id = `${prefix}_${instanceId}_${String(nextId)}`;\n nextId += 1;\n return id;\n}\n","import type { DigitFormId } from './types.js';\n\nconst WESTERN = '0123456789';\nconst ARABIC_INDIC = '٠١٢٣٤٥٦٧٨٩';\nconst PERSIAN_INDIC = '۰۱۲۳۴۵۶۷۸۹';\n\nconst digitSets: Record<DigitFormId, string> = {\n western: WESTERN,\n arabicIndic: ARABIC_INDIC,\n persianIndic: PERSIAN_INDIC,\n};\n\nfunction digitValue(char: string): number {\n const western = WESTERN.indexOf(char);\n if (western >= 0) {\n return western;\n }\n const arabicIndic = ARABIC_INDIC.indexOf(char);\n if (arabicIndic >= 0) {\n return arabicIndic;\n }\n return PERSIAN_INDIC.indexOf(char);\n}\n\nexport function formatDigits(value: string, digitForm: DigitFormId = 'western'): string {\n const target = digitSets[digitForm];\n return Array.from(value, (char) => {\n const value = digitValue(char);\n return value >= 0 ? target[value] : char;\n }).join('');\n}\n","import { formatDigits } from '../editor/digits.js';\nimport type { DigitFormId } from '../editor/types.js';\nimport type { ButexUiLocale } from '../uiLocale.js';\nimport type { Document2HijriDate, Document2Meta, HijriMonthId } from './types.js';\n\nexport const BUTEX_BASMALA_LINE1 = 'بِسْمِ ٱللَّٰهِ ٱلرَّحْمَٰنِ ٱلرَّحِيمِ';\n\nexport const BUTEX_BASMALA_LINE2 = 'وَٱلصَّلَاةُ وَٱلسَّلَامُ عَلَىٰ رَسُولِ ٱللَّٰهِ';\n\nexport const BUTEX_BASMALA_SALAWAT = 'صَلَّى ٱللَّهُ عَلَيْهِ وَسَلَّمَ';\n\n/** Three-line basmala joined for UI / plain-text matchers. */\nexport const BUTEX_BASMALA = `${BUTEX_BASMALA_LINE1}\\n${BUTEX_BASMALA_LINE2}\\n${BUTEX_BASMALA_SALAWAT}`;\n\nexport const BUTEX_CLOSING_HAMDALA = 'الْحَمْدُ لِلَّهِ نَفَعَنَا بِعِلْمِهِ';\n\nfunction escapeButexTextArg(text: string): string {\n return text.replace(/\\\\/g, '\\\\textbackslash{}').replace(/[{}]/g, '\\\\$&');\n}\n\nfunction butexFontDisplayTex(macro: '\\\\butexdiwani' | '\\\\butexmaghribi', text: string): string {\n return `${macro}{${escapeButexTextArg(text)}}`;\n}\n\n/** Display-math body using BuTeX Diwani (for MathJax preview islands). */\nexport function butexDiwaniDisplayTex(text: string): string {\n return butexFontDisplayTex('\\\\butexdiwani', text);\n}\n\n/** Full display equation for XeLaTeX export. */\nexport function butexDiwaniDisplayLatex(text: string): string {\n return `\\\\[\\n${butexDiwaniDisplayTex(text)}\\n\\\\]`;\n}\n\n/** Display-math body using BuTeX Maghribi (for document chrome). */\nexport function butexMaghribiDisplayTex(text: string): string {\n return butexFontDisplayTex('\\\\butexmaghribi', text);\n}\n\n/** Full display equation using BuTeX Maghribi for XeLaTeX export. */\nexport function butexMaghribiDisplayLatex(text: string): string {\n return `\\\\[\\n${butexMaghribiDisplayTex(text)}\\n\\\\]`;\n}\n\nconst BASMALA_LINES = [BUTEX_BASMALA_LINE1, BUTEX_BASMALA_LINE2, BUTEX_BASMALA_SALAWAT] as const;\n\n/** Three-line Maghribi body for MathJax basmala islands. */\nexport function butexBasmalaDisplayTex(): string {\n return BASMALA_LINES.map((line) => butexMaghribiDisplayTex(line)).join(' \\\\\\\\ ');\n}\n\n/** Standalone display equation when there is no \\\\maketitle (title-less docs). */\nexport function butexBasmalaDisplayLatex(): string {\n return `\\\\[\\n\\\\begin{gathered}\\n${BASMALA_LINES.map((line) => butexMaghribiDisplayTex(line)).join(' \\\\\\\\\\n')}\\n\\\\end{gathered}\\n\\\\]`;\n}\n\n/**\n * Keep \\\\maketitle inside the current column when twocolumn is on.\n * Standard article otherwise does \\\\twocolumn[\\\\@maketitle] and spans both columns.\n * Call after titling so \\\\@maketitle still includes \\\\pretitle hooks.\n */\nexport function butexInColumnMaketitleHook(): string {\n return String.raw`\\makeatletter\n\\renewcommand{\\maketitle}{%\n \\par\n \\begingroup\n \\renewcommand\\thefootnote{\\@fnsymbol\\c@footnote}%\n \\def\\@makefnmark{\\rlap{\\@textsuperscript{\\normalfont\\@thefnmark}}}%\n \\long\\def\\@makefntext##1{\\parindent 1em\\noindent\n \\hb@xt@1.8em{\\hss\\@textsuperscript{\\normalfont\\@thefnmark}}##1}%\n \\@maketitle\n \\thispagestyle{plain}\\@thanks\n \\endgroup\n \\setcounter{footnote}{0}%\n \\global\\let\\thanks\\relax\n \\global\\let\\maketitle\\relax\n \\global\\let\\@maketitle\\relax\n \\global\\let\\@thanks\\@empty\n \\global\\let\\@author\\@empty\n \\global\\let\\@date\\@empty\n \\global\\let\\@title\\@empty\n \\global\\let\\title\\relax\n \\global\\let\\author\\relax\n \\global\\let\\date\\relax\n \\global\\let\\and\\relax\n}\n\\makeatother`;\n}\n\n/** Titling hooks so the basmala stays attached to the visible title. */\nexport function butexBasmalaTitlingPreamble(options: { twocolumn?: boolean } = {}): string {\n const lines = [\n '\\\\usepackage{titling}',\n '\\\\pretitle{%',\n ' \\\\begin{center}',\n ...BASMALA_LINES.map((line, index) => {\n const suffix = index < BASMALA_LINES.length - 1 ? '\\\\\\\\' : '';\n return ` ${butexMaghribiDisplayTex(line)}${suffix}`;\n }),\n ' \\\\par\\\\vspace{1.5em}',\n ' \\\\LARGE',\n '}',\n '\\\\posttitle{\\\\par\\\\end{center}}',\n ];\n if (options.twocolumn) {\n lines.push(butexInColumnMaketitleHook());\n }\n return lines.join('\\n');\n}\nexport const HIJRI_YEAR_MIN = 1400;\nexport const HIJRI_YEAR_MAX = 1500;\n\nexport const HIJRI_MONTH_IDS: HijriMonthId[] = [\n 'محرم',\n 'صفر',\n 'ربيع الأول',\n 'ربيع الآخر',\n 'جمادى الأولى',\n 'جمادى الآخرة',\n 'رجب',\n 'شعبان',\n 'رمضان',\n 'شوال',\n 'ذو القعدة',\n 'ذو الحجة',\n];\n\nconst HIJRI_MONTH_LABELS_EN: Record<HijriMonthId, string> = {\n محرم: 'Muharram',\n صفر: 'Safar',\n 'ربيع الأول': 'Rabiʻ I',\n 'ربيع الآخر': 'Rabiʻ II',\n 'جمادى الأولى': 'Jumada I',\n 'جمادى الآخرة': 'Jumada II',\n رجب: 'Rajab',\n شعبان: 'Shaʻban',\n رمضان: 'Ramadan',\n شوال: 'Shawwal',\n 'ذو القعدة': 'Dhul Qaʻdah',\n 'ذو الحجة': 'Dhul Hijjah',\n};\n\n/** Legacy Latin month ids from earlier drafts — accepted on import only. */\nconst LEGACY_LATIN_MONTH: Record<string, HijriMonthId> = {\n muharram: 'محرم',\n safar: 'صفر',\n rabiAwwal: 'ربيع الأول',\n rabiThani: 'ربيع الآخر',\n jumadaAwwal: 'جمادى الأولى',\n jumadaThani: 'جمادى الآخرة',\n rajab: 'رجب',\n shaban: 'شعبان',\n ramadan: 'رمضان',\n shawwal: 'شوال',\n dhulQadah: 'ذو القعدة',\n dhulHijjah: 'ذو الحجة',\n};\n\nexport const DEFAULT_HIJRI_DATE: Document2HijriDate = {\n day: 1,\n month: 'محرم',\n year: 1448,\n};\n\nexport function hijriMonthLabel(month: HijriMonthId, locale: ButexUiLocale = 'ar'): string {\n return locale === 'en' ? HIJRI_MONTH_LABELS_EN[month] : month;\n}\n\nexport function emptyDocument2Meta(): Document2Meta {\n return {\n title: '',\n authors: '',\n date: { ...DEFAULT_HIJRI_DATE },\n abstract: '',\n };\n}\n\nfunction clampInt(value: number, min: number, max: number): number {\n if (!Number.isFinite(value)) {\n return min;\n }\n return Math.min(max, Math.max(min, Math.trunc(value)));\n}\n\nfunction isHijriMonthId(value: unknown): value is HijriMonthId {\n return typeof value === 'string' && (HIJRI_MONTH_IDS as string[]).includes(value);\n}\n\nfunction resolveHijriMonthId(value: unknown): HijriMonthId {\n if (isHijriMonthId(value)) {\n return value;\n }\n if (typeof value === 'string' && value in LEGACY_LATIN_MONTH) {\n return LEGACY_LATIN_MONTH[value]!;\n }\n return DEFAULT_HIJRI_DATE.month;\n}\n\nexport function normalizeDocument2HijriDate(value: unknown): Document2HijriDate {\n if (typeof value !== 'object' || value === null) {\n return { ...DEFAULT_HIJRI_DATE };\n }\n const raw = value as Record<string, unknown>;\n const day = clampInt(typeof raw.day === 'number' ? raw.day : Number(raw.day), 1, 30);\n const year = clampInt(typeof raw.year === 'number' ? raw.year : Number(raw.year), HIJRI_YEAR_MIN, HIJRI_YEAR_MAX);\n const month = resolveHijriMonthId(raw.month);\n return { day, month, year };\n}\n\nexport function normalizeDocument2Meta(value: unknown): Document2Meta {\n if (typeof value !== 'object' || value === null) {\n return emptyDocument2Meta();\n }\n const raw = value as Record<string, unknown>;\n return {\n title: typeof raw.title === 'string' ? raw.title : '',\n authors: typeof raw.authors === 'string' ? raw.authors : '',\n date: normalizeDocument2HijriDate(raw.date),\n abstract: typeof raw.abstract === 'string' ? raw.abstract : '',\n };\n}\n\nexport type Document2MetaProp = Partial<Omit<Document2Meta, 'date'>> & {\n date?: Partial<Document2HijriDate>;\n};\n\n/** Prop fills gaps; JSON wins only when the key is present on the JSON object. */\nexport function mergeDocument2Meta(fromJson: unknown, fromProp?: Document2MetaProp): Document2Meta {\n const fromPropMeta: Document2Meta = {\n title: typeof fromProp?.title === 'string' ? fromProp.title : '',\n authors: typeof fromProp?.authors === 'string' ? fromProp.authors : '',\n abstract: typeof fromProp?.abstract === 'string' ? fromProp.abstract : '',\n date: fromProp?.date\n ? normalizeDocument2HijriDate({ ...DEFAULT_HIJRI_DATE, ...fromProp.date })\n : { ...DEFAULT_HIJRI_DATE },\n };\n if (typeof fromJson !== 'object' || fromJson === null) {\n return fromPropMeta;\n }\n const json = fromJson as Record<string, unknown>;\n return {\n title: 'title' in json && typeof json.title === 'string' ? json.title : fromPropMeta.title,\n authors: 'authors' in json && typeof json.authors === 'string' ? json.authors : fromPropMeta.authors,\n abstract: 'abstract' in json && typeof json.abstract === 'string' ? json.abstract : fromPropMeta.abstract,\n date: 'date' in json ? normalizeDocument2HijriDate(json.date) : fromPropMeta.date,\n };\n}\n\n/** For live Document2Node meta: prop fills empty title/authors/abstract; date patch merges. */\nexport function fillDocument2MetaGaps(current: Document2Meta, fromProp?: Document2MetaProp): Document2Meta {\n if (!fromProp) {\n return cloneDocument2Meta(current);\n }\n return {\n title: current.title.trim().length > 0 ? current.title : typeof fromProp.title === 'string' ? fromProp.title : current.title,\n authors:\n current.authors.trim().length > 0\n ? current.authors\n : typeof fromProp.authors === 'string'\n ? fromProp.authors\n : current.authors,\n abstract:\n current.abstract.trim().length > 0\n ? current.abstract\n : typeof fromProp.abstract === 'string'\n ? fromProp.abstract\n : current.abstract,\n date: fromProp.date\n ? normalizeDocument2HijriDate({ ...current.date, ...fromProp.date })\n : { ...current.date },\n };\n}\n\nexport function document2HasMaketitle(meta: Document2Meta): boolean {\n return meta.title.trim().length > 0 || meta.authors.trim().length > 0;\n}\n\nexport function document2HasAbstract(meta: Document2Meta): boolean {\n return meta.abstract.trim().length > 0;\n}\n\nexport function document2HasTitleStack(meta: Document2Meta): boolean {\n return document2HasMaketitle(meta) || document2HasAbstract(meta);\n}\n\nexport type FormatHijriDateOptions = {\n locale?: ButexUiLocale;\n digitForm?: DigitFormId;\n};\n\nexport function formatHijriDate(date: Document2HijriDate, options: FormatHijriDateOptions | ButexUiLocale = 'ar'): string {\n const opts: FormatHijriDateOptions = typeof options === 'string' ? { locale: options } : options;\n const locale = opts.locale ?? 'ar';\n const digitForm: DigitFormId =\n opts.digitForm ?? (locale === 'en' ? 'western' : 'arabicIndic');\n const month = hijriMonthLabel(date.month, locale);\n const day = formatDigits(String(date.day), digitForm);\n const year = formatDigits(String(date.year), digitForm);\n if (locale === 'en') {\n return `${day} ${month} ${year} AH`;\n }\n return `${day} ${month} ${year}هـ`;\n}\n\nexport function cloneDocument2Meta(meta: Document2Meta): Document2Meta {\n return {\n title: meta.title,\n authors: meta.authors,\n date: { ...meta.date },\n abstract: meta.abstract,\n };\n}\n","import { formatDigits } from '../editor/digits.js';\nimport type { DigitFormId } from '../editor/types.js';\nimport type { FormatCiteLabelOptions, Reference2, Reference2Json, ReferenceFieldSeparator } from './types.js';\nimport { document2Id } from './ids.js';\n\nexport const DEFAULT_REFERENCE_FIELD_SEPARATOR: ReferenceFieldSeparator = '،';\n\nexport function normalizeReferenceFieldSeparator(value: unknown): ReferenceFieldSeparator {\n return value === ',' ? ',' : DEFAULT_REFERENCE_FIELD_SEPARATOR;\n}\n\nexport function referenceNumberMap(references: Array<Pick<Reference2, 'key'>>): Map<string, number> {\n const map = new Map<string, number>();\n references.forEach((reference, index) => {\n if (!map.has(reference.key)) {\n map.set(reference.key, index + 1);\n }\n });\n return map;\n}\n\nexport function resolveCiteNumbers(keys: string[], references: Array<Pick<Reference2, 'key'>>): Array<number | null> {\n const map = referenceNumberMap(references);\n return keys.map((key) => map.get(key) ?? null);\n}\n\nexport function formatCiteLabel(\n keys: string[],\n references: Array<Pick<Reference2, 'key'>>,\n options: FormatCiteLabelOptions = {},\n): string {\n const documentDirection = options.documentDirection ?? 'rtl';\n const digitForm: DigitFormId = options.digitForm ?? (documentDirection === 'rtl' ? 'arabicIndic' : 'western');\n const numbers = resolveCiteNumbers(keys, references).map((value) => (value === null ? '?' : String(value)));\n const display = documentDirection === 'rtl' ? [...numbers].reverse() : numbers;\n const separator = documentDirection === 'rtl' ? '،' : ', ';\n const body = display.map((part) => formatDigits(part, digitForm)).join(separator);\n return `[${body}]`;\n}\n\nexport function formatBibliographyNumber(index: number, options: FormatCiteLabelOptions = {}): string {\n const documentDirection = options.documentDirection ?? 'rtl';\n const digitForm: DigitFormId = options.digitForm ?? (documentDirection === 'rtl' ? 'arabicIndic' : 'western');\n return formatDigits(String(index), digitForm);\n}\n\nexport function parseCiteKeys(source: string): string[] {\n const match = /^\\\\cite\\{([^}]*)\\}$/.exec(source.trim());\n if (!match) {\n return [];\n }\n return (match[1] ?? '')\n .split(',')\n .map((key) => key.trim())\n .filter((key) => key.length > 0);\n}\n\nexport function citeTokenLatex(keys: string[]): string {\n return `\\\\cite{${keys.join(',')}}`;\n}\n\nexport function referenceFromJson(json: Reference2Json): Reference2 {\n return {\n id: document2Id('ref'),\n key: json.key,\n authors: typeof json.authors === 'string' ? json.authors : '',\n title: typeof json.title === 'string' ? json.title : '',\n year: typeof json.year === 'string' ? json.year : '',\n url: typeof json.url === 'string' ? json.url : '',\n venue: typeof json.venue === 'string' ? json.venue : '',\n fieldSeparator: normalizeReferenceFieldSeparator(json.field_separator),\n };\n}\n\nexport function createEmptyReference2(partial: Partial<Reference2Json> = {}): Reference2 {\n return referenceFromJson({\n key: partial.key ?? `ref${String(Date.now()).slice(-4)}`,\n authors: partial.authors,\n title: partial.title,\n year: partial.year,\n url: partial.url,\n venue: partial.venue,\n field_separator: partial.field_separator,\n });\n}\n\n/** Joined authors/title/venue/year for preview and export (no \\\\bibitem wrapper). */\nexport function bibliographyEntryBody(\n reference: Pick<Reference2, 'authors' | 'title' | 'venue' | 'year' | 'fieldSeparator'>,\n separator: ReferenceFieldSeparator = reference.fieldSeparator,\n options: { digitForm?: DigitFormId } = {},\n): string {\n const year =\n options.digitForm !== undefined ? formatDigits(reference.year, options.digitForm) : reference.year;\n const parts = [reference.authors, reference.title, reference.venue, year].filter((part) => part.trim().length > 0);\n return parts.join(`${separator} `);\n}\n\nexport function bibliographyEntryLatex(reference: Reference2): string {\n const body = bibliographyEntryBody(reference);\n const url = reference.url.trim().length > 0 ? ` \\\\url{${reference.url}}` : '';\n return `\\\\bibitem{${reference.key}} ${body}${url}`.trim();\n}\n\n/**\n * Build an href for a bibliography URL. Values without a scheme become https://…\n * so the browser does not resolve them against the editor origin (e.g. localhost).\n * Leaves http(s)/mailto/ftp and other schemed URLs unchanged. Empty → ''.\n */\nexport function absoluteHttpHref(url: string): string {\n const trimmed = url.trim();\n if (trimmed.length === 0) {\n return '';\n }\n if (/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(trimmed)) {\n return trimmed;\n }\n if (trimmed.startsWith('//')) {\n return `https:${trimmed}`;\n }\n return `https://${trimmed}`;\n}\n","import type { ChainNode } from '../arabic_ast.js';\n\ntype CommandRenderContext = {\n name: string;\n optionalArgs: ChainNode[];\n mandatoryArgs: ChainNode[];\n renderChain: (chain: ChainNode) => string;\n};\n\nexport function renderCommandCore(context: CommandRenderContext): string {\n const optional = context.optionalArgs.map((arg) => `[${context.renderChain(arg)}]`).join('');\n const mandatory = context.mandatoryArgs.map((arg) => `{${context.renderChain(arg)}}`).join('');\n return context.name + optional + mandatory;\n}\n","import { renderCommandCore } from './commands/index.js';\n\nexport type ArabicNodeJson = {\n node_type: string;\n expr?: string;\n name?: string;\n superscript?: ChainJson | null;\n subscript?: ChainJson | null;\n left_delim_expr?: string;\n right_delim_expr?: string;\n inner_expr?: ChainJson;\n optional_args?: ChainJson[];\n mandatory_args?: ChainJson[];\n opening?: string;\n closing?: string;\n lines?: ChainJson[];\n};\n\nexport type ChainJson = {\n node_type: 'ChainClass';\n chain: ArabicNodeJson[];\n};\n\nexport class State {\n // Empty for now, like the Python State placeholder used by BaseNode.\n}\n\nexport class BaseAstNode {\n state: State;\n superscript: ChainNode | null;\n subscript: ChainNode | null;\n nodeType: string;\n\n constructor(state: State | null = null) {\n if (state === null) {\n state = new State();\n }\n\n this.state = state;\n this.superscript = null;\n this.subscript = null;\n this.nodeType = this.constructor.name;\n }\n\n latex(): string {\n throw new Error('NotImplementedError');\n }\n\n arabicLatex(): string {\n throw new Error('NotImplementedError');\n }\n\n toArabicLatex(): string {\n return this.arabicLatex();\n }\n\n /** Latin-style scripts: `^{...}` and `_{...}` for english_json rendering. */\n latexScripts(): string {\n let s = '';\n\n if (this.superscript !== null) {\n s += '^{' + this.superscript.latex() + '}';\n }\n\n if (this.subscript !== null) {\n s += '_{' + this.subscript.latex() + '}';\n }\n\n return s;\n }\n\n /**\n * Arabic scripts use \\\\prescript{sup}{sub}{content} (matches reference Python output).\n * Call with rendered strings for sup/sub chains (may be empty strings).\n */\n arabicLatexScripts(sup: string, sub: string, content: string): string {\n if (sup !== '' || sub !== '') {\n return '\\\\prescript{' + sup + '}{' + sub + '}{' + content + '}';\n }\n return content;\n }\n}\n\nexport class ChainNode {\n chain: BaseAstNode[];\n\n constructor(chain: BaseAstNode[] = []) {\n this.chain = chain;\n }\n\n latex(): string {\n return this.chain.map((node) => node.latex()).join(' ');\n }\n toEnglishLatex(): string {\n return this.chain.map((node) => node.latex()).join(' ');\n }\n /** RTL: reverse order relative to Latin chain (see test/ref_tests.txt). */\n arabicLatex(): string {\n const reversed = this.chain.slice().reverse();\n return reversed.map((node) => node.arabicLatex()).join(' ');\n }\n\n toArabicLatex(): string {\n return this.arabicLatex();\n }\n}\n\nexport class NumberNode extends BaseAstNode {\n expr: string;\n\n constructor(expr: string, state: State | null = null) {\n super(state);\n this.nodeType = 'NumberObject';\n this.expr = expr;\n }\n\n latex(): string {\n return this.expr + this.latexScripts();\n }\n\n arabicLatex(): string {\n const sup = this.superscript !== null ? this.superscript.arabicLatex() : '';\n const sub = this.subscript !== null ? this.subscript.arabicLatex() : '';\n return this.arabicLatexScripts(sup, sub, this.expr);\n }\n}\n\nexport class CharNode extends BaseAstNode {\n expr: string;\n\n constructor(expr: string, state: State | null = null) {\n super(state);\n this.nodeType = 'CharObject';\n this.expr = expr;\n }\n\n latex(): string {\n return this.expr + this.latexScripts();\n }\n\n arabicLatex(): string {\n const sup = this.superscript !== null ? this.superscript.arabicLatex() : '';\n const sub = this.subscript !== null ? this.subscript.arabicLatex() : '';\n return this.arabicLatexScripts(sup, sub, this.expr);\n }\n}\n\n/**\n * Operator leaf: value comes from JSON as-is (English or Arabic side already chosen by the service).\n * Scripts are not appended (Python parity).\n */\nexport class OperatorNode extends BaseAstNode {\n expr: string;\n\n constructor(expr: string, state: State | null = null) {\n super(state);\n this.nodeType = 'OperatorObject';\n this.expr = expr;\n }\n\n latex(): string {\n return this.expr;\n }\n\n arabicLatex(): string {\n return this.expr;\n }\n}\n\nexport class DelimiterNode extends BaseAstNode {\n leftDelimExpr: string;\n innerExpr: ChainNode;\n rightDelimExpr: string;\n\n constructor(leftDelimExpr: string, innerExpr: ChainNode, rightDelimExpr: string, state: State | null = null) {\n super(state);\n this.nodeType = 'DelimiterObject';\n this.leftDelimExpr = leftDelimExpr;\n this.innerExpr = innerExpr;\n this.rightDelimExpr = rightDelimExpr;\n }\n\n latex(): string {\n return this.leftDelimExpr + this.innerExpr.latex() + this.rightDelimExpr + this.latexScripts();\n }\n\n arabicLatex(): string {\n const sup = this.superscript !== null ? this.superscript.arabicLatex() : '';\n const sub = this.subscript !== null ? this.subscript.arabicLatex() : '';\n const content = this.leftDelimExpr + this.innerExpr.arabicLatex() + this.rightDelimExpr;\n return this.arabicLatexScripts(sup, sub, content);\n }\n}\n\nexport class CommandNode extends BaseAstNode {\n name: string;\n optionalArgs: ChainNode[];\n mandatoryArgs: ChainNode[];\n\n constructor(\n name: string,\n optionalArgs: ChainNode[] = [],\n mandatoryArgs: ChainNode[] = [],\n state: State | null = null\n ) {\n super(state);\n this.nodeType = 'CommandObject';\n this.name = name;\n this.optionalArgs = optionalArgs;\n this.mandatoryArgs = mandatoryArgs;\n }\n\n latex(): string {\n const content = renderCommandCore({\n name: this.name,\n optionalArgs: this.optionalArgs,\n mandatoryArgs: this.mandatoryArgs,\n renderChain: (chain) => chain.latex(),\n });\n return content + this.latexScripts();\n }\n\n arabicLatex(): string {\n const sup = this.superscript !== null ? this.superscript.arabicLatex() : '';\n const sub = this.subscript !== null ? this.subscript.arabicLatex() : '';\n const arabicName =\n this.name === '\\\\sqrt' || this.name === '\\\\arabsqrt' ? '\\\\arsqrt' : this.name;\n const content = renderCommandCore({\n name: arabicName,\n optionalArgs: this.optionalArgs,\n mandatoryArgs: this.mandatoryArgs,\n renderChain: (chain) => chain.arabicLatex(),\n });\n return this.arabicLatexScripts(sup, sub, content);\n }\n}\n\nexport class EnvNode extends BaseAstNode {\n opening: string;\n lines: ChainNode[];\n closing: string;\n\n constructor(opening: string, lines: ChainNode[] = [], closing: string, state: State | null = null) {\n super(state);\n this.nodeType = 'EnvObject';\n this.opening = opening;\n this.lines = lines;\n this.closing = closing;\n }\n\n latex(): string {\n if (this.lines.length === 0) {\n return this.opening + this.closing + this.latexScripts();\n }\n\n const formattedLines = this.lines.map((line) => ` ${line.latex()}`);\n const content = formattedLines.join(' \\\\\\\\' + '\\n');\n return `${this.opening}\\n${content}\\n${this.closing}` + this.latexScripts();\n }\n\n arabicLatex(): string {\n const sup = this.superscript !== null ? this.superscript.arabicLatex() : '';\n const sub = this.subscript !== null ? this.subscript.arabicLatex() : '';\n\n if (this.lines.length === 0) {\n return this.arabicLatexScripts(sup, sub, this.opening + this.closing);\n }\n\n const formattedLines = this.lines.map((line) => ` ${line.arabicLatex()}`);\n const content = formattedLines.join(' \\\\\\\\' + '\\n');\n const fullContent = `${this.opening}\\n${content}\\n${this.closing}`;\n return this.arabicLatexScripts(sup, sub, fullContent);\n }\n}\n\ntype ParseMode = 'english' | 'arabic';\n\nfunction parseScripts(node: BaseAstNode, json: ArabicNodeJson, mode: ParseMode): void {\n if (json.superscript) {\n node.superscript = parseChain(json.superscript, mode);\n }\n\n if (json.subscript) {\n node.subscript = parseChain(json.subscript, mode);\n }\n}\n\nfunction parseNode(json: ArabicNodeJson, mode: ParseMode): BaseAstNode {\n if (json.node_type === 'DelimiterObject') {\n const node = parseDelimiter(json, mode);\n parseScripts(node, json, mode);\n return node;\n }\n\n if (json.node_type === 'OperatorObject') {\n if (typeof json.expr !== 'string') {\n throw new Error('OperatorObject requires string expr');\n }\n const node = new OperatorNode(json.expr);\n parseScripts(node, json, mode);\n return node;\n }\n\n if (json.node_type === 'CommandObject') {\n const node = parseCommand(json, mode);\n parseScripts(node, json, mode);\n return node;\n }\n\n if (json.node_type === 'EnvObject') {\n const node = parseEnv(json, mode);\n parseScripts(node, json, mode);\n return node;\n }\n\n if (typeof json.expr !== 'string') {\n throw new Error(`${json.node_type} requires string expr`);\n }\n\n let node: BaseAstNode;\n\n if (json.node_type === 'NumberObject') {\n node = new NumberNode(json.expr);\n } else if (json.node_type === 'CharObject') {\n node = new CharNode(json.expr);\n } else {\n throw new Error(`Unsupported node_type: ${json.node_type}`);\n }\n\n parseScripts(node, json, mode);\n return node;\n}\n\nfunction parseDelimiter(json: ArabicNodeJson, mode: ParseMode): DelimiterNode {\n if (typeof json.left_delim_expr !== 'string') {\n throw new Error('DelimiterObject requires string left_delim_expr');\n }\n\n if (!json.inner_expr || json.inner_expr.node_type !== 'ChainClass') {\n throw new Error('DelimiterObject requires ChainClass inner_expr');\n }\n\n if (typeof json.right_delim_expr !== 'string') {\n throw new Error('DelimiterObject requires string right_delim_expr');\n }\n\n const innerExpr = parseChain(json.inner_expr, mode);\n return new DelimiterNode(json.left_delim_expr, innerExpr, json.right_delim_expr);\n}\n\nfunction parseCommand(json: ArabicNodeJson, mode: ParseMode): CommandNode {\n if (typeof json.name !== 'string') {\n throw new Error('CommandObject requires string name');\n }\n\n const optionalJson = Array.isArray(json.optional_args) ? json.optional_args : [];\n const mandatoryJson = Array.isArray(json.mandatory_args) ? json.mandatory_args : [];\n const optionalArgs = optionalJson.map((arg) => parseChain(arg, mode));\n const mandatoryArgs = mandatoryJson.map((arg) => parseChain(arg, mode));\n\n return new CommandNode(json.name, optionalArgs, mandatoryArgs);\n}\n\nfunction parseEnv(json: ArabicNodeJson, mode: ParseMode): EnvNode {\n if (typeof json.opening !== 'string') {\n throw new Error('EnvObject requires string opening');\n }\n\n if (typeof json.closing !== 'string') {\n throw new Error('EnvObject requires string closing');\n }\n\n if (!Array.isArray(json.lines)) {\n throw new Error('EnvObject requires lines array');\n }\n\n const lines = json.lines.map((line) => parseChain(line, mode));\n return new EnvNode(json.opening, lines, json.closing);\n}\n\nfunction parseChain(json: ChainJson, mode: ParseMode): ChainNode {\n if (json.node_type !== 'ChainClass') {\n throw new Error(`Expected ChainClass, got: ${json.node_type}`);\n }\n\n const nodes = json.chain.map((childJson) => parseNode(childJson, mode));\n return new ChainNode(nodes);\n}\n\n/** Import AST from Python english_dict JSON (Latin expr fields). */\nexport function fromEnglishJson(json: ChainJson | ArabicNodeJson): ChainNode | BaseAstNode {\n if (json.node_type === 'ChainClass') {\n return parseChain(json as ChainJson, 'english');\n }\n return parseNode(json, 'english');\n}\n\n/** Import AST from Python arabic_dict JSON (Arabic expr fields). Same shape as English; values differ. */\nexport function fromArabicJson(json: ChainJson | ArabicNodeJson): ChainNode | BaseAstNode {\n if (json.node_type === 'ChainClass') {\n return parseChain(json as ChainJson, 'arabic');\n }\n return parseNode(json, 'arabic');\n}\n","import {\n BaseAstNode,\n ChainNode,\n CharNode,\n CommandNode,\n DelimiterNode,\n EnvNode,\n NumberNode,\n OperatorNode,\n fromArabicJson,\n fromEnglishJson,\n type ArabicNodeJson,\n type ChainJson,\n} from '../ast/arabic_ast.js';\nimport type { DocumentParseMode, MathNode, MathObjectJson } from './types.js';\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nfunction isMathObjectJson(value: unknown): value is MathObjectJson {\n return isObject(value) && value.node_type === 'MathObject';\n}\n\nfunction assertChainNode(value: unknown): ChainNode {\n if (!(value instanceof ChainNode)) {\n throw new Error('MathObject lines must parse to ChainNode');\n }\n return value;\n}\n\nexport function fromMathObjectJson(json: unknown, mode: DocumentParseMode = 'english'): MathNode {\n if (!isMathObjectJson(json)) {\n throw new Error('MathObject requires node_type \"MathObject\"');\n }\n\n if (typeof json.math_mode !== 'string') {\n throw new Error('MathObject requires string math_mode');\n }\n\n if (typeof json.closing !== 'string') {\n throw new Error('MathObject requires string closing');\n }\n\n if (!Array.isArray(json.lines) || json.lines.length === 0) {\n throw new Error('MathObject requires non-empty lines array');\n }\n\n const parseChain = mode === 'arabic' ? fromArabicJson : fromEnglishJson;\n const lines = json.lines.map((line) => assertChainNode(parseChain(line)));\n\n return {\n nodeType: 'MathObject',\n mathMode: json.math_mode,\n lines,\n closing: json.closing,\n };\n}\n\nfunction scriptsToJson(node: BaseAstNode, path: string): Pick<ArabicNodeJson, 'superscript' | 'subscript'> {\n return {\n ...(node.superscript ? { superscript: chainToJson(node.superscript, `${path}.superscript`) } : {}),\n ...(node.subscript ? { subscript: chainToJson(node.subscript, `${path}.subscript`) } : {}),\n };\n}\n\nfunction nodeToJson(node: BaseAstNode, path: string): ArabicNodeJson {\n const scripts = scriptsToJson(node, path);\n if (node instanceof CharNode || node instanceof NumberNode || node instanceof OperatorNode) {\n return { node_type: node.nodeType, expr: node.expr, ...scripts };\n }\n if (node instanceof DelimiterNode) {\n return {\n node_type: 'DelimiterObject',\n left_delim_expr: node.leftDelimExpr,\n inner_expr: chainToJson(node.innerExpr, `${path}.inner_expr`),\n right_delim_expr: node.rightDelimExpr,\n ...scripts,\n };\n }\n if (node instanceof CommandNode) {\n return {\n node_type: 'CommandObject',\n name: node.name,\n optional_args: node.optionalArgs.map((arg, index) => chainToJson(arg, `${path}.optional_args[${String(index)}]`)),\n mandatory_args: node.mandatoryArgs.map((arg, index) => chainToJson(arg, `${path}.mandatory_args[${String(index)}]`)),\n ...scripts,\n };\n }\n if (node instanceof EnvNode) {\n return {\n node_type: 'EnvObject',\n opening: node.opening,\n lines: node.lines.map((line, index) => chainToJson(line, `${path}.lines[${String(index)}]`)),\n closing: node.closing,\n ...scripts,\n };\n }\n throw new Error(`Unsupported runtime math node at ${path}: ${node.nodeType}`);\n}\n\nfunction chainToJson(chain: ChainNode, path: string): ChainJson {\n if (!(chain instanceof ChainNode)) {\n throw new Error(`Expected live ChainNode at ${path}`);\n }\n return {\n node_type: 'ChainClass',\n chain: chain.chain.map((node, index) => nodeToJson(node, `${path}.chain[${String(index)}]`)),\n };\n}\n\nexport function toMathObjectJson(math: MathNode): MathObjectJson {\n if (math.nodeType !== 'MathObject' || !Array.isArray(math.lines) || math.lines.length === 0) {\n throw new Error('Cannot serialize invalid runtime MathObject');\n }\n return {\n node_type: 'MathObject',\n math_mode: math.mathMode,\n lines: math.lines.map((line, index) => chainToJson(line, `$.lines[${String(index)}]`)),\n closing: math.closing,\n };\n}\n\nexport function renderMathNodeLatex(math: MathNode): string {\n const lines = math.lines.map((line) => line.arabicLatex());\n\n if (math.mathMode === '$' || math.mathMode === '\\\\(') {\n return math.mathMode + lines.join(' ') + math.closing;\n }\n\n if (math.mathMode === '$$' || math.mathMode === '\\\\[') {\n if (lines.length === 1) {\n return math.mathMode + '\\n' + lines[0] + '\\n' + math.closing;\n }\n return math.mathMode + '\\n' + lines.map((line) => ` ${line}`).join(' \\\\\\\\\\n') + '\\n' + math.closing;\n }\n\n if (lines.length === 1) {\n return `${math.mathMode}\\n ${lines[0]}\\n${math.closing}`;\n }\n\n return `${math.mathMode}\\n${lines.map((line) => ` ${line}`).join(' \\\\\\\\\\n')}\\n${math.closing}`;\n}\n\nexport function isDisplayMathNode(math: MathNode): boolean {\n return math.mathMode === '$$' || math.mathMode === '\\\\[' || math.mathMode.startsWith('\\\\begin{');\n}\n","import { formatDigits } from '../editor/digits.js';\nimport type { DigitFormId } from '../editor/types.js';\nimport type { ButexUiLocale } from '../uiLocale.js';\nimport { formatBibliographyNumber } from './citations.js';\nimport type {\n Document2Block,\n Document2Direction,\n Document2Node,\n FormatCiteLabelOptions,\n ImageBlock2,\n InlineField2,\n MathToken2,\n TableBlock2,\n} from './types.js';\n\nexport type Document2LabelKind = 'fig' | 'tab' | 'eq';\n\nexport type Document2LabelEntry = {\n key: string;\n kind: Document2LabelKind;\n caption: string;\n /** Block id for fig/tab, or math token id for eq. */\n ownerId: string;\n number: number;\n};\n\nexport type FloatMetaPatch = {\n centered?: boolean;\n captionEnabled?: boolean;\n caption?: string;\n labelEnabled?: boolean;\n label?: string;\n};\n\nexport function defaultFloatMeta(): {\n centered: true;\n captionEnabled: false;\n caption: '';\n labelEnabled: false;\n label: '';\n} {\n return {\n centered: true,\n captionEnabled: false,\n caption: '',\n labelEnabled: false,\n label: '',\n };\n}\n\nexport function parseFloatMetaFromJson(json: {\n caption?: string;\n label?: string;\n caption_enabled?: boolean;\n label_enabled?: boolean;\n centered?: boolean;\n}): {\n centered: boolean;\n captionEnabled: boolean;\n caption: string;\n labelEnabled: boolean;\n label: string;\n} {\n const caption = typeof json.caption === 'string' ? json.caption : '';\n const label = typeof json.label === 'string' ? json.label : '';\n return {\n centered: json.centered !== false,\n captionEnabled: json.caption_enabled === true || (typeof json.caption_enabled !== 'boolean' && caption.length > 0),\n caption,\n labelEnabled: json.label_enabled === true || (typeof json.label_enabled !== 'boolean' && label.trim().length > 0),\n label,\n };\n}\n\nexport function parseRefKeys(source: string): { keys: string[]; refCommand: 'ref' | 'eqref' } {\n const eqref = /^\\\\eqref\\{([^}]*)\\}$/.exec(source.trim());\n if (eqref) {\n return {\n refCommand: 'eqref',\n keys: (eqref[1] ?? '')\n .split(',')\n .map((key) => key.trim())\n .filter((key) => key.length > 0),\n };\n }\n const ref = /^\\\\ref\\{([^}]*)\\}$/.exec(source.trim());\n if (ref) {\n return {\n refCommand: 'ref',\n keys: (ref[1] ?? '')\n .split(',')\n .map((key) => key.trim())\n .filter((key) => key.length > 0),\n };\n }\n return { keys: [], refCommand: 'ref' };\n}\n\nexport function refTokenLatex(keys: string[], refCommand: 'ref' | 'eqref'): string {\n const command = refCommand === 'eqref' ? '\\\\eqref' : '\\\\ref';\n return `${command}{${keys.join(',')}}`;\n}\n\n/** Collect enabled labels in document order, numbering per kind. */\nexport function collectDocument2Labels(document: Document2Node): Document2LabelEntry[] {\n const entries: Document2LabelEntry[] = [];\n const counters: Record<Document2LabelKind, number> = { fig: 0, tab: 0, eq: 0 };\n\n function pushEqFromField(tokens: MathToken2[] | InlineField2['tokens']): void {\n for (const token of tokens) {\n if (token.kind !== 'math') {\n continue;\n }\n if (token.display && token.labelEnabled && token.label && token.label.trim().length > 0) {\n counters.eq += 1;\n entries.push({\n key: token.label.trim(),\n kind: 'eq',\n caption: '',\n ownerId: token.id,\n number: counters.eq,\n });\n }\n }\n }\n\n function walk(blocks: Document2Block[]): void {\n for (const block of blocks) {\n if (block.kind === 'image' && block.labelEnabled && block.label.trim().length > 0) {\n counters.fig += 1;\n entries.push({\n key: block.label.trim(),\n kind: 'fig',\n caption: block.captionEnabled ? block.caption : '',\n ownerId: block.id,\n number: counters.fig,\n });\n }\n if (block.kind === 'table') {\n if (block.labelEnabled && block.label.trim().length > 0) {\n counters.tab += 1;\n entries.push({\n key: block.label.trim(),\n kind: 'tab',\n caption: block.captionEnabled ? block.caption : '',\n ownerId: block.id,\n number: counters.tab,\n });\n }\n for (const row of block.rows) {\n for (const cell of row) {\n pushEqFromField(cell.tokens);\n }\n }\n }\n if (block.kind === 'textBlock') {\n pushEqFromField(block.field.tokens);\n }\n if (block.kind === 'list') {\n for (const item of block.items) {\n pushEqFromField(item.field.tokens);\n walk(item.blocks);\n }\n }\n }\n }\n\n walk(document.blocks);\n return entries;\n}\n\nexport function labelNumberMap(document: Document2Node): Map<string, { kind: Document2LabelKind; number: number }> {\n const map = new Map<string, { kind: Document2LabelKind; number: number }>();\n for (const entry of collectDocument2Labels(document)) {\n if (!map.has(entry.key)) {\n map.set(entry.key, { kind: entry.kind, number: entry.number });\n }\n }\n return map;\n}\n\nexport type FormatFloatCaptionTitleOptions = {\n uiLocale?: ButexUiLocale;\n documentDirection?: Document2Direction;\n digitForm?: DigitFormId;\n};\n\n/** Localized numbered float/equation title: الشكل ١ / Figure 1 / المعادلة ١. */\nexport function formatFloatCaptionTitle(\n kind: Document2LabelKind,\n number: number,\n options: FormatFloatCaptionTitleOptions = {},\n): string {\n const locale = options.uiLocale ?? 'ar';\n const kindWord =\n kind === 'fig'\n ? locale === 'ar'\n ? 'الشكل'\n : 'Figure'\n : kind === 'tab'\n ? locale === 'ar'\n ? 'الجدول'\n : 'Table'\n : locale === 'ar'\n ? 'المعادلة'\n : 'Equation';\n const digits = formatBibliographyNumber(number, {\n documentDirection: options.documentDirection ?? (locale === 'ar' ? 'rtl' : 'ltr'),\n digitForm: options.digitForm ?? (locale === 'ar' ? 'arabicIndic' : 'western'),\n });\n return `${kindWord} ${digits}`;\n}\n\n/** Caption line as shown in document preview: الشكل ١: نص / Figure 1. text. */\nexport function formatFloatCaptionPreview(\n title: string,\n caption: string | undefined,\n uiLocale: ButexUiLocale = 'ar',\n): string {\n const trimmed = caption?.trim() ?? '';\n if (trimmed.length === 0) {\n return title;\n }\n const separator = uiLocale === 'ar' ? ': ' : '. ';\n return `${title}${separator}${trimmed}`;\n}\n\nexport function formatRefLabel(\n keys: string[],\n document: Document2Node,\n refCommand: 'ref' | 'eqref',\n options: FormatCiteLabelOptions = {},\n): string {\n const documentDirection: Document2Direction = options.documentDirection ?? 'rtl';\n const digitForm: DigitFormId = options.digitForm ?? (documentDirection === 'rtl' ? 'arabicIndic' : 'western');\n const map = labelNumberMap(document);\n const parts = keys.map((key) => {\n const hit = map.get(key);\n if (!hit) {\n return '?';\n }\n return formatDigits(String(hit.number), digitForm);\n });\n const body = parts.join(documentDirection === 'rtl' ? '،' : ', ');\n if (refCommand === 'eqref') {\n return `(${body})`;\n }\n return body;\n}\n\nexport function stripDisplayMathDelimiters(source: string): string {\n const trimmed = source.trim();\n if (trimmed.startsWith('\\\\[') && trimmed.endsWith('\\\\]')) {\n return trimmed.slice(2, -2).trim();\n }\n if (trimmed.startsWith('$$') && trimmed.endsWith('$$')) {\n return trimmed.slice(2, -2).trim();\n }\n if (trimmed.startsWith('\\\\begin{equation}') && trimmed.endsWith('\\\\end{equation}')) {\n return trimmed.slice('\\\\begin{equation}'.length, -'\\\\end{equation}'.length).trim();\n }\n return trimmed;\n}\n\nexport function applyFloatMetaPatch<T extends ImageBlock2 | TableBlock2>(block: T, patch: FloatMetaPatch): void {\n if (typeof patch.centered === 'boolean') {\n block.centered = patch.centered;\n }\n if (typeof patch.captionEnabled === 'boolean') {\n block.captionEnabled = patch.captionEnabled;\n }\n if (typeof patch.caption === 'string') {\n block.caption = patch.caption;\n }\n if (typeof patch.labelEnabled === 'boolean') {\n block.labelEnabled = patch.labelEnabled;\n }\n if (typeof patch.label === 'string') {\n block.label = patch.label;\n }\n}\n","import type { DetectedInlineSpan2, DetectedMathSpan2 } from './types.js';\nimport { parseCiteKeys } from './citations.js';\nimport { parseRefKeys } from './labels.js';\n\nconst MATH_ENVIRONMENTS = new Set([\n 'equation',\n 'equation*',\n 'align',\n 'align*',\n 'aligned',\n 'gather',\n 'gather*',\n 'multline',\n 'multline*',\n]);\n\nfunction isEscaped(value: string, index: number): boolean {\n let slashCount = 0;\n let i = index - 1;\n while (i >= 0 && value[i] === '\\\\') {\n slashCount += 1;\n i -= 1;\n }\n return slashCount % 2 === 1;\n}\n\nfunction findClosingDollar(value: string, start: number): number {\n let i = start;\n while (i < value.length) {\n if (value[i] === '$' && !isEscaped(value, i)) {\n return i;\n }\n i += 1;\n }\n return -1;\n}\n\nfunction environmentSpan(value: string, start: number): DetectedMathSpan2 | null {\n const match = /^\\\\begin\\{([A-Za-z*]+)\\}/.exec(value.slice(start));\n if (!match) {\n return null;\n }\n\n const envName = match[1] ?? '';\n if (!MATH_ENVIRONMENTS.has(envName)) {\n return null;\n }\n\n const opening = match[0] ?? '';\n const closing = `\\\\end{${envName}}`;\n const closingStart = value.indexOf(closing, start + opening.length);\n if (closingStart < 0) {\n return null;\n }\n\n const end = closingStart + closing.length;\n return { start, end, source: value.slice(start, end), opening, closing, display: true };\n}\n\nfunction citeSpan(value: string, start: number): DetectedInlineSpan2 | null {\n if (!value.startsWith('\\\\cite{', start) || isEscaped(value, start)) {\n return null;\n }\n const openBrace = start + '\\\\cite'.length;\n if (value[openBrace] !== '{') {\n return null;\n }\n let depth = 0;\n for (let i = openBrace; i < value.length; i += 1) {\n const char = value[i];\n if (char === '{' && !isEscaped(value, i)) {\n depth += 1;\n continue;\n }\n if (char === '}' && !isEscaped(value, i)) {\n depth -= 1;\n if (depth === 0) {\n const end = i + 1;\n const source = value.slice(start, end);\n return { kind: 'cite', start, end, source, keys: parseCiteKeys(source) };\n }\n }\n }\n return null;\n}\n\nfunction refSpan(value: string, start: number): DetectedInlineSpan2 | null {\n const eqrefPrefix = '\\\\eqref{';\n const refPrefix = '\\\\ref{';\n let refCommand: 'ref' | 'eqref' = 'ref';\n let prefix = refPrefix;\n if (value.startsWith(eqrefPrefix, start) && !isEscaped(value, start)) {\n refCommand = 'eqref';\n prefix = eqrefPrefix;\n } else if (value.startsWith(refPrefix, start) && !isEscaped(value, start)) {\n refCommand = 'ref';\n prefix = refPrefix;\n } else {\n return null;\n }\n\n const openBrace = start + prefix.length - 1;\n if (value[openBrace] !== '{') {\n return null;\n }\n let depth = 0;\n for (let i = openBrace; i < value.length; i += 1) {\n const char = value[i];\n if (char === '{' && !isEscaped(value, i)) {\n depth += 1;\n continue;\n }\n if (char === '}' && !isEscaped(value, i)) {\n depth -= 1;\n if (depth === 0) {\n const end = i + 1;\n const source = value.slice(start, end);\n const parsed = parseRefKeys(source);\n return { kind: 'ref', start, end, source, keys: parsed.keys, refCommand };\n }\n }\n }\n return null;\n}\n\nfunction mathSpanAt(value: string, i: number): DetectedMathSpan2 | null {\n if (value.startsWith('\\\\begin{', i)) {\n return environmentSpan(value, i);\n }\n\n if (value.startsWith('\\\\(', i)) {\n const close = value.indexOf('\\\\)', i + 2);\n if (close >= 0) {\n const end = close + 2;\n return { start: i, end, source: value.slice(i, end), opening: '\\\\(', closing: '\\\\)', display: false };\n }\n }\n\n if (value.startsWith('\\\\[', i)) {\n const close = value.indexOf('\\\\]', i + 2);\n if (close >= 0) {\n const end = close + 2;\n return { start: i, end, source: value.slice(i, end), opening: '\\\\[', closing: '\\\\]', display: true };\n }\n }\n\n if (value.startsWith('$$', i) && !isEscaped(value, i)) {\n const close = value.indexOf('$$', i + 2);\n if (close >= 0) {\n const end = close + 2;\n return { start: i, end, source: value.slice(i, end), opening: '$$', closing: '$$', display: true };\n }\n }\n\n if (value[i] === '$' && !isEscaped(value, i)) {\n const close = findClosingDollar(value, i + 1);\n if (close >= 0) {\n const end = close + 1;\n return { start: i, end, source: value.slice(i, end), opening: '$', closing: '$', display: false };\n }\n }\n\n return null;\n}\n\n/** Math-only spans (used for math_objects alignment counts). */\nexport function detectMathSpans2(value: string): DetectedMathSpan2[] {\n return detectInlineSpans2(value)\n .filter((span): span is DetectedInlineSpan2 & { kind: 'math' } => span.kind === 'math')\n .map(({ kind: _kind, ...span }) => span);\n}\n\n/** Left-to-right math + \\\\cite + \\\\ref/\\\\eqref spans without overlap. */\nexport function detectInlineSpans2(value: string): DetectedInlineSpan2[] {\n const spans: DetectedInlineSpan2[] = [];\n let i = 0;\n\n while (i < value.length) {\n const cite = citeSpan(value, i);\n if (cite) {\n spans.push(cite);\n i = cite.end;\n continue;\n }\n\n const ref = refSpan(value, i);\n if (ref) {\n spans.push(ref);\n i = ref.end;\n continue;\n }\n\n const math = mathSpanAt(value, i);\n if (math) {\n spans.push({ kind: 'math', ...math });\n i = math.end;\n continue;\n }\n\n i += 1;\n }\n\n return spans;\n}\n","import { fromMathObjectJson } from '../document/mathObject.js';\nimport { normalizeDocument2Meta, emptyDocument2Meta } from './articleMeta.js';\nimport { referenceFromJson } from './citations.js';\nimport { document2Id } from './ids.js';\nimport { detectInlineSpans2, detectMathSpans2 } from './inlineScanner.js';\nimport { parseFloatMetaFromJson } from './labels.js';\nimport type {\n BibliographyBlock2,\n Document2Block,\n Document2BlockJson,\n Document2Diagnostic,\n Document2MathObjectJson,\n Document2ListItemJson,\n Document2Node,\n Document2ParseMode,\n ImageBlock2,\n ImportDocument2Options,\n InlineField2,\n InlineToken2,\n ListBlock2,\n ListItem2,\n RawBlock2,\n Reference2,\n Reference2Json,\n TableBlock2,\n TextFormatSpan2Json,\n TextStyle2,\n TextBlock2,\n} from './types.js';\n\nconst TEXT_COMMANDS = new Set(['\\\\section', '\\\\subsection', '\\\\subsubsection', '\\\\paragraph']);\nconst LIST_COMMANDS = new Set(['\\\\begin{itemize}', '\\\\begin{enumerate}']);\n\ntype BlockIdState = {\n used: Set<string>;\n};\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nfunction requireString(value: unknown, message: string): string {\n if (typeof value !== 'string') {\n throw new Error(message);\n }\n return value;\n}\n\nfunction isRecordOfStrings(value: unknown): value is Record<string, string> {\n return isObject(value) && Object.values(value).every((entry) => typeof entry === 'string');\n}\n\nfunction asBlockJson(value: unknown): Document2BlockJson {\n if (!isObject(value)) {\n throw new Error('Document block must be an object');\n }\n if (typeof value.command !== 'string') {\n throw new Error('Document block requires string command');\n }\n return value as Document2BlockJson;\n}\n\nfunction blockIdFromJson(json: Document2BlockJson, state: BlockIdState): string {\n const imported = typeof json.id === 'string' ? json.id.trim() : '';\n if (imported.length > 0 && !state.used.has(imported)) {\n state.used.add(imported);\n return imported;\n }\n\n let generated = document2Id('block');\n while (state.used.has(generated)) {\n generated = document2Id('block');\n }\n state.used.add(generated);\n return generated;\n}\n\nfunction pushDiagnostic(diagnostics: Document2Diagnostic[], options: ImportDocument2Options, path: string, message: string): void {\n if (options.strict) {\n throw new Error(message);\n }\n diagnostics.push({ code: 'math_alignment', message, path });\n}\n\nfunction parseReferences(json: unknown): Reference2[] {\n if (!Array.isArray(json)) {\n return [];\n }\n const references: Reference2[] = [];\n for (const entry of json) {\n if (!isObject(entry) || typeof entry.key !== 'string' || entry.key.trim().length === 0) {\n continue;\n }\n references.push(\n referenceFromJson({\n key: entry.key.trim(),\n authors: typeof entry.authors === 'string' ? entry.authors : undefined,\n title: typeof entry.title === 'string' ? entry.title : undefined,\n year: typeof entry.year === 'string' ? entry.year : undefined,\n url: typeof entry.url === 'string' ? entry.url : undefined,\n venue: typeof entry.venue === 'string' ? entry.venue : undefined,\n field_separator:\n entry.field_separator === ',' || entry.field_separator === '،'\n ? entry.field_separator\n : undefined,\n } satisfies Reference2Json),\n );\n }\n return references;\n}\n\nexport function createInlineField2(\n value = '',\n mathObjects: Array<Document2MathObjectJson | null> = [],\n options: ImportDocument2Options = {},\n path = '$',\n diagnostics: Document2Diagnostic[] = [],\n formats: TextFormatSpan2Json[] = [],\n): InlineField2 {\n const mode: Document2ParseMode = options.mode ?? 'english';\n const spans = detectInlineSpans2(value);\n const mathSpans = spans.filter((span) => span.kind === 'math');\n const tokens: InlineToken2[] = [];\n let index = 0;\n let mathObjectIndex = 0;\n\n if (mathObjects.length > 0 && mathObjects.length !== mathSpans.length) {\n pushDiagnostic(diagnostics, options, path, `math_objects count mismatch: detected ${String(mathSpans.length)}, got ${String(mathObjects.length)}`);\n }\n\n for (const span of spans) {\n if (span.start > index) {\n pushFormattedTextTokens(tokens, value.slice(index, span.start), index, formats);\n }\n\n if (span.kind === 'cite') {\n tokens.push({\n id: document2Id('cite'),\n kind: 'cite',\n keys: span.keys.length > 0 ? span.keys : [],\n });\n index = span.end;\n continue;\n }\n\n if (span.kind === 'ref') {\n tokens.push({\n id: document2Id('ref'),\n kind: 'ref',\n keys: span.keys.length > 0 ? span.keys : [],\n refCommand: span.refCommand,\n });\n index = span.end;\n continue;\n }\n\n const mathJson = mathObjects[mathObjectIndex];\n mathObjectIndex += 1;\n const structuredMathJson = mathJson?.node_type === 'MathObject' ? mathJson : null;\n if (structuredMathJson && (structuredMathJson.math_mode !== span.opening || structuredMathJson.closing !== span.closing)) {\n pushDiagnostic(diagnostics, options, path, 'math_objects order mismatch');\n }\n\n if (structuredMathJson && structuredMathJson.math_mode === span.opening && structuredMathJson.closing === span.closing) {\n tokens.push({\n id: document2Id('math'),\n kind: 'math',\n display: span.display,\n opening: span.opening,\n closing: span.closing,\n source: span.source,\n sourceSide:\n structuredMathJson.source_side === 'arabic' || structuredMathJson.source_side === 'english'\n ? structuredMathJson.source_side\n : mode,\n math: fromMathObjectJson(structuredMathJson, mode),\n editable: true,\n sourceOwner: structuredMathJson.source_owner === 'editor' ? 'editor' : 'imported-structured',\n ...(typeof structuredMathJson.label_enabled === 'boolean' ? { labelEnabled: structuredMathJson.label_enabled } : {}),\n ...(typeof structuredMathJson.label === 'string' ? { label: structuredMathJson.label } : {}),\n });\n } else {\n tokens.push({\n id: document2Id('math'),\n kind: 'math',\n display: span.display,\n opening: span.opening,\n closing: span.closing,\n source: span.source,\n math: null,\n editable: false,\n reason: 'هذه المعادلة محفوظة كنص خام فقط حاليا',\n sourceOwner: 'raw',\n ...(mathJson?.node_type === 'RawMathObject' && typeof mathJson.label_enabled === 'boolean'\n ? { labelEnabled: mathJson.label_enabled }\n : {}),\n ...(mathJson?.node_type === 'RawMathObject' && typeof mathJson.label === 'string'\n ? { label: mathJson.label }\n : {}),\n });\n }\n\n index = span.end;\n }\n\n if (index < value.length || tokens.length === 0) {\n pushFormattedTextTokens(tokens, value.slice(index), index, formats);\n }\n\n return { id: document2Id('field'), tokens: compactTextTokens(tokens) };\n}\n\nfunction styleFromFormat(format: TextFormatSpan2Json): TextStyle2 | null {\n const style: TextStyle2 = {};\n if (format.bold === true) {\n style.bold = true;\n }\n if (format.italic === true) {\n style.italic = true;\n }\n if (format.underline === true) {\n style.underline = true;\n }\n return style.bold || style.italic || style.underline ? style : null;\n}\n\nfunction mergeTextStyle(base: TextStyle2 | undefined, added: TextStyle2): TextStyle2 {\n return {\n ...(base?.bold ? { bold: true as const } : {}),\n ...(base?.italic ? { italic: true as const } : {}),\n ...(base?.underline ? { underline: true as const } : {}),\n ...(added.bold ? { bold: true as const } : {}),\n ...(added.italic ? { italic: true as const } : {}),\n ...(added.underline ? { underline: true as const } : {}),\n };\n}\n\nfunction textStylesEqual(a: TextStyle2 | undefined, b: TextStyle2 | undefined): boolean {\n return Boolean(a?.bold) === Boolean(b?.bold) && Boolean(a?.italic) === Boolean(b?.italic) && Boolean(a?.underline) === Boolean(b?.underline);\n}\n\nfunction compactTextTokens(tokens: InlineToken2[]): InlineToken2[] {\n const compacted: InlineToken2[] = [];\n for (const token of tokens) {\n const previous = compacted[compacted.length - 1];\n if (previous?.kind === 'text' && token.kind === 'text' && textStylesEqual(previous.style, token.style)) {\n previous.text += token.text;\n } else {\n compacted.push(token);\n }\n }\n return compacted;\n}\n\nfunction styleKey(style: TextStyle2 | undefined): string {\n return `${style?.bold ? 'b' : ''}${style?.italic ? 'i' : ''}${style?.underline ? 'u' : ''}`;\n}\n\nfunction pushFormattedTextTokens(tokens: InlineToken2[], text: string, sourceStart: number, formats: TextFormatSpan2Json[]): void {\n if (text.length === 0) {\n tokens.push({ id: document2Id('text'), kind: 'text', text });\n return;\n }\n const styles: Array<TextStyle2 | undefined> = Array.from({ length: text.length });\n for (const format of formats) {\n const style = styleFromFormat(format);\n if (!style || !Number.isFinite(format.start) || !Number.isFinite(format.end)) {\n continue;\n }\n const start = Math.max(0, Math.min(text.length, Math.trunc(format.start) - sourceStart));\n const end = Math.max(0, Math.min(text.length, Math.trunc(format.end) - sourceStart));\n if (end <= start) {\n continue;\n }\n for (let index = start; index < end; index += 1) {\n styles[index] = mergeTextStyle(styles[index], style);\n }\n }\n\n let chunkStart = 0;\n for (let index = 1; index <= text.length; index += 1) {\n if (index < text.length && styleKey(styles[index]) === styleKey(styles[chunkStart])) {\n continue;\n }\n const chunk = text.slice(chunkStart, index);\n const style = styles[chunkStart];\n tokens.push({ id: document2Id('text'), kind: 'text', text: chunk, ...(style ? { style } : {}) });\n chunkStart = index;\n }\n}\n\nfunction closingForList(command: '\\\\begin{itemize}' | '\\\\begin{enumerate}'): '\\\\end{itemize}' | '\\\\end{enumerate}' {\n return command === '\\\\begin{itemize}' ? '\\\\end{itemize}' : '\\\\end{enumerate}';\n}\n\nfunction parseTextBlock(\n json: Document2BlockJson,\n options: ImportDocument2Options,\n path: string,\n diagnostics: Document2Diagnostic[],\n blockIds: BlockIdState,\n): TextBlock2 {\n const value = requireString(json.value, `${json.command} requires string value`);\n return {\n id: blockIdFromJson(json, blockIds),\n kind: 'textBlock',\n command: json.command as TextBlock2['command'],\n field: createInlineField2(value, json.math_objects ?? [], options, `${path}.value`, diagnostics, json.command === '\\\\paragraph' ? json.formats ?? [] : []),\n ...(json.centered === true ? { centered: true } : {}),\n };\n}\n\nfunction parseListItem(\n json: Document2ListItemJson,\n options: ImportDocument2Options,\n path: string,\n diagnostics: Document2Diagnostic[],\n blockIds: BlockIdState,\n): ListItem2 {\n const value = requireString(json.value, 'Document list item requires string value');\n const blocksJson = Array.isArray(json.blocks) ? json.blocks : [];\n return {\n id: document2Id('item'),\n field: createInlineField2(value, json.math_objects ?? [], options, `${path}.value`, diagnostics, json.formats ?? []),\n blocks: blocksJson.map((block, index) =>\n parseBlock(asBlockJson(block), options, `${path}.blocks[${String(index)}]`, diagnostics, blockIds),\n ),\n };\n}\n\nfunction parseListBlock(\n json: Document2BlockJson,\n options: ImportDocument2Options,\n path: string,\n diagnostics: Document2Diagnostic[],\n blockIds: BlockIdState,\n): ListBlock2 {\n if (!Array.isArray(json.items)) {\n throw new Error(`${json.command} requires items array`);\n }\n const command = json.command as ListBlock2['command'];\n const closing = closingForList(command);\n return {\n id: blockIdFromJson(json, blockIds),\n kind: 'list',\n command,\n closing,\n items: json.items.map((item, index) =>\n parseListItem(item, options, `${path}.items[${String(index)}]`, diagnostics, blockIds),\n ),\n };\n}\n\nfunction parseTableBlock(\n json: Document2BlockJson,\n options: ImportDocument2Options,\n path: string,\n diagnostics: Document2Diagnostic[],\n blockIds: BlockIdState,\n): TableBlock2 {\n if (!Array.isArray(json.rows)) {\n throw new Error('\\\\begin{tabular} requires rows array');\n }\n\n const mathObjects = json.math_objects ?? [];\n let mathObjectIndex = 0;\n const rows = json.rows.map((row, rowIndex) => {\n if (!Array.isArray(row)) {\n throw new Error('\\\\begin{tabular} rows must be arrays');\n }\n return row.map((cell, columnIndex) => {\n const value = requireString(cell, '\\\\begin{tabular} cells must be strings');\n const spanCount = detectMathSpans2(value).length;\n const cellMathObjects = mathObjects.slice(mathObjectIndex, mathObjectIndex + spanCount);\n mathObjectIndex += spanCount;\n const cellFormats = json.cell_formats?.[rowIndex]?.[columnIndex] ?? [];\n return createInlineField2(value, cellMathObjects, options, `${path}.rows[${String(rowIndex)}][${String(columnIndex)}]`, diagnostics, cellFormats);\n });\n });\n\n if (mathObjects.length > 0 && mathObjects.length !== mathObjectIndex) {\n pushDiagnostic(diagnostics, options, path, `math_objects count mismatch: detected ${String(mathObjectIndex)}, got ${String(mathObjects.length)}`);\n }\n\n return {\n id: blockIdFromJson(json, blockIds),\n kind: 'table',\n command: '\\\\begin{tabular}',\n closing: '\\\\end{tabular}',\n columns: typeof json.columns === 'string' ? json.columns : '',\n rows,\n ...parseFloatMetaFromJson(json),\n };\n}\n\nfunction parseImageBlock(json: Document2BlockJson, blockIds: BlockIdState): ImageBlock2 {\n const assetId = typeof json.asset_id === 'string' && json.asset_id.length > 0 ? json.asset_id : undefined;\n const value =\n assetId !== undefined\n ? typeof json.value === 'string'\n ? json.value\n : ''\n : requireString(json.value, '\\\\includegraphics requires string value');\n return {\n id: blockIdFromJson(json, blockIds),\n kind: 'image',\n command: '\\\\includegraphics',\n value,\n ...(assetId !== undefined ? { assetId } : {}),\n options: isRecordOfStrings(json.options) ? json.options : {},\n ...parseFloatMetaFromJson(json),\n };\n}\n\nfunction parseRawBlock(json: Document2BlockJson, blockIds: BlockIdState): RawBlock2 {\n return {\n id: blockIdFromJson(json, blockIds),\n kind: 'raw',\n command: '\\\\raw',\n value: typeof json.value === 'string' ? json.value : '',\n };\n}\n\nfunction parseBibliographyBlock(json: Document2BlockJson, blockIds: BlockIdState): BibliographyBlock2 {\n return {\n id: blockIdFromJson(json, blockIds),\n kind: 'bibliography',\n command: '\\\\begin{thebibliography}',\n closing: '\\\\end{thebibliography}',\n };\n}\n\nfunction parseBlock(\n json: Document2BlockJson,\n options: ImportDocument2Options,\n path: string,\n diagnostics: Document2Diagnostic[],\n blockIds: BlockIdState,\n): Document2Block {\n if (TEXT_COMMANDS.has(json.command)) {\n return parseTextBlock(json, options, path, diagnostics, blockIds);\n }\n if (LIST_COMMANDS.has(json.command)) {\n return parseListBlock(json, options, path, diagnostics, blockIds);\n }\n if (json.command === '\\\\begin{tabular}') {\n return parseTableBlock(json, options, path, diagnostics, blockIds);\n }\n if (json.command === '\\\\includegraphics') {\n return parseImageBlock(json, blockIds);\n }\n if (json.command === '\\\\begin{thebibliography}' || json.command === '\\\\bibliography') {\n return parseBibliographyBlock(json, blockIds);\n }\n if (json.command === '\\\\raw') {\n return parseRawBlock(json, blockIds);\n }\n return {\n id: blockIdFromJson(json, blockIds),\n kind: 'raw',\n command: '\\\\raw',\n value: typeof json.value === 'string' ? json.value : json.command,\n };\n}\n\nexport function fromDocumentJson2(json: unknown, options: ImportDocument2Options = {}): Document2Node {\n if (!isObject(json) || json.node_type !== 'DocumentObject') {\n throw new Error('DocumentObject requires node_type \"DocumentObject\"');\n }\n if (!Array.isArray(json.blocks)) {\n throw new Error('DocumentObject requires blocks array');\n }\n\n const diagnostics: Document2Diagnostic[] = [];\n const blockIds: BlockIdState = { used: new Set<string>() };\n return {\n nodeType: 'DocumentObject',\n meta: normalizeDocument2Meta(json.meta),\n references: parseReferences(json.references),\n blocks: json.blocks.map((block, index) =>\n parseBlock(asBlockJson(block), options, `$.blocks[${String(index)}]`, diagnostics, blockIds),\n ),\n diagnostics,\n };\n}\n\nexport function createEmptyDocument2(): Document2Node {\n return {\n nodeType: 'DocumentObject',\n meta: emptyDocument2Meta(),\n references: [],\n blocks: [],\n diagnostics: [],\n };\n}\n","export type AccentPlacement = 'over' | 'under';\n\nexport const ACCENT_COMMANDS = {\n vec: {\n id: 'vec',\n englishTex: '\\\\vec',\n arabicTex: '\\\\arabvec',\n placement: 'over' as const,\n label: '⃗',\n title: 'سهم فوق',\n },\n hat: {\n id: 'hat',\n englishTex: '\\\\hat',\n arabicTex: '\\\\hat',\n placement: 'over' as const,\n label: 'ˆ',\n title: 'قبعة',\n },\n tilde: {\n id: 'tilde',\n englishTex: '\\\\tilde',\n arabicTex: '\\\\tilde',\n placement: 'over' as const,\n label: '˜',\n title: 'مدة',\n },\n dot: {\n id: 'dot',\n englishTex: '\\\\dot',\n arabicTex: '\\\\dot',\n placement: 'over' as const,\n label: '˙',\n title: 'نقطة فوق',\n },\n ddot: {\n id: 'ddot',\n englishTex: '\\\\ddot',\n arabicTex: '\\\\ddot',\n placement: 'over' as const,\n label: '¨',\n title: 'نقطتان فوق',\n },\n dddot: {\n id: 'dddot',\n englishTex: '\\\\dddot',\n arabicTex: '\\\\dddot',\n placement: 'over' as const,\n label: '⃛',\n title: 'ثلاث نقاط فوق',\n },\n bar: {\n id: 'bar',\n englishTex: '\\\\bar',\n arabicTex: '\\\\bar',\n placement: 'over' as const,\n label: '¯',\n title: 'خط فوق',\n },\n check: {\n id: 'check',\n englishTex: '\\\\check',\n arabicTex: '\\\\check',\n placement: 'over' as const,\n label: 'ˇ',\n title: 'علامة تحقق',\n },\n breve: {\n id: 'breve',\n englishTex: '\\\\breve',\n arabicTex: '\\\\breve',\n placement: 'over' as const,\n label: '˘',\n title: 'قوس قصير',\n },\n acute: {\n id: 'acute',\n englishTex: '\\\\acute',\n arabicTex: '\\\\grave',\n placement: 'over' as const,\n label: '´',\n title: 'نبرة حادة',\n },\n grave: {\n id: 'grave',\n englishTex: '\\\\grave',\n arabicTex: '\\\\acute',\n placement: 'over' as const,\n label: '`',\n title: 'نبرة ثقيلة',\n },\n overline: {\n id: 'overline',\n englishTex: '\\\\overline',\n arabicTex: '\\\\overline',\n placement: 'over' as const,\n label: '‾',\n title: 'خط علوي ممتد',\n },\n underline: {\n id: 'underline',\n englishTex: '\\\\underline',\n arabicTex: '\\\\underline',\n placement: 'under' as const,\n label: '_',\n title: 'خط سفلي',\n },\n overleftarrow: {\n id: 'overleftarrow',\n englishTex: '\\\\overleftarrow',\n arabicTex: '\\\\overrightarrow',\n placement: 'over' as const,\n label: '←',\n title: 'سهم علوي إلى اليسار',\n },\n overrightarrow: {\n id: 'overrightarrow',\n englishTex: '\\\\overrightarrow',\n arabicTex: '\\\\overleftarrow',\n placement: 'over' as const,\n label: '→',\n title: 'سهم علوي إلى اليمين',\n },\n overleftrightarrow: {\n id: 'overleftrightarrow',\n englishTex: '\\\\overleftrightarrow',\n arabicTex: '\\\\overleftrightarrow',\n placement: 'over' as const,\n label: '↔',\n title: 'سهم علوي مزدوج الاتجاه',\n },\n} as const;\n\nexport type AccentCommandId = keyof typeof ACCENT_COMMANDS;\n\nexport type AccentCommandSpec = (typeof ACCENT_COMMANDS)[AccentCommandId] & {\n placement: AccentPlacement;\n};\n\nexport function accentCommandSpec(id: string): AccentCommandSpec | null {\n return Object.prototype.hasOwnProperty.call(ACCENT_COMMANDS, id)\n ? ACCENT_COMMANDS[id as AccentCommandId]\n : null;\n}\n\nexport function accentCommandsList(): AccentCommandSpec[] {\n return Object.values(ACCENT_COMMANDS);\n}\n\n/** Resolve accent id from a TeX command name like `\\hat` or `\\arabvec`. */\nexport function accentCommandIdFromTex(tex: string): AccentCommandId | null {\n const normalized = tex.startsWith('\\\\') ? tex : `\\\\${tex}`;\n for (const spec of Object.values(ACCENT_COMMANDS)) {\n if (spec.englishTex === normalized) {\n return spec.id;\n }\n }\n for (const spec of Object.values(ACCENT_COMMANDS)) {\n if (spec.arabicTex === normalized) {\n return spec.id;\n }\n }\n return null;\n}\n","export const ATOMIC_COMMANDS = {\n ///////////////////////// Functions ////////////////////////////////\n\n //////////////// Trigonometric Functions \n cos: {\n id: 'cos',\n category: 'function',\n englishTex: '\\\\cos',\n arabicTex: '\\\\arcos',\n arabicLabel: 'جتا',\n title: 'جيب التمام',\n },\n sin: {\n id: 'sin',\n category: 'function',\n englishTex: '\\\\sin',\n arabicTex: '\\\\arsin',\n arabicLabel: 'جا',\n title: 'جيب',\n },\n tan: {\n id: 'tan',\n category: 'function',\n englishTex: '\\\\tan',\n arabicTex: '\\\\artan',\n arabicLabel: 'ظا',\n title: 'ظل',\n },\n cot: {\n id: 'cot',\n category: 'function',\n englishTex: '\\\\cot',\n arabicTex: '\\\\arcot',\n arabicLabel: 'ظتا',\n title: 'ظل تمام',\n },\n sec: {\n id: 'sec',\n category: 'function',\n englishTex: '\\\\sec',\n arabicTex: '\\\\arsec',\n arabicLabel: 'قا',\n title: 'قاطع',\n },\n csc: {\n id: 'csc',\n category: 'function',\n englishTex: '\\\\csc',\n arabicTex: '\\\\arcsc',\n arabicLabel: 'قتا',\n title: 'قاطع تمام',\n },\n\n\n /////////////////// Arc Trigonometric Functions \n arccos: {\n id: 'arccos',\n category: 'function',\n englishTex: '\\\\arccos',\n arabicTex: '\\\\aracos',\n arabicLabel: 'قجتا',\n title: 'قاطع جيب التمام',\n },\n arcsin: {\n id: 'arcsin',\n category: 'function',\n englishTex: '\\\\arcsin',\n arabicTex: '\\\\arasin',\n arabicLabel: 'قجا',\n title: 'قاطع جيب',\n },\n arctan: {\n id: 'arctan',\n category: 'function',\n englishTex: '\\\\arctan',\n arabicTex: '\\\\aratan',\n arabicLabel: 'قظا',\n title: 'قاطع ظل',\n },\n arccot: {\n id: 'arccot',\n category: 'function',\n englishTex: '\\\\arccot',\n arabicTex: '\\\\aracot',\n arabicLabel: 'قظتا',\n title: 'قاطع ظل التمام',\n },\n arcsec: {\n id: 'arcsec',\n category: 'function',\n englishTex: '\\\\arcsec',\n arabicTex: '\\\\arasec',\n arabicLabel: 'ققا',\n title: 'قاطع القاطع',\n },\n arccsc: {\n id: 'arccsc',\n category: 'function',\n englishTex: '\\\\arccsc',\n arabicTex: '\\\\aracsc',\n arabicLabel: 'ققتا',\n title: 'قاطع القاطع التمام',\n },\n\n ///////////////// Hyperbolic Functions \n cosh: {\n id: 'cosh',\n category: 'function',\n englishTex: '\\\\cosh',\n arabicTex: '\\\\arcosh',\n arabicLabel: 'جتزا',\n title: 'جيب التمام الزائد',\n },\n sinh: {\n id: 'sinh',\n category: 'function',\n englishTex: '\\\\sinh',\n arabicTex: '\\\\arsinh',\n arabicLabel: 'جزا',\n title: 'جيب الزائد',\n },\n tanh: {\n id: 'tanh',\n category: 'function',\n englishTex: '\\\\tanh',\n arabicTex: '\\\\artanh',\n arabicLabel: 'ظزا',\n title: 'ظل الزائد',\n },\n coth: {\n id: 'coth',\n category: 'function',\n englishTex: '\\\\coth',\n arabicTex: '\\\\arcoth',\n arabicLabel: 'ظتزا',\n title: 'ظل تمام الزائد',\n },\n\n ////// These function somehow doesnt exist in LaTeX and therefore MathJax, skip for now. no problem.\n // sech: {\n // id: 'sech',\n // category: 'function',\n // englishTex: '\\\\sech',\n // arabicTex: '\\\\arsech',\n // arabicLabel: 'قزا',\n // title: 'قاطع الزائد',\n // },\n // csch: {\n // id: 'csch',\n // category: 'function',\n // englishTex: '\\\\csch',\n // arabicTex: '\\\\arcsch',\n // arabicLabel: 'قتزا',\n // title: 'قاطع تمام الزائد',\n // },\n\n\n ///////////////// arc Hyperbolic Functions \n ///// Not on MathJax, skip for now, it is okay.\n\n\n\n ////////////////////// Limits & Series ////////////////////////////////\n sum: {\n id: 'sum',\n category: 'limits_series',\n englishTex: '\\\\sum',\n arabicTex: '\\\\arsum',\n arabicLabel: 'مجـــ',\n title: 'مجموع',\n },\n prod: {\n id: 'prod',\n category: 'limits_series',\n englishTex: '\\\\prod',\n arabicTex: '\\\\arprod',\n arabicLabel: 'جـــد',\n title: 'جداء',\n },\n lim: {\n id: 'lim',\n category: 'limits_series',\n englishTex: '\\\\lim',\n arabicTex: '\\\\arlim',\n arabicLabel: 'نـــــها',\n title: 'حد',\n },\n max: {\n id: 'max',\n category: 'limits_series',\n englishTex: '\\\\max',\n arabicTex: '\\\\armax',\n arabicLabel: 'أكبر',\n title: 'أكبر',\n },\n min: {\n id: 'min',\n category: 'limits_series',\n englishTex: '\\\\min',\n arabicTex: '\\\\armin',\n arabicLabel: 'أصغر',\n title: 'أصغر',\n },\n sup: {\n id: 'sup',\n category: 'limits_series',\n englishTex: '\\\\sup',\n arabicTex: '\\\\arsup',\n arabicLabel: 'أعلى',\n title: 'أعلى',\n },\n inf: {\n id: 'inf',\n category: 'limits_series',\n englishTex: '\\\\inf',\n arabicTex: '\\\\arinf',\n arabicLabel: 'أدنى',\n title: 'أدنى',\n },\n\n ////////////////////// Logarithmic and Exponential and Determinant Functions ////////////////////////////////\n pi: {\n id: 'pi',\n category: 'function2',\n englishTex: '\\\\pi',\n arabicTex: '\\\\arpi',\n arabicLabel: 'ط',\n title: 'نسبة الدائرة',\n },\n exp: {\n id: 'exp',\n category: 'function2',\n englishTex: '\\\\exp',\n arabicTex: '\\\\arexp',\n arabicLabel: 'هـ',\n title: 'أسية',\n },\n ln: {\n id: 'ln',\n category: 'function2',\n englishTex: '\\\\ln',\n arabicTex: '\\\\arln',\n arabicRenderTex: '\\\\prescript{}{\\\\arexp}{\\\\arlog}',\n arabicLabel: 'لو',\n title: 'لوغاريتم طبيعي',\n },\n log: {\n id: 'log',\n category: 'function2',\n englishTex: '\\\\log',\n arabicTex: '\\\\arlog',\n arabicLabel: 'لو',\n title: 'لوغاريتم',\n },\n det: {\n id: 'det',\n category: 'function2',\n englishTex: '\\\\det',\n arabicTex: '\\\\ardet',\n arabicLabel: 'محدد',\n title: 'محدد',\n },\n\n ////////////////////// Derivatives ////////////////////////////////\n ad: {\n id: 'ad',\n category: 'derivative',\n englishTex: '\\\\mathrm{d}',\n englishLabel: 'd',\n arabicTex: '\\\\ad',\n arabicLabel: 'ء',\n title: 'علامة الاشتقاق',\n },\n\n ////////////////////// Groups /////////////////////////////////\n N: {\n id: 'N',\n category: 'groups',\n englishTex: '\\\\mathbb{N}',\n arabicTex: '\\\\arabN',\n arabicLabel: 'ط',\n title: 'أعداد طبيعية',\n },\n Z: {\n id: 'Z',\n category: 'groups',\n englishTex: '\\\\mathbb{Z}',\n arabicTex: '\\\\arabZ',\n arabicLabel: 'ص',\n title: 'أعداد صحيحة',\n },\n Q: {\n id: 'Q',\n category: 'groups',\n englishTex: '\\\\mathbb{Q}',\n arabicTex: '\\\\arabQ',\n arabicLabel: 'ن',\n title: 'أعداد نسبية',\n },\n R: {\n id: 'R',\n category: 'groups',\n englishTex: '\\\\mathbb{R}',\n arabicTex: '\\\\arabR',\n arabicLabel: 'ح',\n title: 'أعداد حقيقية',\n },\n C: {\n id: 'C',\n category: 'groups',\n englishTex: '\\\\mathbb{C}',\n arabicTex: '\\\\arabC',\n arabicLabel: 'ع',\n title: 'أعداد عُقدية',\n },\n H: {\n id: 'H',\n category: 'groups',\n englishTex: '\\\\mathbb{H}',\n arabicTex: '\\\\arabH',\n arabicLabel: 'ر',\n title: 'أعداد رباعية',\n },\n\n ////////////////////// Operations ////////////////////////////\n\n\n ////////////////////// Spacing ////////////////////////////////\n negThinSpace: {\n id: 'negThinSpace',\n category: 'spacing',\n englishTex: '\\\\!',\n arabicTex: '\\\\!',\n arabicLabel: '',\n title: 'فراغ سالب رفيع',\n spacing: { direction: 'negative', level: 1 },\n },\n mediumSpace: {\n id: 'mediumSpace',\n category: 'spacing',\n englishTex: '\\\\:',\n arabicTex: '\\\\:',\n arabicLabel: '',\n title: 'فراغ متوسط',\n spacing: { direction: 'positive', level: 1 },\n },\n thickSpace: {\n id: 'thickSpace',\n category: 'spacing',\n englishTex: '\\\\;',\n arabicTex: '\\\\;',\n arabicLabel: '',\n title: 'فراغ عريض',\n spacing: { direction: 'positive', level: 2 },\n },\n quadSpace: {\n id: 'quadSpace',\n category: 'spacing',\n englishTex: '\\\\quad',\n arabicTex: '\\\\quad',\n arabicLabel: '',\n title: 'فراغ كبير',\n spacing: { direction: 'positive', level: 3 },\n },\n qquadSpace: {\n id: 'qquadSpace',\n category: 'spacing',\n englishTex: '\\\\qquad',\n arabicTex: '\\\\qquad',\n arabicLabel: '',\n title: 'فراغ كبير جدا',\n spacing: { direction: 'positive', level: 4 },\n },\n} as const;\n\nexport type AtomicCommandId = keyof typeof ATOMIC_COMMANDS;\nexport type AtomicCommandCategory = 'function' | 'function2' | 'limits_series' | 'groups' | 'spacing' | 'derivative';\nexport type SpacingDirection = 'positive' | 'negative';\n\nexport type AtomicCommandSpec = (typeof ATOMIC_COMMANDS)[AtomicCommandId] & {\n arabicRenderTex?: string;\n englishLabel?: string;\n};\nexport type SpacingCommandSpec = AtomicCommandSpec & {\n category: 'spacing';\n spacing: {\n direction: SpacingDirection;\n level: 1 | 2 | 3 | 4;\n };\n};\n\nexport function atomicCommandsByCategory(category: AtomicCommandCategory): AtomicCommandSpec[] {\n return Object.values(ATOMIC_COMMANDS).filter((command) => command.category === category);\n}\n\nexport function isSpacingCommandSpec(spec: AtomicCommandSpec | null): spec is SpacingCommandSpec {\n return spec?.category === 'spacing';\n}\n\nexport function atomicCommandSpec(id: string): AtomicCommandSpec | null {\n return Object.prototype.hasOwnProperty.call(ATOMIC_COMMANDS, id)\n ? ATOMIC_COMMANDS[id as AtomicCommandId]\n : null;\n}\n","export const ATOMIC_OPERATOR_COMMANDS = {\n inf: {\n id: 'inf',\n category: 'operators1',\n Tex: '\\\\infty',\n mirror: true,\n Label: '∞',\n title: 'اللانهاية',\n svg_path: null,\n },\n times: {\n id: 'times',\n category: 'operators1',\n Tex: '\\\\times',\n mirror: false,\n Label: '×',\n title: 'ضرب',\n svg_path: null,\n },\n div: {\n id: 'div',\n category: 'operators1',\n Tex: '\\\\div',\n mirror: false,\n Label: '÷',\n title: 'قسمة',\n svg_path: null,\n },\n pm: {\n id: 'pm',\n category: 'operators1',\n Tex: '\\\\pm',\n mirror: false,\n Label: '±',\n title: 'زائد أو ناقص',\n svg_path: null,\n },\n mp: {\n id: 'mp',\n category: 'operators1',\n Tex: '\\\\mp',\n mirror: false,\n Label: '∓',\n title: 'ناقص أو زائد',\n svg_path: null,\n },\n neq: {\n id: 'neq',\n category: 'operators1',\n Tex: '\\\\neq',\n mirror: true,\n compileMirror: true,\n Label: '≠',\n title: 'لا يساوي',\n svg_path: null,\n },\n approx: {\n id: 'approx',\n category: 'operators1',\n Tex: '\\\\approx',\n mirror: false,\n displayMirror: true,\n Label: '≈',\n title: 'تقريبا يساوي',\n svg_path: null,\n },\n sim: {\n id: 'sim',\n category: 'operators1',\n Tex: '\\\\sim',\n mirror: false,\n displayMirror: true,\n Label: '∼',\n title: 'مشابه',\n svg_path: null,\n },\n mid: {\n id: 'mid',\n category: 'operators1',\n Tex: '\\\\mid',\n mirror: false,\n Label: '∣',\n title: 'يقسم',\n svg_path: null,\n },\n leq: {\n id: 'leq',\n category: 'operators1',\n Tex: '\\\\leq',\n mirror: true,\n displayMirror: false,\n compileMirror: true,\n Label: '≤',\n title: 'أصغر من أو يساوي',\n svg_path: null,\n },\n geq: {\n id: 'geq',\n category: 'operators1',\n Tex: '\\\\geq',\n mirror: true,\n displayMirror: false,\n compileMirror: true,\n Label: '≥',\n title: 'أكبر من أو يساوي',\n svg_path: null,\n },\n coloneqq: {\n id: 'coloneqq',\n category: 'operators1',\n Tex: '\\\\coloneqq',\n mirror: true,\n displayMirror: false,\n compileMirror: true,\n Label: '≔',\n title: 'يعرف بأنه يساوي',\n svg_path: null,\n },\n eqqcolon: {\n id: 'eqqcolon',\n category: 'operators1',\n Tex: '\\\\eqqcolon',\n mirror: true,\n displayMirror: false,\n compileMirror: true,\n Label: '≕',\n title: 'يساوي بالتعريف',\n svg_path: null,\n },\n\n ///// Operators 2\n propto: {\n id: 'propto',\n category: 'operators2',\n Tex: '\\\\propto',\n mirror: true,\n displayMirror: false,\n compileMirror: true,\n Label: '∝',\n title: 'يتناسب مع',\n svg_path: null,\n },\n in: {\n id: 'in',\n category: 'operators2',\n Tex: '\\\\in',\n mirror: true,\n displayMirror: false,\n compileMirror: true,\n Label: '∈',\n title: 'ينتمي إلى',\n svg_path: null,\n },\n notin: {\n id: 'notin',\n category: 'operators2',\n Tex: '\\\\notin',\n mirror: false,\n displayMirror: true,\n Label: '∉',\n title: 'لا ينتمي إلى',\n svg_path: null,\n },\n subset: {\n id: 'subset',\n category: 'operators2',\n Tex: '\\\\subset',\n mirror: true,\n displayMirror: false,\n compileMirror: true,\n Label: '⊂',\n title: 'مجموعة جزئية من',\n svg_path: null,\n },\n supset: {\n id: 'supset',\n category: 'operators2',\n Tex: '\\\\supset',\n mirror: true,\n displayMirror: false,\n compileMirror: true,\n Label: '⊃',\n title: 'مجموعة شاملة لـ',\n svg_path: null,\n },\n subseteq: {\n id: 'subseteq',\n category: 'operators2',\n Tex: '\\\\subseteq',\n mirror: true,\n displayMirror: false,\n compileMirror: true,\n Label: '⊆',\n title: 'مجموعة جزئية أو تساوي',\n svg_path: null,\n },\n supseteq: {\n id: 'supseteq',\n category: 'operators2',\n Tex: '\\\\supseteq',\n mirror: true,\n displayMirror: false,\n compileMirror: true,\n Label: '⊇',\n title: 'مجموعة شاملة أو تساوي',\n svg_path: null,\n },\n cap: {\n id: 'cap',\n category: 'operators2',\n Tex: '\\\\cap',\n mirror: false,\n displayMirror: true,\n Label: '∩',\n title: 'تقاطع',\n svg_path: null,\n },\n cup: {\n id: 'cup',\n category: 'operators2',\n Tex: '\\\\cup',\n mirror: false,\n displayMirror: true,\n Label: '∪',\n title: 'اتحاد',\n svg_path: null,\n },\n emptyset: {\n id: 'emptyset',\n category: 'operators2',\n Tex: '\\\\emptyset',\n mirror: false,\n displayMirror: true,\n Label: '∅',\n title: 'المجموعة الخالية',\n svg_path: null,\n },\n nsubseteq: {\n id: 'nsubseteq',\n category: 'operators2',\n Tex: '\\\\nsubseteq',\n mirror: true,\n displayMirror: false,\n compileMirror: true,\n Label: '⊈',\n title: 'ليست مجموعة جزئية أو تساوي',\n svg_path: null,\n },\n nsupseteq: {\n id: 'nsupseteq',\n category: 'operators2',\n Tex: '\\\\nsupseteq',\n mirror: true,\n displayMirror: false,\n compileMirror: true,\n Label: '⊉',\n title: 'ليست مجموعة شاملة أو تساوي',\n svg_path: null,\n },\n\n ///// Dots\n ldots: {\n id: 'ldots',\n category: 'dots',\n Tex: '\\\\ldots',\n mirror: false,\n Label: '…',\n title: 'نقاط أفقية',\n svg_path: null,\n },\n cdot: {\n id: 'cdot',\n category: 'dots',\n Tex: '\\\\cdot',\n mirror: false,\n Label: '·',\n title: 'نقطة ضرب',\n svg_path: null,\n },\n cdots: {\n id: 'cdots',\n category: 'dots',\n Tex: '\\\\cdots',\n mirror: false,\n Label: '⋯',\n title: 'نقاط وسطية أفقية',\n svg_path: null,\n },\n vdots: {\n id: 'vdots',\n category: 'dots',\n Tex: '\\\\vdots',\n mirror: false,\n Label: '⋮',\n title: 'نقاط عمودية',\n svg_path: null,\n },\n ddots: {\n id: 'ddots',\n category: 'dots',\n Tex: '\\\\ddots',\n mirror: true,\n displayMirror: false,\n compileMirror: true,\n Label: '⋱',\n title: 'نقاط قطرية',\n svg_path: null,\n },\n\n /// Operators 3\n leftrightarrowDouble: {\n id: 'leftrightarrowDouble',\n category: 'operators3',\n Tex: '\\\\Leftrightarrow',\n mirror: false,\n Label: '⇔',\n title: 'يكافئ',\n svg_path: null,\n },\n implies: {\n id: 'implies',\n category: 'operators3',\n Tex: '\\\\implies',\n mirror: true,\n compileMirror: true,\n Label: '⇒',\n title: 'يستلزم',\n svg_path: null,\n },\n impliedby: {\n id: 'impliedby',\n category: 'operators3',\n Tex: '\\\\impliedby',\n mirror: true,\n compileMirror: true,\n Label: '⇐',\n title: 'مستلزم من',\n svg_path: null,\n },\n iff: {\n id: 'iff',\n category: 'operators3',\n Tex: '\\\\iff',\n mirror: false,\n Label: '⇔',\n title: 'إذا وفقط إذا',\n svg_path: null,\n },\n Longrightarrow: {\n id: 'Longrightarrow',\n category: 'operators3',\n Tex: '\\\\Longrightarrow',\n mirror: true,\n compileMirror: true,\n Label: '⟹',\n title: 'سهم مزدوج طويل إلى اليمين',\n svg_path: null,\n },\n Longleftarrow: {\n id: 'Longleftarrow',\n category: 'operators3',\n Tex: '\\\\Longleftarrow',\n mirror: true,\n compileMirror: true,\n Label: '⟸',\n title: 'سهم مزدوج طويل إلى اليسار',\n svg_path: null,\n },\n to: {\n id: 'to',\n category: 'operators3',\n Tex: '\\\\to',\n mirror: true,\n compileMirror: true,\n Label: '→',\n title: 'يؤول إلى',\n svg_path: null,\n },\n rightleftharpoons: {\n id: 'rightleftharpoons',\n category: 'operators3',\n Tex: '\\\\rightleftharpoons',\n mirror: true,\n compileMirror: true,\n Label: '⇌',\n title: 'اتزان',\n svg_path: null,\n },\n leftarrow: {\n id: 'leftarrow',\n category: 'operators3',\n Tex: '\\\\leftarrow',\n mirror: true,\n compileMirror: true,\n Label: '←',\n title: 'سهم إلى اليسار',\n svg_path: null,\n },\n rightarrow: {\n id: 'rightarrow',\n category: 'operators3',\n Tex: '\\\\rightarrow',\n mirror: true,\n compileMirror: true,\n Label: '→',\n title: 'سهم إلى اليمين',\n svg_path: null,\n },\n leftarrowDouble: {\n id: 'leftarrowDouble',\n category: 'operators3',\n Tex: '\\\\Leftarrow',\n mirror: true,\n compileMirror: true,\n Label: '⇐',\n title: 'سهم مزدوج إلى اليسار',\n svg_path: null,\n },\n rightarrowDouble: {\n id: 'rightarrowDouble',\n category: 'operators3',\n Tex: '\\\\Rightarrow',\n mirror: true,\n compileMirror: true,\n Label: '⇒',\n title: 'سهم مزدوج إلى اليمين',\n svg_path: null,\n },\n leftharpoonup: {\n id: 'leftharpoonup',\n category: 'operators3',\n Tex: '\\\\leftharpoonup',\n mirror: true,\n compileMirror: true,\n Label: '↼',\n title: 'سهم خطافي علوي إلى اليسار',\n svg_path: null,\n },\n rightharpoonup: {\n id: 'rightharpoonup',\n category: 'operators3',\n Tex: '\\\\rightharpoonup',\n mirror: true,\n compileMirror: true,\n Label: '⇀',\n title: 'سهم خطافي علوي إلى اليمين',\n svg_path: null,\n },\n leftharpoondown: {\n id: 'leftharpoondown',\n category: 'operators3',\n Tex: '\\\\leftharpoondown',\n mirror: true,\n compileMirror: true,\n Label: '↽',\n title: 'سهم خطافي سفلي إلى اليسار',\n svg_path: null,\n },\n rightharpoondown: {\n id: 'rightharpoondown',\n category: 'operators3',\n Tex: '\\\\rightharpoondown',\n mirror: true,\n compileMirror: true,\n Label: '⇁',\n title: 'سهم خطافي سفلي إلى اليمين',\n svg_path: null,\n },\n\n // Integrals\n int: {\n id: 'int',\n category: 'integrals',\n Tex: '\\\\int',\n mirror: true,\n compileMirror: true,\n Label: '∫',\n title: 'تكامل',\n svg_path: null,\n },\n iint: {\n id: 'iint',\n category: 'integrals',\n Tex: '\\\\iint',\n mirror: true,\n displayMirror: false,\n compileMirror: true,\n Label: '∬',\n title: 'تكامل مزدوج',\n svg_path: null,\n },\n iiint: {\n id: 'iiint',\n category: 'integrals',\n Tex: '\\\\iiint',\n mirror: true,\n displayMirror: false,\n compileMirror: true,\n Label: '∭',\n title: 'تكامل ثلاثي',\n svg_path: null,\n },\n iiiint: {\n id: 'iiiint',\n category: 'integrals',\n Tex: '\\\\iiiint',\n mirror: true,\n displayMirror: false,\n compileMirror: true,\n Label: '⨌',\n title: 'تكامل رباعي',\n svg_path: null,\n },\n oint: {\n id: 'oint',\n category: 'integrals',\n Tex: '\\\\oint',\n mirror: true,\n displayMirror: false,\n compileMirror: true,\n Label: '∮',\n title: 'تكامل مغلق',\n svg_path: null,\n },\n oiint: {\n id: 'oiint',\n category: 'integrals',\n Tex: '\\\\oiint',\n mirror: true,\n displayMirror: false,\n compileMirror: true,\n Label: '∯',\n title: 'تكامل سطحي مغلق',\n svg_path: null,\n },\n oiiint: {\n id: 'oiiint',\n category: 'integrals',\n Tex: '\\\\oiiint',\n mirror: true,\n displayMirror: false,\n compileMirror: true,\n Label: '∰',\n title: 'تكامل حجمي مغلق',\n svg_path: null,\n },\n} as const;\n\nexport type AtomicOperatorCommandId = keyof typeof ATOMIC_OPERATOR_COMMANDS;\n\nexport type AtomicOperatorCommandCategory =\n | 'operators1'\n | 'operators2'\n | 'operators3'\n | 'dots'\n | 'integrals';\n\nexport type AtomicOperatorCommandSpec =\n (typeof ATOMIC_OPERATOR_COMMANDS)[AtomicOperatorCommandId] & {\n displayMirror?: boolean;\n compileMirror?: boolean;\n };\n\nexport function shouldMirrorOperatorDisplay(\n command: AtomicOperatorCommandSpec | null | undefined,\n): boolean {\n return command?.displayMirror ?? command?.mirror ?? false;\n}\n\nconst MIRRORED_OPERATOR_TEX = Object.values(ATOMIC_OPERATOR_COMMANDS)\n .filter((command) => command.mirror)\n .map((command) => command.Tex)\n .sort((a, b) => b.length - a.length) as string[];\n\nconst COMPILE_MIRRORED_OPERATOR_TEX = Object.values(ATOMIC_OPERATOR_COMMANDS)\n .filter((command) => 'compileMirror' in command && command.compileMirror)\n .map((command) => command.Tex)\n .sort((a, b) => b.length - a.length) as string[];\n\nfunction matchingMirroredOperatorFrom(tex: string, index: number, operatorTexList: string[]): string | null {\n for (const operatorTex of operatorTexList) {\n if (!tex.startsWith(operatorTex, index)) {\n continue;\n }\n const next = tex[index + operatorTex.length];\n if (next != null && /[A-Za-z]/.test(next)) {\n continue;\n }\n return operatorTex;\n }\n return null;\n}\n\nfunction findMatchingBrace(tex: string, openIndex: number): number {\n let depth = 0;\n for (let index = openIndex; index < tex.length; index += 1) {\n const char = tex[index];\n if (char === '\\\\') {\n index += 1;\n continue;\n }\n if (char === '{') {\n depth += 1;\n } else if (char === '}') {\n depth -= 1;\n if (depth === 0) {\n return index;\n }\n }\n }\n return -1;\n}\n\nexport function mirrorBuTeXOperatorsInTex(tex: string, options: { target?: 'preview' | 'compile' } = {}): string {\n const mirroredOperatorTex = options.target === 'compile'\n ? COMPILE_MIRRORED_OPERATOR_TEX\n : MIRRORED_OPERATOR_TEX;\n let result = '';\n let index = 0;\n\n while (index < tex.length) {\n if (tex.startsWith('\\\\butexmirror{', index)) {\n const end = findMatchingBrace(tex, index + '\\\\butexmirror'.length);\n if (end !== -1) {\n const bodyStart = index + '\\\\butexmirror{'.length;\n const body = tex.slice(bodyStart, end);\n if (\n options.target === 'compile' &&\n MIRRORED_OPERATOR_TEX.includes(body) &&\n !mirroredOperatorTex.includes(body)\n ) {\n result += body;\n } else {\n result += tex.slice(index, end + 1);\n }\n index = end + 1;\n continue;\n }\n }\n\n const operatorTex = matchingMirroredOperatorFrom(tex, index, mirroredOperatorTex);\n if (operatorTex) {\n result += `\\\\butexmirror{${operatorTex}}`;\n index += operatorTex.length;\n continue;\n }\n\n result += tex[index];\n index += 1;\n }\n\n return result;\n}\n\nexport function atomicOperatorCommandsByCategory(\n category: AtomicOperatorCommandCategory,\n): AtomicOperatorCommandSpec[] {\n return Object.values(ATOMIC_OPERATOR_COMMANDS).filter(\n (command) => command.category === category,\n );\n}\n\nexport function atomicOperatorCommandSpec(\n id: string,\n): AtomicOperatorCommandSpec | null {\n return Object.prototype.hasOwnProperty.call(ATOMIC_OPERATOR_COMMANDS, id)\n ? ATOMIC_OPERATOR_COMMANDS[id as AtomicOperatorCommandId]\n : null;\n}\n","import type { EditorChain, EditorNode, EditorSession, EditorSide, EnvColumnAlignment, GridEnvName, MatrixEnvStyle } from './types.js';\nimport type { AccentCommandId } from './accentCommands.js';\nimport type { AtomicCommandId } from './atomicCommands.js';\nimport type { AtomicOperatorCommandId } from './atomicCommandsOperators.js';\n\nlet nextId = 1;\n\nfunction makeId(prefix: string): string {\n const id = `${prefix}_${String(nextId)}`;\n nextId += 1;\n return id;\n}\n\nexport function createEditorChain(nodes: EditorNode[] = []): EditorChain {\n return {\n id: makeId('chain'),\n nodes,\n };\n}\n\nexport function createEditorNode(kind: EditorNode['kind'], expr: string): EditorNode {\n return {\n id: makeId('node'),\n kind,\n expr,\n characterFont: undefined,\n superscript: null,\n subscript: null,\n leftDelimExpr: '',\n rightDelimExpr: '',\n innerExpr: null,\n numerator: null,\n denominator: null,\n radicand: null,\n rootIndex: null,\n overExpr: null,\n underExpr: null,\n baseExpr: null,\n envName: null,\n matrixStyle: null,\n matrixRows: null,\n columnAlignments: null,\n };\n}\n\nexport function createDelimiterNode(leftDelimExpr: string, rightDelimExpr: string): EditorNode {\n return {\n ...createEditorNode('delimiter', ''),\n leftDelimExpr,\n rightDelimExpr,\n innerExpr: createEditorChain(),\n };\n}\n\nexport function createFracNode(): EditorNode {\n return {\n ...createEditorNode('frac', ''),\n numerator: createEditorChain(),\n denominator: createEditorChain(),\n };\n}\n\nexport function createSqrtNode(): EditorNode {\n return {\n ...createEditorNode('sqrt', ''),\n radicand: createEditorChain(),\n rootIndex: createEditorChain(),\n };\n}\n\nexport function createOversetNode(): EditorNode {\n return {\n ...createEditorNode('overset', ''),\n overExpr: createEditorChain(),\n baseExpr: createEditorChain(),\n };\n}\n\nexport function createUndersetNode(): EditorNode {\n return {\n ...createEditorNode('underset', ''),\n underExpr: createEditorChain(),\n baseExpr: createEditorChain(),\n };\n}\n\nexport function createAccentNode(accentId: AccentCommandId): EditorNode {\n return {\n ...createEditorNode('accent', accentId),\n baseExpr: createEditorChain(),\n };\n}\n\nexport function createMatrixEnvNode(style: MatrixEnvStyle, rows: number, columns: number): EditorNode {\n return createGridEnvNode(style, rows, columns);\n}\n\nexport function createGridEnvNode(\n envName: GridEnvName,\n rows: number,\n columns: number,\n columnAlignments?: EnvColumnAlignment[],\n): EditorNode {\n const safeRows = Math.max(1, Math.min(12, Math.trunc(rows)));\n const safeColumns = Math.max(1, Math.min(12, Math.trunc(columns)));\n const matrixStyles = new Set<GridEnvName>(['matrix', 'pmatrix', 'bmatrix', 'Bmatrix', 'vmatrix', 'Vmatrix']);\n const isMatrix = matrixStyles.has(envName) && envName !== 'array' && envName !== 'aligned';\n return {\n ...createEditorNode('env', ''),\n envName,\n matrixStyle: isMatrix ? (envName as MatrixEnvStyle) : null,\n matrixRows: Array.from({ length: safeRows }, () =>\n Array.from({ length: safeColumns }, () => createEditorChain()),\n ),\n columnAlignments: envName === 'array'\n ? Array.from({ length: safeColumns }, (_, index) => columnAlignments?.[index] ?? 'c')\n : null,\n };\n}\n\nexport function createAtomicCommandNode(commandId: AtomicCommandId): EditorNode {\n return createEditorNode('atomicCommand', commandId);\n}\n\nexport function createAtomicOperatorCommandNode(commandId: AtomicOperatorCommandId): EditorNode {\n return createEditorNode('atomicOperatorCommand', commandId);\n}\n\nexport function cloneEditorSession(session: EditorSession): EditorSession {\n return {\n englishTree: structuredClone(session.englishTree),\n arabicTree: structuredClone(session.arabicTree),\n activeSide: session.activeSide,\n splitLeafTyping: session.splitLeafTyping,\n forceSplitNextLeaf: session.forceSplitNextLeaf,\n arabicReverseNumberTyping: session.arabicReverseNumberTyping,\n currentCharacterFont: session.currentCharacterFont ?? 'default',\n currentDigitForm: session.currentDigitForm ?? 'western',\n caret: { ...session.caret },\n selection: session.selection ? { ...session.selection } : null,\n selectedNodeId: session.selectedNodeId,\n selectedStructureNodeId: session.selectedStructureNodeId,\n sync: structuredClone(session.sync),\n debugLog: session.debugLog.slice(),\n };\n}\n\nfunction collectNodeIds(chain: EditorChain, ids: string[]): void {\n for (const node of chain.nodes) {\n ids.push(node.id);\n if (node.superscript) {\n collectNodeIds(node.superscript, ids);\n }\n if (node.subscript) {\n collectNodeIds(node.subscript, ids);\n }\n if (node.innerExpr) {\n collectNodeIds(node.innerExpr, ids);\n }\n if (node.numerator) {\n collectNodeIds(node.numerator, ids);\n }\n if (node.denominator) {\n collectNodeIds(node.denominator, ids);\n }\n if (node.rootIndex) {\n collectNodeIds(node.rootIndex, ids);\n }\n if (node.radicand) {\n collectNodeIds(node.radicand, ids);\n }\n if (node.overExpr) {\n collectNodeIds(node.overExpr, ids);\n }\n if (node.underExpr) {\n collectNodeIds(node.underExpr, ids);\n }\n if (node.baseExpr) {\n collectNodeIds(node.baseExpr, ids);\n }\n if (node.matrixRows) {\n for (const row of node.matrixRows) {\n for (const cell of row) {\n collectNodeIds(cell, ids);\n }\n }\n }\n }\n}\n\nexport function buildInitialSyncMap(englishTree: EditorChain, arabicTree: EditorChain): EditorSession['sync'] {\n const englishIds: string[] = [];\n const arabicIds: string[] = [];\n collectNodeIds(englishTree, englishIds);\n collectNodeIds(arabicTree, arabicIds);\n\n const all = new Set<string>([...englishIds, ...arabicIds]);\n const sync: EditorSession['sync'] = {};\n for (const nodeId of all) {\n sync[nodeId] = { expr: 'synced' };\n }\n return sync;\n}\n\nexport function createEditorSession(englishTree: EditorChain, arabicTree: EditorChain, activeSide: EditorSide = 'arabic'): EditorSession {\n return {\n englishTree,\n arabicTree,\n activeSide,\n splitLeafTyping: false,\n forceSplitNextLeaf: false,\n arabicReverseNumberTyping: true,\n currentCharacterFont: 'default',\n currentDigitForm: 'western',\n caret: {\n chainId: englishTree.id,\n index: 0,\n },\n selection: null,\n selectedNodeId: null,\n selectedStructureNodeId: null,\n sync: buildInitialSyncMap(englishTree, arabicTree),\n debugLog: [],\n };\n}\n","import type { CharacterFontId } from './types.js';\n\nexport type CharacterFontSpec = {\n id: CharacterFontId;\n label: string;\n titleKey:\n | 'defaultFont'\n | 'takweenFont'\n | 'diwaniFont'\n | 'diwaniOutlineFont'\n | 'maghribiFont';\n cssClass?: string;\n mathJaxClass?: string;\n macro?: string;\n latexFontCommand?: string;\n latexFontFamily?: string;\n browserFontStack?: string;\n importAliases?: string[];\n svgLayoutKey?: string;\n};\n\nexport const CHARACTER_FONT_SPECS: CharacterFontSpec[] = [\n {\n id: 'default',\n label: 'س',\n titleKey: 'defaultFont',\n },\n {\n id: 'takween',\n label: 'تك',\n titleKey: 'takweenFont',\n cssClass: 'node-value--takween',\n mathJaxClass: 'butex-takween-text',\n macro: '\\\\butextakween',\n latexFontCommand: '\\\\takween',\n latexFontFamily: 'Takween',\n browserFontStack: '\"BuTeX Takween\", Amiri, \"Segoe UI\", Tahoma, sans-serif',\n importAliases: ['\\\\takween'],\n svgLayoutKey: 'takween',\n },\n {\n id: 'diwani',\n label: 'ديو',\n titleKey: 'diwaniFont',\n cssClass: 'node-value--diwani',\n mathJaxClass: 'butex-diwani-text',\n macro: '\\\\butexdiwani',\n latexFontCommand: '\\\\diwani',\n latexFontFamily: 'Diwani Letter',\n browserFontStack: '\"Diwani Letter\", Amiri, \"Segoe UI\", Tahoma, sans-serif',\n importAliases: ['\\\\diwani'],\n svgLayoutKey: 'diwani',\n },\n {\n id: 'diwaniOutline',\n label: 'ظل',\n titleKey: 'diwaniOutlineFont',\n cssClass: 'node-value--diwani-outline',\n mathJaxClass: 'butex-diwani-outline-text',\n macro: '\\\\butexdiwanioutline',\n latexFontCommand: '\\\\diwanioutlineshaded',\n latexFontFamily: 'Diwani Outline Shaded',\n browserFontStack: '\"BuTeX Diwani Outline\", \"Diwani Letter\", Amiri, \"Segoe UI\", Tahoma, sans-serif',\n importAliases: ['\\\\diwanioutlineshaded'],\n svgLayoutKey: 'diwani-outline',\n },\n {\n id: 'maghribi',\n label: 'مغ',\n titleKey: 'maghribiFont',\n cssClass: 'node-value--maghribi',\n mathJaxClass: 'butex-maghribi-text',\n macro: '\\\\butexmaghribi',\n latexFontCommand: '\\\\maghribi',\n latexFontFamily: 'Almaghribi Warsh Quran',\n browserFontStack: '\"Almaghribi Warsh Quran\", Amiri, \"Segoe UI\", Tahoma, sans-serif',\n svgLayoutKey: 'maghribi',\n },\n];\n\nexport const CHARACTER_FONT_OPTIONS = CHARACTER_FONT_SPECS.map(({ id, label }) => ({ id, label }));\n\nexport const NON_DEFAULT_CHARACTER_FONT_SPECS = CHARACTER_FONT_SPECS.filter(\n (font): font is CharacterFontSpec & { macro: string } => font.id !== 'default' && typeof font.macro === 'string',\n);\n\nexport function characterFontSpec(fontId: CharacterFontId): CharacterFontSpec {\n return CHARACTER_FONT_SPECS.find((font) => font.id === fontId) ?? CHARACTER_FONT_SPECS[0];\n}\n\nexport function characterFontSpecByMacro(macro: string): CharacterFontSpec | null {\n return NON_DEFAULT_CHARACTER_FONT_SPECS.find(\n (font) => font.macro === macro || font.importAliases?.includes(macro),\n ) ?? null;\n}\n","import type { EditorSide } from './types.js';\n\n/** LTR divide stroke stored on the English tree (reference OperatorObject `/`). */\nexport const DIVIDE_OPERATOR_EN = '/';\n\n/** RTL divide stroke shown on the Arabic editing surface. */\nexport const DIVIDE_OPERATOR_AR = '\\\\';\n\nexport function isDivideOperatorExpr(expr: string): boolean {\n return expr === DIVIDE_OPERATOR_EN || expr === DIVIDE_OPERATOR_AR;\n}\n\nexport function divideOperatorSurfaceExpr(expr: string, side: EditorSide): string {\n if (!isDivideOperatorExpr(expr)) {\n return expr;\n }\n return side === 'arabic' ? DIVIDE_OPERATOR_AR : DIVIDE_OPERATOR_EN;\n}\n\nexport function renderDivideOperatorLatex(side: EditorSide): string {\n return side === 'arabic' ? '\\\\backslash' : DIVIDE_OPERATOR_EN;\n}\n","import type { DigitFormId, EditorChain, EditorNode, EditorSession, EnvColumnAlignment } from './types.js';\nimport { accentCommandSpec } from './accentCommands.js';\nimport { atomicCommandSpec } from './atomicCommands.js';\nimport { atomicOperatorCommandSpec } from './atomicCommandsOperators.js';\nimport { characterFontSpec } from './characterFonts.js';\nimport { isDivideOperatorExpr, renderDivideOperatorLatex } from './divideOperator.js';\nimport { formatDigits } from './digits.js';\n\ntype RenderOptions = {\n digitForm?: DigitFormId;\n};\n\nfunction selectedDigitForm(options?: RenderOptions): DigitFormId {\n return options?.digitForm ?? 'western';\n}\n\nfunction latinScripts(node: EditorNode, options?: RenderOptions): string {\n let scripts = '';\n if (node.superscript) {\n scripts += `^{${renderChainEnglish(node.superscript, options)}}`;\n }\n if (node.subscript) {\n scripts += `_{${renderChainEnglish(node.subscript, options)}}`;\n }\n return scripts;\n}\n\nfunction optionalRootIndexEnglish(node: EditorNode, options?: RenderOptions): string {\n if (!node.rootIndex) {\n return '';\n }\n const rendered = renderChainEnglish(node.rootIndex, options);\n return rendered === '' ? '' : `[${rendered}]`;\n}\n\nfunction optionalRootIndexArabic(node: EditorNode, options?: RenderOptions): string {\n if (!node.rootIndex) {\n return '';\n }\n const rendered = renderChainArabic(node.rootIndex, options);\n return rendered === '' ? '' : `[${rendered}]`;\n}\n\nfunction arabicScripts(node: EditorNode, content: string, options?: RenderOptions): string {\n const sup = node.superscript ? renderChainArabic(node.superscript, options) : '';\n const sub = node.subscript ? renderChainArabic(node.subscript, options) : '';\n if (sup !== '' || sub !== '') {\n return `\\\\prescript{${sup}}{${sub}}{${content}}`;\n }\n return content;\n}\n\nfunction renderMatrixRowsEnglish(node: EditorNode, options?: RenderOptions): string {\n if (!node.matrixRows) {\n return '';\n }\n const envName = node.envName ?? node.matrixStyle;\n if (!envName) {\n return '';\n }\n const rows = node.matrixRows.map((row) => row.map((cell) => renderChainEnglish(cell, options)).join(' & '));\n if (envName === 'array') {\n const spec = (node.columnAlignments ?? []).slice(0, node.matrixRows[0]?.length ?? 0).join('');\n return `\\\\begin{array}{${spec || 'c'}}${rows.join(' \\\\\\\\\\n')}\\\\end{array}`;\n }\n return `\\\\begin{${envName}}${rows.join(' \\\\\\\\\\n')}\\\\end{${envName}}`;\n}\n\nfunction reverseAlignmentForArabic(alignment: EnvColumnAlignment): EnvColumnAlignment {\n if (alignment === 'l') {\n return 'r';\n }\n if (alignment === 'r') {\n return 'l';\n }\n return 'c';\n}\n\nfunction renderMatrixRowsArabic(node: EditorNode, options?: RenderOptions): string {\n if (!node.matrixRows) {\n return '';\n }\n const envName = node.envName ?? node.matrixStyle;\n if (!envName) {\n return '';\n }\n const rows = node.matrixRows.map((row) =>\n row\n .slice()\n .reverse()\n .map((cell) => renderChainArabic(cell, options))\n .join(' & '),\n );\n if (envName === 'array') {\n const spec = (node.columnAlignments ?? [])\n .slice(0, node.matrixRows[0]?.length ?? 0)\n .reverse()\n .map(reverseAlignmentForArabic)\n .join('');\n return `\\\\begin{array}{${spec || 'c'}}${rows.join(' \\\\\\\\\\n')}\\\\end{array}`;\n }\n return `\\\\begin{${envName}}${rows.join(' \\\\\\\\\\n')}\\\\end{${envName}}`;\n}\n\nfunction renderAccentEnglish(\n command: 'overset' | 'underset',\n accent: EditorChain | null,\n base: EditorChain | null,\n options?: RenderOptions,\n): string {\n const baseTex = base ? renderChainEnglish(base, options) : '';\n const accentTex = accent ? renderChainEnglish(accent, options) : '';\n if (accentTex === '') {\n return baseTex;\n }\n return `\\\\${command}{${accentTex}}{${baseTex}}`;\n}\n\nfunction renderAccentArabic(\n command: 'overset' | 'underset',\n accent: EditorChain | null,\n base: EditorChain | null,\n options?: RenderOptions,\n): string {\n const baseTex = base ? renderChainArabic(base, options) : '';\n const accentTex = accent ? renderChainArabic(accent, options) : '';\n if (accentTex === '') {\n return baseTex;\n }\n return `\\\\${command}{${accentTex}}{${baseTex}}`;\n}\n\nfunction escapeText(s: string): string {\n return s.replace(/\\\\/g, '\\\\textbackslash{}').replace(/[{}]/g, '\\\\$&');\n}\n\nfunction renderCharContent(node: EditorNode, options?: RenderOptions): string {\n const expr = formatDigits(node.expr, selectedDigitForm(options));\n const font = node.characterFont ?? 'default';\n const macro = characterFontSpec(font).macro;\n if (macro) {\n return `${macro}{${escapeText(expr)}}`;\n }\n return expr;\n}\n\nfunction renderNodeEnglish(node: EditorNode, options?: RenderOptions): string {\n if (node.kind === 'delimiter' && node.innerExpr) {\n return `${node.leftDelimExpr}${renderChainEnglish(node.innerExpr, options)}${node.rightDelimExpr}${latinScripts(node, options)}`;\n }\n if (node.kind === 'frac' && node.numerator && node.denominator) {\n const body = `\\\\frac{${renderChainEnglish(node.numerator, options)}}{${renderChainEnglish(node.denominator, options)}}`;\n return `${body}${latinScripts(node, options)}`;\n }\n if (node.kind === 'sqrt' && node.radicand) {\n const body = `\\\\sqrt${optionalRootIndexEnglish(node, options)}{${renderChainEnglish(node.radicand, options)}}`;\n return `${body}${latinScripts(node, options)}`;\n }\n if (node.kind === 'overset' && node.baseExpr) {\n const body = renderAccentEnglish('overset', node.overExpr, node.baseExpr, options);\n return `${body}${latinScripts(node, options)}`;\n }\n if (node.kind === 'underset' && node.baseExpr) {\n const body = renderAccentEnglish('underset', node.underExpr, node.baseExpr, options);\n return `${body}${latinScripts(node, options)}`;\n }\n if (node.kind === 'accent' && node.baseExpr) {\n const cmd = accentCommandSpec(node.expr)?.englishTex ?? `\\\\${node.expr}`;\n const body = `${cmd}{${renderChainEnglish(node.baseExpr, options)}}`;\n return `${body}${latinScripts(node, options)}`;\n }\n if (node.kind === 'env') {\n return `${renderMatrixRowsEnglish(node, options)}${latinScripts(node, options)}`;\n }\n if (node.kind === 'atomicCommand') {\n const body = atomicCommandSpec(node.expr)?.englishTex ?? node.expr;\n return `${body}${latinScripts(node, options)}`;\n }\n if (node.kind === 'atomicOperatorCommand') {\n const body = atomicOperatorCommandSpec(node.expr)?.Tex ?? node.expr;\n return `${body}${latinScripts(node, options)}`;\n }\n if (node.kind === 'char') {\n return `${renderCharContent(node, options)}${latinScripts(node, options)}`;\n }\n if (node.kind === 'operator' && isDivideOperatorExpr(node.expr)) {\n return `${renderDivideOperatorLatex('english')}${latinScripts(node, options)}`;\n }\n return `${formatDigits(node.expr, selectedDigitForm(options))}${latinScripts(node, options)}`;\n}\n\nfunction renderNodeArabic(node: EditorNode, options?: RenderOptions): string {\n if (node.kind === 'delimiter' && node.innerExpr) {\n const content = `${node.leftDelimExpr}${renderChainArabic(node.innerExpr, options)}${node.rightDelimExpr}`;\n return arabicScripts(node, content, options);\n }\n if (node.kind === 'frac' && node.numerator && node.denominator) {\n const content = `\\\\frac{${renderChainArabic(node.numerator, options)}}{${renderChainArabic(node.denominator, options)}}`;\n return arabicScripts(node, content, options);\n }\n if (node.kind === 'sqrt' && node.radicand) {\n const content = `\\\\arsqrt${optionalRootIndexArabic(node, options)}{${renderChainArabic(node.radicand, options)}}`;\n return arabicScripts(node, content, options);\n }\n if (node.kind === 'overset' && node.baseExpr) {\n const content = renderAccentArabic('overset', node.overExpr, node.baseExpr, options);\n return arabicScripts(node, content, options);\n }\n if (node.kind === 'underset' && node.baseExpr) {\n const content = renderAccentArabic('underset', node.underExpr, node.baseExpr, options);\n return arabicScripts(node, content, options);\n }\n if (node.kind === 'accent' && node.baseExpr) {\n const cmd = accentCommandSpec(node.expr)?.arabicTex ?? `\\\\${node.expr}`;\n const content = `${cmd}{${renderChainArabic(node.baseExpr, options)}}`;\n return arabicScripts(node, content, options);\n }\n if (node.kind === 'env') {\n return arabicScripts(node, renderMatrixRowsArabic(node, options), options);\n }\n if (node.kind === 'atomicCommand') {\n const spec = atomicCommandSpec(node.expr);\n const content = spec?.arabicRenderTex ?? spec?.arabicTex ?? node.expr;\n return arabicScripts(node, content, options);\n }\n if (node.kind === 'atomicOperatorCommand') {\n const spec = atomicOperatorCommandSpec(node.expr);\n const tex = spec?.Tex ?? node.expr;\n const content = spec?.mirror ? `\\\\butexmirror{${tex}}` : tex;\n return arabicScripts(node, content, options);\n }\n if (node.kind === 'char') {\n const expr = formatDigits(node.expr, selectedDigitForm(options));\n const content = renderCharContent(node, options);\n return arabicScripts(node, (node.characterFont ?? 'default') === 'default'\n ? `\\\\text{${escapeText(expr)}}`\n : content, options);\n }\n if (node.kind === 'operator' && isDivideOperatorExpr(node.expr)) {\n return arabicScripts(node, renderDivideOperatorLatex('arabic'), options);\n }\n return arabicScripts(node, formatDigits(node.expr, selectedDigitForm(options)), options);\n}\n\nexport function renderChainEnglish(chain: EditorChain, options?: RenderOptions): string {\n return chain.nodes.map((node) => renderNodeEnglish(node, options)).join(' ');\n}\n\nexport function renderChainArabic(chain: EditorChain, options?: RenderOptions): string {\n return chain.nodes\n .slice()\n .reverse()\n .map((node) => renderNodeArabic(node, options))\n .join(' ');\n}\n\nexport function renderEnglishLatexFromSession(session: EditorSession): string {\n return renderChainEnglish(session.englishTree, { digitForm: session.currentDigitForm ?? 'western' });\n}\n\nexport function renderArabicLatexFromSession(session: EditorSession): string {\n return renderChainArabic(session.arabicTree, { digitForm: session.currentDigitForm ?? 'western' });\n}\n","import { caretStep } from './caretOrder.js';\nimport {\n type EditorFragment,\n regenerateFragmentIds,\n serializeSelection,\n} from './clipboard.js';\nimport {\n cloneEditorSession,\n createDelimiterNode,\n createEditorChain,\n createEditorNode,\n createFracNode,\n createSqrtNode,\n createAccentNode,\n createOversetNode,\n createUndersetNode,\n createGridEnvNode,\n createAtomicCommandNode,\n createAtomicOperatorCommandNode,\n} from './factory.js';\nimport { renderArabicLatexFromSession, renderEnglishLatexFromSession } from './render.js';\nimport { buildFirstDerivativeFrac, buildSecondDerivativeFrac, derivativeTemplateInitialCaret } from './derivativeTemplates.js';\nimport {\n buildLimitsSeriesTemplate,\n limitsSeriesTemplateInitialCaret,\n buildAccentPairTemplate,\n accentPairTemplateInitialCaret,\n} from './limitsTemplates.js';\nimport { DIVIDE_OPERATOR_AR, DIVIDE_OPERATOR_EN } from './divideOperator.js';\nimport { coveredNodeIds, isSelectionActive, nodeChildChains, normalizeSelection } from './selection.js';\nimport { activeTreeKey, findChainById, findNodeById, passiveTreeKey } from './traversal.js';\nimport type {\n CharacterFontId,\n DigitFormId,\n EditorChain,\n EditorDebugEntry,\n EditorNode,\n EditorSession,\n EditorSide,\n EnvColumnAlignment,\n GridEnvName,\n MatrixEnvStyle,\n} from './types.js';\nimport type { ButexUiLocale } from '../uiLocale.js';\nimport { equationEditorMessages } from './uiLocale.js';\nimport type { AccentCommandId } from './accentCommands.js';\nimport type { AtomicCommandId } from './atomicCommands.js';\nimport type { AtomicOperatorCommandId } from './atomicCommandsOperators.js';\n\nfunction ensureSyncEntry(session: EditorSession, nodeId: string): void {\n if (!session.sync[nodeId]) {\n session.sync[nodeId] = { expr: 'synced' };\n }\n}\n\nfunction markExprSync(session: EditorSession, nodeId: string): void {\n const english = findNodeById(session.englishTree, nodeId);\n const arabic = findNodeById(session.arabicTree, nodeId);\n ensureSyncEntry(session, nodeId);\n if (!english || !arabic) {\n session.sync[nodeId].expr = 'diverged';\n return;\n }\n session.sync[nodeId].expr = english.node.expr === arabic.node.expr ? 'synced' : 'diverged';\n}\n\n/** Keep highlighted node aligned with caret (keyboard + programmatic caret moves). */\nexport function syncSelectionToCaret(session: EditorSession): void {\n const activeKey = activeTreeKey(session.activeSide);\n const tree = session[activeKey];\n const { chainId, index } = session.caret;\n const located = findChainById(tree, chainId);\n if (!located) {\n session.selectedNodeId = null;\n return;\n }\n if (index > 0) {\n session.selectedNodeId = located.chain.nodes[index - 1].id;\n return;\n }\n if (located.relation.kind === 'superscript' || located.relation.kind === 'subscript') {\n session.selectedNodeId = located.relation.ownerNodeId;\n return;\n }\n if (\n located.relation.kind === 'inner' ||\n located.relation.kind === 'numerator' ||\n located.relation.kind === 'denominator' ||\n located.relation.kind === 'radicand' ||\n located.relation.kind === 'rootIndex' ||\n located.relation.kind === 'overExpr' ||\n located.relation.kind === 'underExpr' ||\n located.relation.kind === 'baseExpr' ||\n located.relation.kind === 'matrixCell'\n ) {\n session.selectedNodeId = located.relation.ownerNodeId;\n return;\n }\n session.selectedNodeId = null;\n}\n\nfunction appendDebug(session: EditorSession, command: string, note: string): void {\n const entry: EditorDebugEntry = {\n timestamp: new Date().toISOString(),\n command,\n activeSide: session.activeSide,\n englishLatex: renderEnglishLatexFromSession(session),\n arabicLatex: renderArabicLatexFromSession(session),\n renderOk: true,\n renderError: null,\n note,\n };\n const nextLog = session.debugLog.concat(entry);\n session.debugLog = nextLog.slice(-120);\n}\n\nfunction insertMirroredNode(session: EditorSession, chainId: string, index: number, englishNode: EditorNode, arabicNode: EditorNode): void {\n const englishLocated = findChainById(session.englishTree, chainId);\n const arabicLocated = findChainById(session.arabicTree, chainId);\n if (!englishLocated || !arabicLocated) {\n return;\n }\n const safeIndex = Math.max(0, Math.min(index, englishLocated.chain.nodes.length));\n englishLocated.chain.nodes.splice(safeIndex, 0, englishNode);\n arabicLocated.chain.nodes.splice(safeIndex, 0, arabicNode);\n ensureSyncEntry(session, englishNode.id);\n markExprSync(session, englishNode.id);\n}\n\nfunction syncMatrixCellChainIds(englishNode: EditorNode, arabicNode: EditorNode): void {\n const englishRows = englishNode.matrixRows ?? [];\n const arabicRows = arabicNode.matrixRows ?? [];\n const rowLimit = Math.min(englishRows.length, arabicRows.length);\n for (let rowIndex = 0; rowIndex < rowLimit; rowIndex += 1) {\n const englishRow = englishRows[rowIndex];\n const arabicRow = arabicRows[rowIndex];\n const columnLimit = Math.min(englishRow.length, arabicRow.length);\n for (let columnIndex = 0; columnIndex < columnLimit; columnIndex += 1) {\n arabicRow[columnIndex].id = englishRow[columnIndex].id;\n }\n }\n}\n\nfunction createMatrixRow(columnCount: number): EditorChain[] {\n return Array.from({ length: columnCount }, () => createEditorChain());\n}\n\nfunction findSelectedMatrixPair(session: EditorSession): { english: EditorNode; arabic: EditorNode } | null {\n const targetNodeId = session.selectedStructureNodeId ?? session.selectedNodeId;\n if (!targetNodeId) {\n return null;\n }\n const englishLocated = findNodeById(session.englishTree, targetNodeId);\n const arabicLocated = findNodeById(session.arabicTree, targetNodeId);\n if (!englishLocated || !arabicLocated) {\n return null;\n }\n if (englishLocated.node.kind !== 'env' || arabicLocated.node.kind !== 'env') {\n return null;\n }\n return { english: englishLocated.node, arabic: arabicLocated.node };\n}\n\nfunction normalizeArrayAlignments(node: EditorNode): void {\n if ((node.envName ?? node.matrixStyle) !== 'array' || !node.matrixRows) {\n return;\n }\n const columnCount = Math.max(1, node.matrixRows[0]?.length ?? 1);\n const current = node.columnAlignments ?? [];\n node.columnAlignments = Array.from({ length: columnCount }, (_, index) => current[index] ?? 'c');\n}\n\nfunction removeMirroredNodeById(session: EditorSession, nodeId: string): boolean {\n const englishLocated = findNodeById(session.englishTree, nodeId);\n const arabicLocated = findNodeById(session.arabicTree, nodeId);\n if (!englishLocated || !arabicLocated) {\n return false;\n }\n englishLocated.chain.nodes.splice(englishLocated.index, 1);\n arabicLocated.chain.nodes.splice(arabicLocated.index, 1);\n delete session.sync[nodeId];\n return true;\n}\n\n/**\n * Mutates `next` to remove every node covered by its current selection (mirrored\n * across EN/AR), parks the caret at selection.start, and clears the selection.\n * Returns true when something was removed.\n */\nfunction applyDeleteSelectionRange(next: EditorSession): boolean {\n if (!isSelectionActive(next.selection)) {\n next.selection = null;\n return false;\n }\n const ids = coveredNodeIds(next);\n if (ids.length === 0) {\n next.selection = null;\n return false;\n }\n const sel = next.selection;\n if (!sel) {\n return false;\n }\n const start = Math.min(sel.anchorIndex, sel.focusIndex);\n const chainId = sel.chainId;\n for (const id of ids) {\n removeMirroredNodeById(next, id);\n }\n next.caret = { chainId, index: start };\n next.selection = null;\n next.selectedStructureNodeId = null;\n return true;\n}\n\n/** Recursively ensure sync entries for an inserted mirrored subtree (top + nested). */\nfunction syncSubtreeRecursive(session: EditorSession, eng: EditorNode, ar: EditorNode): void {\n ensureSyncEntry(session, eng.id);\n markExprSync(session, eng.id);\n const engChains = nodeChildChains(eng);\n const arChains = nodeChildChains(ar);\n const limit = Math.min(engChains.length, arChains.length);\n for (let c = 0; c < limit; c += 1) {\n const ec = engChains[c];\n const ac = arChains[c];\n const innerLimit = Math.min(ec.nodes.length, ac.nodes.length);\n for (let j = 0; j < innerLimit; j += 1) {\n syncSubtreeRecursive(session, ec.nodes[j], ac.nodes[j]);\n }\n }\n}\n\nexport function switchSide(session: EditorSession): EditorSession {\n const next = cloneEditorSession(session);\n next.activeSide = next.activeSide === 'english' ? 'arabic' : 'english';\n next.selection = null;\n appendDebug(next, 'switchSide', `active=${next.activeSide}`);\n return next;\n}\n\nexport function setSplitLeafTyping(session: EditorSession, enabled: boolean): EditorSession {\n const next = cloneEditorSession(session);\n next.splitLeafTyping = enabled;\n appendDebug(next, 'setSplitLeafTyping', enabled ? 'on' : 'off');\n return next;\n}\n\nexport function setArabicReverseNumberTyping(session: EditorSession, enabled: boolean): EditorSession {\n const next = cloneEditorSession(session);\n next.arabicReverseNumberTyping = enabled;\n appendDebug(next, 'setArabicReverseNumberTyping', enabled ? 'on' : 'off');\n return next;\n}\n\nexport function setCaret(session: EditorSession, chainId: string, index: number): EditorSession {\n const next = cloneEditorSession(session);\n const activeKey = activeTreeKey(next.activeSide);\n const located = findChainById(next[activeKey], chainId);\n if (!located) {\n return session;\n }\n next.caret = {\n chainId,\n index: Math.max(0, Math.min(index, located.chain.nodes.length)),\n };\n next.selection = null;\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n return next;\n}\n\nexport function moveCaret(session: EditorSession, delta: -1 | 1): EditorSession {\n const next = cloneEditorSession(session);\n const activeKey = activeTreeKey(next.activeSide);\n const tree = next[activeKey];\n const located = findChainById(tree, next.caret.chainId);\n if (!located) {\n return session;\n }\n next.caret = caretStep(tree, next.caret, delta);\n next.selection = null;\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaret', `delta=${String(delta)} dfs`);\n return next;\n}\n\nexport function horizontalCaretDelta(session: EditorSession, direction: 'left' | 'right'): -1 | 1 {\n const activeKey = activeTreeKey(session.activeSide);\n const tree = session[activeKey];\n const located = findChainById(tree, session.caret.chainId);\n const inMatrixCell = located?.relation.kind === 'matrixCell';\n const canMoveInsideCell =\n inMatrixCell &&\n session.activeSide === 'arabic' &&\n ((direction === 'left' && session.caret.index < located.chain.nodes.length) ||\n (direction === 'right' && session.caret.index > 0));\n if (session.activeSide === 'arabic' && (!inMatrixCell || canMoveInsideCell)) {\n return direction === 'left' ? 1 : -1;\n }\n return direction === 'left' ? -1 : 1;\n}\n\nexport function moveCaretHorizontal(session: EditorSession, direction: 'left' | 'right'): EditorSession {\n const activeKey = activeTreeKey(session.activeSide);\n const tree = session[activeKey];\n const located = findChainById(tree, session.caret.chainId);\n if (!located || located.relation.kind !== 'matrixCell') {\n return moveCaret(session, horizontalCaretDelta(session, direction));\n }\n\n const textDelta = session.activeSide === 'arabic'\n ? direction === 'left' ? 1 : -1\n : direction === 'left' ? -1 : 1;\n const nextIndex = session.caret.index + textDelta;\n if (nextIndex >= 0 && nextIndex <= located.chain.nodes.length) {\n return moveCaret(session, textDelta);\n }\n\n const ownerLocated =\n located.relation.ownerNodeId !== null ? findNodeById(tree, located.relation.ownerNodeId) : null;\n const ownerNode = ownerLocated?.node ?? null;\n if (!ownerLocated || !ownerNode?.matrixRows) {\n return session;\n }\n\n const rowIndex = located.relation.rowIndex ?? 0;\n const columnIndex = located.relation.columnIndex ?? 0;\n const row = ownerNode.matrixRows[rowIndex];\n if (!row) {\n return session;\n }\n\n const toVisualIndex = (column: number, columnCount: number): number =>\n session.activeSide === 'arabic' ? columnCount - 1 - column : column;\n const fromVisualIndex = (visualColumn: number, columnCount: number): number =>\n session.activeSide === 'arabic' ? columnCount - 1 - visualColumn : visualColumn;\n const entryIndex = (cell: EditorChain): number => {\n if (session.activeSide === 'arabic') {\n return direction === 'left' ? 0 : cell.nodes.length;\n }\n return direction === 'left' ? cell.nodes.length : 0;\n };\n\n const visualDelta = direction === 'left' ? -1 : 1;\n const currentVisualIndex = toVisualIndex(columnIndex, row.length);\n let targetRowIndex = rowIndex;\n let targetVisualIndex = currentVisualIndex + visualDelta;\n\n if (targetVisualIndex < 0 || targetVisualIndex >= row.length) {\n if (direction === 'left') {\n if (session.activeSide === 'arabic') {\n targetRowIndex = rowIndex + 1;\n const targetRow = ownerNode.matrixRows[targetRowIndex];\n if (targetRow) {\n targetVisualIndex = targetRow.length - 1;\n }\n } else {\n targetRowIndex = rowIndex - 1;\n const targetRow = ownerNode.matrixRows[targetRowIndex];\n if (targetRow) {\n targetVisualIndex = targetRow.length - 1;\n }\n }\n } else if (session.activeSide === 'arabic') {\n targetRowIndex = rowIndex - 1;\n targetVisualIndex = 0;\n } else {\n targetRowIndex = rowIndex + 1;\n targetVisualIndex = 0;\n }\n }\n\n const targetRow = ownerNode.matrixRows[targetRowIndex];\n if (targetRow && targetVisualIndex >= 0 && targetVisualIndex < targetRow.length) {\n const targetColumnIndex = fromVisualIndex(targetVisualIndex, targetRow.length);\n const targetCell = targetRow[targetColumnIndex];\n if (targetCell) {\n const next = cloneEditorSession(session);\n next.caret = { chainId: targetCell.id, index: entryIndex(targetCell) };\n next.selection = null;\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretHorizontal', `matrix-${direction}`);\n return next;\n }\n }\n\n const next = cloneEditorSession(session);\n const exitsAfter =\n (session.activeSide === 'english' && direction === 'right') ||\n (session.activeSide === 'arabic' && direction === 'left');\n next.caret = {\n chainId: ownerLocated.chain.id,\n index: exitsAfter ? ownerLocated.index + 1 : ownerLocated.index,\n };\n next.selection = null;\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretHorizontal', `matrix-${direction}-exit`);\n return next;\n}\n\nexport function moveCaretVertical(session: EditorSession, direction: 'up' | 'down'): EditorSession {\n const next = cloneEditorSession(session);\n next.selection = null;\n const activeKey = activeTreeKey(next.activeSide);\n const tree = next[activeKey];\n const located = findChainById(tree, next.caret.chainId);\n if (!located) {\n return session;\n }\n\n const ownerLocated =\n located.relation.ownerNodeId !== null ? findNodeById(tree, located.relation.ownerNodeId) : null;\n const ownerNode = ownerLocated?.node ?? null;\n\n if (located.relation.kind === 'numerator' && ownerLocated && ownerNode && ownerNode.denominator) {\n if (direction === 'down') {\n next.caret = {\n chainId: ownerNode.denominator.id,\n index: ownerNode.denominator.nodes.length,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretVertical', 'frac-num->den');\n return next;\n }\n next.caret = {\n chainId: ownerLocated.chain.id,\n index: ownerLocated.index,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretVertical', 'frac-num-up-exit');\n return next;\n }\n\n if (located.relation.kind === 'denominator' && ownerLocated && ownerNode && ownerNode.numerator) {\n if (direction === 'up') {\n next.caret = {\n chainId: ownerNode.numerator.id,\n index: ownerNode.numerator.nodes.length,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretVertical', 'frac-den->num');\n return next;\n }\n next.caret = {\n chainId: ownerLocated.chain.id,\n index: ownerLocated.index + 1,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretVertical', 'frac-den-down-exit');\n return next;\n }\n\n if (located.relation.kind === 'rootIndex' && ownerLocated && ownerNode && ownerNode.radicand) {\n if (direction === 'down') {\n next.caret = {\n chainId: ownerNode.radicand.id,\n index: ownerNode.radicand.nodes.length,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretVertical', 'sqrt-root->radicand');\n return next;\n }\n next.caret = {\n chainId: ownerLocated.chain.id,\n index: ownerLocated.index,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretVertical', 'sqrt-root-up-exit');\n return next;\n }\n\n if (located.relation.kind === 'radicand' && ownerLocated && ownerNode && ownerNode.rootIndex) {\n if (direction === 'up') {\n next.caret = {\n chainId: ownerNode.rootIndex.id,\n index: ownerNode.rootIndex.nodes.length,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretVertical', 'sqrt-radicand->root');\n return next;\n }\n next.caret = {\n chainId: ownerLocated.chain.id,\n index: ownerLocated.index + 1,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretVertical', 'sqrt-radicand-down-exit');\n return next;\n }\n\n if (located.relation.kind === 'overExpr' && ownerLocated && ownerNode && ownerNode.baseExpr) {\n if (direction === 'down') {\n next.caret = {\n chainId: ownerNode.baseExpr.id,\n index: ownerNode.baseExpr.nodes.length,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretVertical', 'overset-over->base');\n return next;\n }\n next.caret = {\n chainId: ownerLocated.chain.id,\n index: ownerLocated.index,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretVertical', 'overset-over-up-exit');\n return next;\n }\n\n if (\n located.relation.kind === 'baseExpr' &&\n ownerLocated &&\n ownerNode &&\n ownerNode.kind === 'overset' &&\n ownerNode.overExpr\n ) {\n if (direction === 'up') {\n next.caret = {\n chainId: ownerNode.overExpr.id,\n index: ownerNode.overExpr.nodes.length,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretVertical', 'overset-base->over');\n return next;\n }\n next.caret = {\n chainId: ownerLocated.chain.id,\n index: ownerLocated.index + 1,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretVertical', 'overset-base-down-exit');\n return next;\n }\n\n if (\n located.relation.kind === 'baseExpr' &&\n ownerLocated &&\n ownerNode &&\n ownerNode.kind === 'underset' &&\n ownerNode.underExpr\n ) {\n if (direction === 'down') {\n next.caret = {\n chainId: ownerNode.underExpr.id,\n index: ownerNode.underExpr.nodes.length,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretVertical', 'underset-base->under');\n return next;\n }\n next.caret = {\n chainId: ownerLocated.chain.id,\n index: ownerLocated.index,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretVertical', 'underset-base-up-exit');\n return next;\n }\n\n if (located.relation.kind === 'underExpr' && ownerLocated && ownerNode && ownerNode.baseExpr) {\n if (direction === 'up') {\n next.caret = {\n chainId: ownerNode.baseExpr.id,\n index: ownerNode.baseExpr.nodes.length,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretVertical', 'underset-under->base');\n return next;\n }\n next.caret = {\n chainId: ownerLocated.chain.id,\n index: ownerLocated.index + 1,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretVertical', 'underset-under-down-exit');\n return next;\n }\n\n if (\n located.relation.kind === 'baseExpr' &&\n ownerLocated &&\n ownerNode &&\n ownerNode.kind === 'accent'\n ) {\n if (direction === 'up') {\n next.caret = {\n chainId: ownerLocated.chain.id,\n index: ownerLocated.index,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretVertical', 'accent-base-up-exit');\n return next;\n }\n next.caret = {\n chainId: ownerLocated.chain.id,\n index: ownerLocated.index + 1,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretVertical', 'accent-base-down-exit');\n return next;\n }\n\n if (located.relation.kind === 'matrixCell' && ownerLocated && ownerNode?.matrixRows) {\n const rowIndex = located.relation.rowIndex ?? 0;\n const columnIndex = located.relation.columnIndex ?? 0;\n const nextRowIndex = direction === 'up' ? rowIndex - 1 : rowIndex + 1;\n if (nextRowIndex >= 0 && nextRowIndex < ownerNode.matrixRows.length) {\n const nextRow = ownerNode.matrixRows[nextRowIndex];\n const nextCell = nextRow[Math.min(columnIndex, nextRow.length - 1)];\n if (nextCell) {\n next.caret = {\n chainId: nextCell.id,\n index: nextCell.nodes.length,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretVertical', 'matrix-cell');\n return next;\n }\n }\n next.caret = {\n chainId: ownerLocated.chain.id,\n index: direction === 'up' ? ownerLocated.index : ownerLocated.index + 1,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretVertical', `matrix-${direction}-exit`);\n return next;\n }\n\n if (located.relation.kind === 'superscript' && ownerLocated && ownerNode) {\n if (direction === 'down') {\n if (ownerNode.subscript) {\n next.caret = {\n chainId: ownerNode.subscript.id,\n index: ownerNode.subscript.nodes.length,\n };\n } else {\n next.caret = {\n chainId: ownerLocated.chain.id,\n index: ownerLocated.index + 1,\n };\n }\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretVertical', 'sup->down');\n return next;\n }\n next.caret = {\n chainId: ownerLocated.chain.id,\n index: ownerLocated.index,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretVertical', 'sup->up-exit');\n return next;\n }\n\n if (located.relation.kind === 'subscript' && ownerLocated && ownerNode) {\n if (direction === 'up') {\n if (ownerNode.superscript) {\n next.caret = {\n chainId: ownerNode.superscript.id,\n index: ownerNode.superscript.nodes.length,\n };\n } else {\n next.caret = {\n chainId: ownerLocated.chain.id,\n index: ownerLocated.index,\n };\n }\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretVertical', 'sub->up');\n return next;\n }\n next.caret = {\n chainId: ownerLocated.chain.id,\n index: ownerLocated.index + 1,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretVertical', 'sub->down-exit');\n return next;\n }\n\n if (located.relation.kind !== 'root' && located.relation.kind !== 'inner') {\n return session;\n }\n\n const caretIdx = next.caret.index;\n if (caretIdx <= 0) {\n return session;\n }\n const nodeBeforeCaret = located.chain.nodes[caretIdx - 1];\n if (!nodeBeforeCaret) {\n return session;\n }\n\n const targetChain =\n direction === 'up'\n ? nodeBeforeCaret.superscript ?? nodeBeforeCaret.subscript\n : nodeBeforeCaret.subscript ?? nodeBeforeCaret.superscript;\n\n if (!targetChain) {\n return session;\n }\n next.caret = {\n chainId: targetChain.id,\n index: targetChain.nodes.length,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'moveCaretVertical', `base->script:${direction}`);\n return next;\n}\n\nfunction insertLeaf(session: EditorSession, kind: 'char' | 'number' | 'operator', expr: string): EditorSession {\n const next = cloneEditorSession(session);\n const englishNode = createEditorNode(kind, expr);\n const arabicNode = createEditorNode(kind, expr);\n if (kind === 'char' && (next.currentCharacterFont ?? 'default') !== 'default') {\n englishNode.characterFont = next.currentCharacterFont;\n arabicNode.characterFont = next.currentCharacterFont;\n }\n arabicNode.id = englishNode.id;\n insertMirroredNode(next, next.caret.chainId, next.caret.index, englishNode, arabicNode);\n next.caret.index += 1;\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'insertLeaf', `${kind}:${expr}`);\n return next;\n}\n\n/** When Arabic active and flag on, number fragments prepend on both mirrored exprs (same printed string on EN/AR). */\nfunction shouldReverseArabicNumber(session: EditorSession): boolean {\n return session.activeSide === 'arabic' && session.arabicReverseNumberTyping;\n}\n\nfunction characterFontOf(node: EditorNode): CharacterFontId {\n return node.kind === 'char' ? node.characterFont ?? 'default' : 'default';\n}\n\n/** When split mode is off: merge into adjacent same-kind leaf (append after node at index-1, else prepend node at index). */\nfunction tryMergeLeafTyping(session: EditorSession, kind: 'char' | 'number', fragment: string): boolean {\n const engLocated = findChainById(session.englishTree, session.caret.chainId);\n if (!engLocated) {\n return false;\n }\n const nodes = engLocated.chain.nodes;\n const i = session.caret.index;\n let targetId: string | null = null;\n let prepend = false;\n if (i > 0) {\n const prev = nodes[i - 1];\n if (prev.kind === kind && (kind !== 'char' || characterFontOf(prev) === (session.currentCharacterFont ?? 'default'))) {\n targetId = prev.id;\n prepend = false;\n }\n }\n if (!targetId && i < nodes.length) {\n const fwd = nodes[i];\n if (fwd.kind === kind && (kind !== 'char' || characterFontOf(fwd) === (session.currentCharacterFont ?? 'default'))) {\n targetId = fwd.id;\n prepend = true;\n }\n }\n if (!targetId) {\n return false;\n }\n const englishHit = findNodeById(session.englishTree, targetId);\n const arabicHit = findNodeById(session.arabicTree, targetId);\n if (!englishHit || !arabicHit) {\n return false;\n }\n const prependBoth = kind === 'number' && shouldReverseArabicNumber(session) ? true : prepend;\n if (prependBoth) {\n englishHit.node.expr = `${fragment}${englishHit.node.expr}`;\n arabicHit.node.expr = `${fragment}${arabicHit.node.expr}`;\n } else {\n englishHit.node.expr = `${englishHit.node.expr}${fragment}`;\n arabicHit.node.expr = `${arabicHit.node.expr}${fragment}`;\n }\n markExprSync(session, targetId);\n return true;\n}\n\n/**\n * Replace any active selection with a freshly-cleared range, then return a base\n * session ready for the actual insert. Mutating helper so reducers stay short.\n */\nfunction replaceSelectionFirst(session: EditorSession): EditorSession {\n if (!isSelectionActive(session.selection)) {\n return session;\n }\n const next = cloneEditorSession(session);\n applyDeleteSelectionRange(next);\n syncSelectionToCaret(next);\n return next;\n}\n\n/** Returns true when the node before the caret is a pure-digit number leaf (no existing dot). */\nfunction precedingIsExtendableNumber(session: EditorSession): boolean {\n const located = findChainById(session.englishTree, session.caret.chainId);\n if (!located || session.caret.index <= 0) {\n return false;\n }\n const prev = located.chain.nodes[session.caret.index - 1];\n if (!prev || prev.kind !== 'number') {\n return false;\n }\n if (prev.expr.includes('.')) {\n return false;\n }\n return /^\\d+$/.test(prev.expr);\n}\n\n/** One-shot: forces the next insertChar/insertNumber to start a new leaf instead of merging. No-op in split mode. */\nexport function breakLeafTyping(session: EditorSession): EditorSession {\n if (session.splitLeafTyping) {\n return session;\n }\n const next = cloneEditorSession(session);\n next.forceSplitNextLeaf = true;\n appendDebug(next, 'breakLeafTyping', 'split-next');\n return next;\n}\n\nexport function setCurrentCharacterFont(session: EditorSession, fontId: CharacterFontId): EditorSession {\n const next = cloneEditorSession(session);\n next.currentCharacterFont = fontId;\n appendDebug(next, 'setCurrentCharacterFont', fontId);\n return next;\n}\n\nexport function toggleTakweenCharacterFont(session: EditorSession): EditorSession {\n return setCurrentCharacterFont(session, (session.currentCharacterFont ?? 'default') === 'takween' ? 'default' : 'takween');\n}\n\nexport function setCurrentDigitForm(session: EditorSession, digitForm: DigitFormId): EditorSession {\n const next = cloneEditorSession(session);\n next.currentDigitForm = digitForm;\n appendDebug(next, 'setCurrentDigitForm', digitForm);\n return next;\n}\n\nexport function insertChar(session: EditorSession, expr: string): EditorSession {\n const base = replaceSelectionFirst(session);\n if (!base.splitLeafTyping && !base.forceSplitNextLeaf) {\n const next = cloneEditorSession(base);\n if (tryMergeLeafTyping(next, 'char', expr)) {\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'mergeLeaf', `char:${expr}`);\n return next;\n }\n }\n const inserted = insertLeaf(base, 'char', expr);\n inserted.forceSplitNextLeaf = false;\n return inserted;\n}\n\nexport function insertNumber(session: EditorSession, expr: string): EditorSession {\n const base = replaceSelectionFirst(session);\n if (!base.splitLeafTyping && !base.forceSplitNextLeaf) {\n const next = cloneEditorSession(base);\n if (tryMergeLeafTyping(next, 'number', expr)) {\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'mergeLeaf', `number:${expr}`);\n return next;\n }\n }\n const inserted = insertLeaf(base, 'number', expr);\n inserted.forceSplitNextLeaf = false;\n return inserted;\n}\n\nexport function insertDivideOperator(session: EditorSession): EditorSession {\n const base = replaceSelectionFirst(session);\n const next = cloneEditorSession(base);\n const englishNode = createEditorNode('operator', DIVIDE_OPERATOR_EN);\n const arabicNode = createEditorNode('operator', DIVIDE_OPERATOR_AR);\n arabicNode.id = englishNode.id;\n insertMirroredNode(next, next.caret.chainId, next.caret.index, englishNode, arabicNode);\n markExprSync(next, englishNode.id);\n next.caret.index += 1;\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'insertDivideOperator', '');\n return next;\n}\n\nexport function insertOperator(session: EditorSession, expr: string): EditorSession {\n if (expr === '.' && !session.splitLeafTyping && precedingIsExtendableNumber(session)) {\n return insertNumber(session, '.');\n }\n if (expr === DIVIDE_OPERATOR_EN || expr === DIVIDE_OPERATOR_AR) {\n return insertDivideOperator(session);\n }\n const base = replaceSelectionFirst(session);\n return insertLeaf(base, 'operator', expr);\n}\n\nexport function insertAtomicCommand(session: EditorSession, commandId: AtomicCommandId): EditorSession {\n const base = replaceSelectionFirst(session);\n const next = cloneEditorSession(base);\n const englishNode = createAtomicCommandNode(commandId);\n const arabicNode = createAtomicCommandNode(commandId);\n arabicNode.id = englishNode.id;\n insertMirroredNode(next, next.caret.chainId, next.caret.index, englishNode, arabicNode);\n next.caret.index += 1;\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'insertAtomicCommand', commandId);\n return next;\n}\n\nexport function insertAtomicOperatorCommand(session: EditorSession, commandId: AtomicOperatorCommandId): EditorSession {\n const base = replaceSelectionFirst(session);\n const next = cloneEditorSession(base);\n const englishNode = createAtomicOperatorCommandNode(commandId);\n const arabicNode = createAtomicOperatorCommandNode(commandId);\n arabicNode.id = englishNode.id;\n insertMirroredNode(next, next.caret.chainId, next.caret.index, englishNode, arabicNode);\n next.caret.index += 1;\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'insertAtomicOperatorCommand', commandId);\n return next;\n}\n\nexport function insertDelimiterPair(session: EditorSession, leftDelimExpr: string, rightDelimExpr: string): EditorSession {\n const base = replaceSelectionFirst(session);\n const next = cloneEditorSession(base);\n const englishNode = createDelimiterNode(leftDelimExpr, rightDelimExpr);\n const arabicNode = createDelimiterNode(leftDelimExpr, rightDelimExpr);\n arabicNode.id = englishNode.id;\n if (arabicNode.innerExpr && englishNode.innerExpr) {\n arabicNode.innerExpr.id = englishNode.innerExpr.id;\n }\n insertMirroredNode(next, next.caret.chainId, next.caret.index, englishNode, arabicNode);\n next.caret = {\n chainId: englishNode.innerExpr ? englishNode.innerExpr.id : next.caret.chainId,\n index: 0,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'insertDelimiterPair', `${leftDelimExpr}${rightDelimExpr}`);\n return next;\n}\n\nexport function insertFraction(session: EditorSession): EditorSession {\n const base = replaceSelectionFirst(session);\n const next = cloneEditorSession(base);\n const englishNode = createFracNode();\n const arabicNode = createFracNode();\n arabicNode.id = englishNode.id;\n if (arabicNode.numerator && englishNode.numerator) {\n arabicNode.numerator.id = englishNode.numerator.id;\n }\n if (arabicNode.denominator && englishNode.denominator) {\n arabicNode.denominator.id = englishNode.denominator.id;\n }\n insertMirroredNode(next, next.caret.chainId, next.caret.index, englishNode, arabicNode);\n next.caret = {\n chainId: englishNode.numerator ? englishNode.numerator.id : next.caret.chainId,\n index: 0,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'insertFraction', '');\n return next;\n}\n\nfunction insertDerivativeFrac(\n session: EditorSession,\n build: () => { english: EditorNode; arabic: EditorNode },\n debugLabel: string,\n): EditorSession {\n const base = replaceSelectionFirst(session);\n const next = cloneEditorSession(base);\n const { english, arabic } = build();\n insertMirroredNode(next, next.caret.chainId, next.caret.index, english, arabic);\n syncSubtreeRecursive(next, english, arabic);\n next.caret = derivativeTemplateInitialCaret(english);\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, debugLabel, '');\n return next;\n}\n\nexport function insertFirstDerivative(session: EditorSession): EditorSession {\n return insertDerivativeFrac(session, buildFirstDerivativeFrac, 'insertFirstDerivative');\n}\n\nexport function insertSecondDerivative(session: EditorSession): EditorSession {\n return insertDerivativeFrac(session, buildSecondDerivativeFrac, 'insertSecondDerivative');\n}\n\nexport function insertSqrt(session: EditorSession): EditorSession {\n const base = replaceSelectionFirst(session);\n const next = cloneEditorSession(base);\n const englishNode = createSqrtNode();\n const arabicNode = createSqrtNode();\n arabicNode.id = englishNode.id;\n if (arabicNode.radicand && englishNode.radicand) {\n arabicNode.radicand.id = englishNode.radicand.id;\n }\n if (arabicNode.rootIndex && englishNode.rootIndex) {\n arabicNode.rootIndex.id = englishNode.rootIndex.id;\n }\n insertMirroredNode(next, next.caret.chainId, next.caret.index, englishNode, arabicNode);\n next.caret = {\n chainId: englishNode.radicand ? englishNode.radicand.id : next.caret.chainId,\n index: 0,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'insertSqrt', '');\n return next;\n}\n\nexport function insertOverset(session: EditorSession): EditorSession {\n const base = replaceSelectionFirst(session);\n const next = cloneEditorSession(base);\n const englishNode = createOversetNode();\n const arabicNode = createOversetNode();\n arabicNode.id = englishNode.id;\n if (arabicNode.overExpr && englishNode.overExpr) {\n arabicNode.overExpr.id = englishNode.overExpr.id;\n }\n if (arabicNode.baseExpr && englishNode.baseExpr) {\n arabicNode.baseExpr.id = englishNode.baseExpr.id;\n }\n insertMirroredNode(next, next.caret.chainId, next.caret.index, englishNode, arabicNode);\n next.caret = {\n chainId: englishNode.overExpr ? englishNode.overExpr.id : next.caret.chainId,\n index: 0,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'insertOverset', '');\n return next;\n}\n\nexport function insertUnderset(session: EditorSession): EditorSession {\n const base = replaceSelectionFirst(session);\n const next = cloneEditorSession(base);\n const englishNode = createUndersetNode();\n const arabicNode = createUndersetNode();\n arabicNode.id = englishNode.id;\n if (arabicNode.underExpr && englishNode.underExpr) {\n arabicNode.underExpr.id = englishNode.underExpr.id;\n }\n if (arabicNode.baseExpr && englishNode.baseExpr) {\n arabicNode.baseExpr.id = englishNode.baseExpr.id;\n }\n insertMirroredNode(next, next.caret.chainId, next.caret.index, englishNode, arabicNode);\n next.caret = {\n chainId: englishNode.underExpr ? englishNode.underExpr.id : next.caret.chainId,\n index: 0,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'insertUnderset', '');\n return next;\n}\n\nexport function insertLimitsSeriesTemplate(\n session: EditorSession,\n commandId: AtomicCommandId,\n): EditorSession {\n const base = replaceSelectionFirst(session);\n const next = cloneEditorSession(base);\n const { english, arabic } = buildLimitsSeriesTemplate(commandId);\n insertMirroredNode(next, next.caret.chainId, next.caret.index, english, arabic);\n syncSubtreeRecursive(next, english, arabic);\n next.caret = limitsSeriesTemplateInitialCaret(english);\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'insertLimitsSeriesTemplate', commandId);\n return next;\n}\n\nexport function insertAccentPair(session: EditorSession): EditorSession {\n const base = replaceSelectionFirst(session);\n const next = cloneEditorSession(base);\n const { english, arabic } = buildAccentPairTemplate();\n insertMirroredNode(next, next.caret.chainId, next.caret.index, english, arabic);\n syncSubtreeRecursive(next, english, arabic);\n next.caret = accentPairTemplateInitialCaret(english);\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'insertAccentPair', '');\n return next;\n}\n\n/**\n * Insert a one-argument math accent. When a selection is active in one chain,\n * wrap the selected nodes into the accent base; otherwise insert an empty base\n * and place the caret inside it.\n */\nexport function insertAccent(session: EditorSession, accentId: AccentCommandId): EditorSession {\n const next = cloneEditorSession(session);\n const englishNode = createAccentNode(accentId);\n const arabicNode = createAccentNode(accentId);\n arabicNode.id = englishNode.id;\n if (arabicNode.baseExpr && englishNode.baseExpr) {\n arabicNode.baseExpr.id = englishNode.baseExpr.id;\n }\n\n if (isSelectionActive(next.selection) && next.selection) {\n const sel = next.selection;\n const { start, end } = normalizeSelection(sel);\n const englishLocated = findChainById(next.englishTree, sel.chainId);\n const arabicLocated = findChainById(next.arabicTree, sel.chainId);\n if (englishLocated && arabicLocated && end > start) {\n const count = end - start;\n const englishWrapped = englishLocated.chain.nodes.splice(start, count);\n const arabicWrapped = arabicLocated.chain.nodes.splice(start, count);\n englishNode.baseExpr!.nodes = englishWrapped;\n arabicNode.baseExpr!.nodes = arabicWrapped;\n englishLocated.chain.nodes.splice(start, 0, englishNode);\n arabicLocated.chain.nodes.splice(start, 0, arabicNode);\n syncSubtreeRecursive(next, englishNode, arabicNode);\n next.caret = {\n chainId: englishNode.baseExpr!.id,\n index: englishWrapped.length,\n };\n next.selection = null;\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'insertAccent', `${accentId}:wrap`);\n return next;\n }\n }\n\n insertMirroredNode(next, next.caret.chainId, next.caret.index, englishNode, arabicNode);\n syncSubtreeRecursive(next, englishNode, arabicNode);\n next.caret = {\n chainId: englishNode.baseExpr ? englishNode.baseExpr.id : next.caret.chainId,\n index: 0,\n };\n next.selection = null;\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'insertAccent', `${accentId}:empty`);\n return next;\n}\n\nexport function insertMatrixEnv(\n session: EditorSession,\n style: MatrixEnvStyle,\n rows: number,\n columns: number,\n): EditorSession {\n return insertGridEnv(session, style, rows, columns);\n}\n\nexport function insertArrayEnv(\n session: EditorSession,\n rows: number,\n columns: number,\n columnAlignments?: EnvColumnAlignment[],\n): EditorSession {\n return insertGridEnv(session, 'array', rows, columns, columnAlignments);\n}\n\nexport function insertAlignedEnv(\n session: EditorSession,\n rows: number,\n columns: number,\n): EditorSession {\n return insertGridEnv(session, 'aligned', rows, columns);\n}\n\nfunction insertGridEnv(\n session: EditorSession,\n envName: GridEnvName,\n rows: number,\n columns: number,\n columnAlignments?: EnvColumnAlignment[],\n): EditorSession {\n const base = replaceSelectionFirst(session);\n const next = cloneEditorSession(base);\n const englishNode = createGridEnvNode(envName, rows, columns, columnAlignments);\n const arabicNode = createGridEnvNode(envName, rows, columns, columnAlignments);\n arabicNode.id = englishNode.id;\n syncMatrixCellChainIds(englishNode, arabicNode);\n insertMirroredNode(next, next.caret.chainId, next.caret.index, englishNode, arabicNode);\n next.caret = {\n chainId: englishNode.matrixRows?.[0]?.[0]?.id ?? next.caret.chainId,\n index: 0,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'insertGridEnv', `${envName}:${String(rows)}x${String(columns)}`);\n return next;\n}\n\nexport function setMatrixEnvStyle(session: EditorSession, style: MatrixEnvStyle): EditorSession {\n const next = cloneEditorSession(session);\n const pair = findSelectedMatrixPair(next);\n if (!pair) {\n return session;\n }\n pair.english.envName = style;\n pair.arabic.envName = style;\n pair.english.matrixStyle = style;\n pair.arabic.matrixStyle = style;\n pair.english.columnAlignments = null;\n pair.arabic.columnAlignments = null;\n appendDebug(next, 'setMatrixEnvStyle', style);\n return next;\n}\n\nexport function setArrayColumnAlignment(\n session: EditorSession,\n columnIndex: number,\n alignment: EnvColumnAlignment,\n): EditorSession {\n const next = cloneEditorSession(session);\n const pair = findSelectedMatrixPair(next);\n if (!pair || (pair.english.envName ?? pair.english.matrixStyle) !== 'array') {\n return session;\n }\n normalizeArrayAlignments(pair.english);\n normalizeArrayAlignments(pair.arabic);\n const columnCount = pair.english.columnAlignments?.length ?? 0;\n const safeIndex = Math.max(0, Math.min(columnIndex, Math.max(0, columnCount - 1)));\n if (pair.english.columnAlignments && pair.arabic.columnAlignments && columnCount > 0) {\n pair.english.columnAlignments[safeIndex] = alignment;\n pair.arabic.columnAlignments[safeIndex] = alignment;\n }\n appendDebug(next, 'setArrayColumnAlignment', `${String(safeIndex)}:${alignment}`);\n return next;\n}\n\nexport function addMatrixRow(session: EditorSession): EditorSession {\n const next = cloneEditorSession(session);\n const pair = findSelectedMatrixPair(next);\n if (!pair || !pair.english.matrixRows || !pair.arabic.matrixRows || pair.english.matrixRows.length >= 12) {\n return session;\n }\n const columnCount = Math.max(1, pair.english.matrixRows[0]?.length ?? 1);\n const englishRow = createMatrixRow(columnCount);\n const arabicRow = createMatrixRow(columnCount);\n for (let i = 0; i < columnCount; i += 1) {\n arabicRow[i].id = englishRow[i].id;\n }\n pair.english.matrixRows.push(englishRow);\n pair.arabic.matrixRows.push(arabicRow);\n normalizeArrayAlignments(pair.english);\n normalizeArrayAlignments(pair.arabic);\n appendDebug(next, 'addMatrixRow', pair.english.id);\n return next;\n}\n\nexport function removeMatrixRow(session: EditorSession): EditorSession {\n const next = cloneEditorSession(session);\n const pair = findSelectedMatrixPair(next);\n if (!pair || !pair.english.matrixRows || !pair.arabic.matrixRows || pair.english.matrixRows.length <= 1) {\n return session;\n }\n pair.english.matrixRows.pop();\n pair.arabic.matrixRows.pop();\n normalizeArrayAlignments(pair.english);\n normalizeArrayAlignments(pair.arabic);\n appendDebug(next, 'removeMatrixRow', pair.english.id);\n return next;\n}\n\nexport function addMatrixColumn(session: EditorSession): EditorSession {\n const next = cloneEditorSession(session);\n const pair = findSelectedMatrixPair(next);\n if (!pair || !pair.english.matrixRows || !pair.arabic.matrixRows) {\n return session;\n }\n const columnCount = pair.english.matrixRows[0]?.length ?? 0;\n if (columnCount >= 12) {\n return session;\n }\n for (let rowIndex = 0; rowIndex < pair.english.matrixRows.length; rowIndex += 1) {\n const englishCell = createEditorChain();\n const arabicCell = createEditorChain();\n arabicCell.id = englishCell.id;\n pair.english.matrixRows[rowIndex].push(englishCell);\n pair.arabic.matrixRows[rowIndex].push(arabicCell);\n }\n normalizeArrayAlignments(pair.english);\n normalizeArrayAlignments(pair.arabic);\n appendDebug(next, 'addMatrixColumn', pair.english.id);\n return next;\n}\n\nexport function removeMatrixColumn(session: EditorSession): EditorSession {\n const next = cloneEditorSession(session);\n const pair = findSelectedMatrixPair(next);\n if (!pair || !pair.english.matrixRows || !pair.arabic.matrixRows) {\n return session;\n }\n const columnCount = pair.english.matrixRows[0]?.length ?? 0;\n if (columnCount <= 1) {\n return session;\n }\n for (let rowIndex = 0; rowIndex < pair.english.matrixRows.length; rowIndex += 1) {\n pair.english.matrixRows[rowIndex].pop();\n pair.arabic.matrixRows[rowIndex].pop();\n }\n normalizeArrayAlignments(pair.english);\n normalizeArrayAlignments(pair.arabic);\n appendDebug(next, 'removeMatrixColumn', pair.english.id);\n return next;\n}\n\nfunction addScript(session: EditorSession, type: 'superscript' | 'subscript'): EditorSession {\n const targetNodeId = session.selectedNodeId;\n if (!targetNodeId) {\n return session;\n }\n const next = cloneEditorSession(session);\n const englishLocated = findNodeById(next.englishTree, targetNodeId);\n const arabicLocated = findNodeById(next.arabicTree, targetNodeId);\n if (!englishLocated || !arabicLocated) {\n return session;\n }\n const englishNode = englishLocated.node;\n const arabicNode = arabicLocated.node;\n if (!englishNode[type]) {\n englishNode[type] = createEditorChain();\n }\n if (!arabicNode[type]) {\n arabicNode[type] = createEditorChain();\n }\n if (englishNode[type] && arabicNode[type]) {\n arabicNode[type].id = englishNode[type].id;\n next.caret = {\n chainId: englishNode[type].id,\n index: englishNode[type].nodes.length,\n };\n }\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, `add${type === 'superscript' ? 'Sup' : 'Sub'}`, targetNodeId);\n return next;\n}\n\nfunction removeScript(session: EditorSession, type: 'superscript' | 'subscript'): EditorSession {\n const targetNodeId = session.selectedNodeId;\n if (!targetNodeId) {\n return session;\n }\n const next = cloneEditorSession(session);\n const englishLocated = findNodeById(next.englishTree, targetNodeId);\n const arabicLocated = findNodeById(next.arabicTree, targetNodeId);\n if (!englishLocated || !arabicLocated) {\n return session;\n }\n englishLocated.node[type] = null;\n arabicLocated.node[type] = null;\n next.caret = {\n chainId: englishLocated.chain.id,\n index: englishLocated.index + 1,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, `remove${type === 'superscript' ? 'Sup' : 'Sub'}`, targetNodeId);\n return next;\n}\n\nexport function addSup(session: EditorSession): EditorSession {\n return addScript(session, 'superscript');\n}\n\nexport function addSub(session: EditorSession): EditorSession {\n return addScript(session, 'subscript');\n}\n\nexport function removeSup(session: EditorSession): EditorSession {\n return removeScript(session, 'superscript');\n}\n\nexport function removeSub(session: EditorSession): EditorSession {\n return removeScript(session, 'subscript');\n}\n\nexport function selectNode(session: EditorSession, nodeId: string | null): EditorSession {\n const next = cloneEditorSession(session);\n next.selectedNodeId = nodeId;\n next.selectedStructureNodeId = null;\n return next;\n}\n\nexport function deleteStructure(session: EditorSession): EditorSession {\n const targetNodeId = session.selectedStructureNodeId ?? session.selectedNodeId;\n if (!targetNodeId) {\n return session;\n }\n const next = cloneEditorSession(session);\n const activeKey = activeTreeKey(next.activeSide);\n const located = findNodeById(next[activeKey], targetNodeId);\n if (!located) {\n return session;\n }\n const removed = removeMirroredNodeById(next, targetNodeId);\n if (!removed) {\n return session;\n }\n next.caret = {\n chainId: located.chain.id,\n index: located.index,\n };\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'deleteStructure', targetNodeId);\n return next;\n}\n\nexport function deleteBackward(session: EditorSession): EditorSession {\n if (isSelectionActive(session.selection)) {\n const next = cloneEditorSession(session);\n applyDeleteSelectionRange(next);\n syncSelectionToCaret(next);\n appendDebug(next, 'deleteBackward', 'deleted range');\n return next;\n }\n const next = cloneEditorSession(session);\n const activeKey = activeTreeKey(next.activeSide);\n const located = findChainById(next[activeKey], next.caret.chainId);\n if (!located) {\n return session;\n }\n if (next.caret.index <= 0) {\n return session;\n }\n const previousNode = located.chain.nodes[next.caret.index - 1];\n if (!previousNode) {\n return session;\n }\n if (\n (previousNode.kind === 'delimiter' || previousNode.kind === 'frac' || previousNode.kind === 'sqrt' || previousNode.kind === 'overset' || previousNode.kind === 'underset' || previousNode.kind === 'accent' || previousNode.kind === 'env') &&\n next.selectedStructureNodeId !== previousNode.id\n ) {\n next.selectedStructureNodeId = previousNode.id;\n next.selectedNodeId = previousNode.id;\n appendDebug(next, 'deleteBackward', 'selected structure');\n return next;\n }\n if (\n !next.splitLeafTyping &&\n (previousNode.kind === 'char' || previousNode.kind === 'number') &&\n previousNode.expr.length > 1\n ) {\n const id = previousNode.id;\n const englishHit = findNodeById(next.englishTree, id);\n const arabicHit = findNodeById(next.arabicTree, id);\n if (englishHit && arabicHit) {\n if (previousNode.kind === 'number' && shouldReverseArabicNumber(next)) {\n englishHit.node.expr = englishHit.node.expr.slice(1);\n arabicHit.node.expr = arabicHit.node.expr.slice(1);\n } else {\n englishHit.node.expr = englishHit.node.expr.slice(0, -1);\n arabicHit.node.expr = arabicHit.node.expr.slice(0, -1);\n }\n markExprSync(next, id);\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'deleteBackward', 'trimmed leaf');\n return next;\n }\n }\n const removed = removeMirroredNodeById(next, previousNode.id);\n if (!removed) {\n return session;\n }\n next.caret.index = Math.max(0, next.caret.index - 1);\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'deleteBackward', 'removed node');\n return next;\n}\n\nexport function deleteForward(session: EditorSession): EditorSession {\n if (isSelectionActive(session.selection)) {\n const next = cloneEditorSession(session);\n applyDeleteSelectionRange(next);\n syncSelectionToCaret(next);\n appendDebug(next, 'deleteForward', 'deleted range');\n return next;\n }\n const next = cloneEditorSession(session);\n const activeKey = activeTreeKey(next.activeSide);\n const located = findChainById(next[activeKey], next.caret.chainId);\n if (!located) {\n return session;\n }\n if (next.caret.index >= located.chain.nodes.length) {\n return session;\n }\n const node = located.chain.nodes[next.caret.index];\n if (!node) {\n return session;\n }\n if (!next.splitLeafTyping && (node.kind === 'char' || node.kind === 'number') && node.expr.length > 1) {\n const englishHit = findNodeById(next.englishTree, node.id);\n const arabicHit = findNodeById(next.arabicTree, node.id);\n if (englishHit && arabicHit) {\n if (node.kind === 'number' && shouldReverseArabicNumber(next)) {\n englishHit.node.expr = englishHit.node.expr.slice(0, -1);\n arabicHit.node.expr = arabicHit.node.expr.slice(0, -1);\n } else {\n englishHit.node.expr = englishHit.node.expr.slice(1);\n arabicHit.node.expr = arabicHit.node.expr.slice(1);\n }\n markExprSync(next, node.id);\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'deleteForward', 'trimmed leaf');\n return next;\n }\n }\n const removed = removeMirroredNodeById(next, node.id);\n if (!removed) {\n return session;\n }\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'deleteForward', 'removed node');\n return next;\n}\n\nexport function setExpr(session: EditorSession, nodeId: string, expr: string): EditorSession {\n const next = cloneEditorSession(session);\n const activeKey = activeTreeKey(next.activeSide);\n const passiveKey = passiveTreeKey(next.activeSide);\n const activeNode = findNodeById(next[activeKey], nodeId);\n const passiveNode = findNodeById(next[passiveKey], nodeId);\n if (!activeNode || !passiveNode) {\n return session;\n }\n activeNode.node.expr = expr;\n markExprSync(next, nodeId);\n appendDebug(next, 'setExpr', nodeId);\n return next;\n}\n\nexport function createStarterSession(): EditorSession {\n const englishRoot = createEditorChain([createEditorNode('char', 'x')]);\n const arabicRoot = createEditorChain([createEditorNode('char', 'س')]);\n arabicRoot.id = englishRoot.id;\n arabicRoot.nodes[0].id = englishRoot.nodes[0].id;\n const session: EditorSession = {\n englishTree: englishRoot,\n arabicTree: arabicRoot,\n activeSide: 'arabic',\n splitLeafTyping: false,\n forceSplitNextLeaf: false,\n arabicReverseNumberTyping: true,\n currentCharacterFont: 'default',\n currentDigitForm: 'western',\n caret: {\n chainId: englishRoot.id,\n index: 1,\n },\n selection: null,\n selectedNodeId: englishRoot.nodes[0].id,\n selectedStructureNodeId: null,\n sync: {\n [englishRoot.nodes[0].id]: { expr: 'diverged' },\n },\n debugLog: [],\n };\n appendDebug(session, 'createStarterSession', 'initialized');\n return session;\n}\n\nexport function syncStateSummary(session: EditorSession, uiLocale: ButexUiLocale = 'ar'): string {\n const messages = equationEditorMessages(uiLocale);\n const diverged = Object.values(session.sync).filter((entry) => entry.expr === 'diverged').length;\n if (diverged === 0) {\n return messages.synced;\n }\n return uiLocale === 'ar' ? `يوجد ${String(diverged)} ${messages.differentItems}` : `${String(diverged)} ${messages.differentItems}`;\n}\n\nexport function setRenderError(session: EditorSession, message: string | null): EditorSession {\n const next = cloneEditorSession(session);\n if (next.debugLog.length === 0) {\n appendDebug(next, 'render', 'init');\n }\n const last = next.debugLog[next.debugLog.length - 1];\n next.debugLog[next.debugLog.length - 1] = {\n ...last,\n renderOk: message === null,\n renderError: message,\n };\n return next;\n}\n\nexport function activeSideLabel(side: EditorSide, uiLocale: ButexUiLocale = 'ar'): string {\n const messages = equationEditorMessages(uiLocale);\n return side === 'arabic' ? messages.arabicSide : messages.englishSide;\n}\n\nconst PASTE_OPERATORS = new Set(['+', '-', '*', '/', '=', '<', '>', '.']);\n\n/** Read-only: build a fragment from the active selection (or null when collapsed). */\nexport function copySelection(session: EditorSession): EditorFragment | null {\n return serializeSelection(session);\n}\n\n/** Cut: removes the selection and returns both the cleaned session and the fragment. */\nexport function cutSelection(\n session: EditorSession,\n): { session: EditorSession; fragment: EditorFragment | null } {\n const fragment = serializeSelection(session);\n if (!fragment) {\n return { session, fragment: null };\n }\n const next = cloneEditorSession(session);\n applyDeleteSelectionRange(next);\n syncSelectionToCaret(next);\n appendDebug(next, 'cutSelection', `count=${String(fragment.english.length)}`);\n return { session: next, fragment };\n}\n\n/**\n * Insert a structured fragment at the caret in the active chain. The fragment\n * is re-id'd so it can't collide with the live tree, mirrored EN/AR ids are\n * preserved, and sync entries are populated for every nested node.\n */\nexport function pasteFragment(session: EditorSession, fragment: EditorFragment): EditorSession {\n if (!fragment || !fragment.english.length || !fragment.arabic.length) {\n return session;\n }\n const next = cloneEditorSession(session);\n applyDeleteSelectionRange(next);\n\n const fresh = regenerateFragmentIds(fragment);\n const limit = Math.min(fresh.english.length, fresh.arabic.length);\n for (let i = 0; i < limit; i += 1) {\n const eng = fresh.english[i];\n const ar = fresh.arabic[i];\n insertMirroredNode(next, next.caret.chainId, next.caret.index, eng, ar);\n syncSubtreeRecursive(next, eng, ar);\n next.caret = { chainId: next.caret.chainId, index: next.caret.index + 1 };\n }\n next.selection = null;\n next.selectedStructureNodeId = null;\n syncSelectionToCaret(next);\n appendDebug(next, 'pasteFragment', `count=${String(limit)}`);\n return next;\n}\n\n/**\n * Plain-text fallback paste. Each character is dispatched through the existing\n * typing path so split/merge mode and selection-replace behave the same as\n * keyboard input. Whitespace is silently skipped in this MVP.\n */\nexport function pasteText(session: EditorSession, text: string): EditorSession {\n if (!text) {\n return session;\n }\n let s = session;\n let i = 0;\n while (i < text.length) {\n const ch = text[i]!;\n if (ch === '\\n' || ch === '\\r' || ch === '\\t' || ch === ' ') {\n if (!s.splitLeafTyping) {\n s = breakLeafTyping(s);\n }\n i += 1;\n continue;\n }\n if (/^[0-9]$/.test(ch)) {\n let j = i + 1;\n let sawDot = false;\n while (j < text.length) {\n const c = text[j]!;\n if (/^[0-9]$/.test(c)) {\n j += 1;\n continue;\n }\n if (c === '.' && !sawDot && j + 1 < text.length && /^[0-9]$/.test(text[j + 1]!)) {\n sawDot = true;\n j += 1;\n continue;\n }\n break;\n }\n s = insertNumber(s, text.slice(i, j));\n i = j;\n continue;\n }\n if (PASTE_OPERATORS.has(ch)) {\n s = insertOperator(s, ch);\n i += 1;\n continue;\n }\n if (ch === DIVIDE_OPERATOR_AR) {\n s = insertDivideOperator(s);\n i += 1;\n continue;\n }\n s = insertChar(s, ch);\n i += 1;\n }\n return s;\n}\n","import type { EditorChain, EditorNode } from '../types.js';\n\ntype BuildChain = (chain: EditorChain) => HTMLElement;\n\nexport const DELIMITER_CSS = `\n.delim-pair {\n display: inline-flex;\n align-items: stretch;\n min-height: 1.85em;\n}\n\n.delim-inner {\n display: inline-flex;\n align-items: center;\n}\n\n.delim {\n display: inline-flex;\n align-self: stretch;\n align-items: center;\n justify-content: center;\n color: var(--butex-delim-color, #475569);\n padding: 0 1px;\n min-height: 100%;\n}\n\n.delim-glyph {\n display: inline-flex;\n align-items: center;\n line-height: 1;\n font-size: clamp(20px, 1.08em + 0.8vh, 36px);\n transform: translateY(-20%) scaleY(var(--butex-delim-scale, 1));\n transform-origin: center;\n}\n`.trim();\n\nconst DELIMITER_BASE_HEIGHT_PX = 18;\nconst DELIMITER_MAX_SCALE = 4.8;\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, value));\n}\n\nfunction applyDelimiterScale(pair: HTMLElement, inner: HTMLElement): void {\n const innerHeight = Math.max(inner.getBoundingClientRect().height, DELIMITER_BASE_HEIGHT_PX);\n const scale = clamp((innerHeight / DELIMITER_BASE_HEIGHT_PX) * 1.18, 1.18, DELIMITER_MAX_SCALE);\n pair.style.setProperty('--butex-delim-scale', scale.toFixed(3));\n}\n\nfunction visibleDelimiter(expr: string): string {\n return expr\n .replace('\\\\left', '')\n .replace('\\\\right', '')\n .replace('\\\\{', '{')\n .replace('\\\\}', '}');\n}\n\nexport function buildDelimiterNodeBody(node: EditorNode, buildChain: BuildChain): HTMLElement {\n const pair = document.createElement('span');\n pair.className = 'delim-pair';\n\n const left = document.createElement('span');\n left.className = 'delim delim--left';\n const leftGlyph = document.createElement('span');\n leftGlyph.className = 'delim-glyph';\n leftGlyph.textContent = visibleDelimiter(node.leftDelimExpr);\n left.appendChild(leftGlyph);\n pair.appendChild(left);\n\n const inner = document.createElement('span');\n inner.className = 'delim-inner';\n if (node.innerExpr) {\n inner.appendChild(buildChain(node.innerExpr));\n }\n pair.appendChild(inner);\n\n const right = document.createElement('span');\n right.className = 'delim delim--right';\n const rightGlyph = document.createElement('span');\n rightGlyph.className = 'delim-glyph';\n rightGlyph.textContent = visibleDelimiter(node.rightDelimExpr);\n right.appendChild(rightGlyph);\n pair.appendChild(right);\n\n applyDelimiterScale(pair, inner);\n requestAnimationFrame(() => applyDelimiterScale(pair, inner));\n\n return pair;\n}\n","import type { EditorChain, EditorNode } from '../types.js';\n\ntype BuildChain = (chain: EditorChain) => HTMLElement;\n\nexport const FRAC_CSS = `\n.frac {\n display: inline-flex;\n flex-direction: column;\n align-items: stretch;\n justify-content: center;\n vertical-align: middle;\n margin: 0 3px;\n min-width: 1.5em;\n}\n\n.frac-num,\n.frac-den {\n display: inline-flex;\n justify-content: center;\n align-items: center;\n min-height: 1.1em;\n padding: 0 4px;\n}\n\n.frac-bar {\n align-self: stretch;\n height: 1px;\n background: var(--butex-frac-bar, currentColor);\n opacity: 0.88;\n}\n`.trim();\n\nexport function buildFracNodeBody(node: EditorNode, buildChain: BuildChain): HTMLElement {\n const wrap = document.createElement('span');\n wrap.className = 'frac';\n\n const num = document.createElement('span');\n num.className = 'frac-num';\n if (node.numerator) {\n num.appendChild(buildChain(node.numerator));\n }\n\n const bar = document.createElement('span');\n bar.className = 'frac-bar';\n bar.setAttribute('aria-hidden', 'true');\n\n const den = document.createElement('span');\n den.className = 'frac-den';\n if (node.denominator) {\n den.appendChild(buildChain(node.denominator));\n }\n\n wrap.appendChild(num);\n wrap.appendChild(bar);\n wrap.appendChild(den);\n\n return wrap;\n}\n","import type { EditorChain, EditorNode, EditorSide } from '../types.js';\n\ntype BuildChain = (chain: EditorChain) => HTMLElement;\n\nexport const SQRT_CSS = `\n.sqrt {\n display: inline-flex;\n align-items: stretch;\n position: relative;\n vertical-align: middle;\n margin: 0 2px;\n min-height: 2.1em;\n direction: ltr;\n --butex-sqrt-scale: 1;\n}\n\n.sqrt.sqrt--english .sqrt-root {\n order: 1;\n}\n\n.sqrt.sqrt--english .sqrt-sign {\n order: 2;\n}\n\n.sqrt.sqrt--english .sqrt-radicand {\n order: 3;\n}\n\n.sqrt.sqrt--arabic .sqrt-radicand {\n order: 1;\n}\n\n.sqrt.sqrt--arabic .sqrt-sign {\n order: 2;\n}\n\n.sqrt.sqrt--arabic .sqrt-root {\n order: 3;\n}\n\n.sqrt.sqrt--arabic .sqrt-root,\n.sqrt.sqrt--arabic .sqrt-radicand {\n direction: rtl;\n}\n\n.sqrt-root {\n align-self: flex-start;\n min-width: 0.9em;\n min-height: 1em;\n margin-inline-end: -0.18em;\n transform: translate(0.16em, 0.02em);\n font-size: 0.64em;\n line-height: 1;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n position: relative;\n z-index: 1;\n}\n\n.sqrt.sqrt--arabic .sqrt-root {\n margin-inline-start: -0.22em;\n margin-inline-end: 0;\n transform: translate(-0.16em, 0.02em);\n}\n\n.sqrt-root .chain {\n min-height: auto;\n}\n\n.sqrt-sign {\n display: inline-flex;\n align-items: flex-end;\n justify-content: center;\n align-self: stretch;\n line-height: 0.78;\n font-size: 2em;\n color: var(--butex-sqrt-color, currentColor);\n transform: scaleY(var(--butex-sqrt-scale));\n transform-origin: center bottom;\n margin-inline-end: -0.24em;\n min-height: 100%;\n position: relative;\n z-index: 1;\n}\n\n.sqrt.sqrt--arabic .sqrt-sign {\n transform: scaleX(-1) scaleY(var(--butex-sqrt-scale));\n margin-inline-start: -0.24em;\n margin-inline-end: 0;\n}\n\n.sqrt-radicand {\n display: inline-flex;\n align-items: center;\n min-width: 1.35em;\n min-height: 1.35em;\n padding: 0.06em 0.24em 0;\n border-top: 2px solid var(--butex-sqrt-bar, currentColor);\n transform: translateY(-0.08em);\n position: relative;\n}\n\n.sqrt-radicand .chain {\n min-height: auto;\n}\n`.trim();\n\nconst SQRT_BASE_HEIGHT_PX = 32;\nconst SQRT_MAX_SCALE = 3.8;\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, value));\n}\n\nfunction applySqrtScale(wrap: HTMLElement, radicand: HTMLElement): void {\n const radicandHeight = Math.max(radicand.getBoundingClientRect().height, SQRT_BASE_HEIGHT_PX);\n const scale = clamp(radicandHeight / SQRT_BASE_HEIGHT_PX, 1, SQRT_MAX_SCALE);\n wrap.style.setProperty('--butex-sqrt-scale', scale.toFixed(3));\n}\n\nexport function buildSqrtNodeBody(node: EditorNode, buildChain: BuildChain, side: EditorSide): HTMLElement {\n const wrap = document.createElement('span');\n wrap.className = `sqrt sqrt--${side}`;\n\n const root = document.createElement('span');\n root.className = 'sqrt-root';\n if (node.rootIndex) {\n root.appendChild(buildChain(node.rootIndex));\n }\n\n const sign = document.createElement('span');\n sign.className = 'sqrt-sign';\n sign.setAttribute('aria-hidden', 'true');\n sign.textContent = '\\u221a';\n\n const radicand = document.createElement('span');\n radicand.className = 'sqrt-radicand';\n if (node.radicand) {\n radicand.appendChild(buildChain(node.radicand));\n }\n\n wrap.appendChild(root);\n wrap.appendChild(sign);\n wrap.appendChild(radicand);\n\n applySqrtScale(wrap, radicand);\n requestAnimationFrame(() => applySqrtScale(wrap, radicand));\n\n return wrap;\n}\n","import type { EditorChain, EditorNode } from '../types.js';\n\ntype BuildChain = (chain: EditorChain) => HTMLElement;\n\nexport const OVERSET_CSS = `\n.overset {\n display: inline-flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n vertical-align: middle;\n margin: 0 2px;\n min-width: 1.2em;\n}\n\n.overset-over {\n display: inline-flex;\n justify-content: center;\n align-items: center;\n min-height: 0.85em;\n padding: 0 2px;\n font-size: 0.72em;\n line-height: 1.1;\n}\n\n.overset-base {\n display: inline-flex;\n justify-content: center;\n align-items: center;\n min-height: 1.05em;\n padding: 0 2px;\n}\n`.trim();\n\nexport function buildOversetNodeBody(node: EditorNode, buildChain: BuildChain): HTMLElement {\n const wrap = document.createElement('span');\n wrap.className = 'overset';\n\n const over = document.createElement('span');\n over.className = 'overset-over';\n if (node.overExpr) {\n over.appendChild(buildChain(node.overExpr));\n }\n\n const base = document.createElement('span');\n base.className = 'overset-base';\n if (node.baseExpr) {\n base.appendChild(buildChain(node.baseExpr));\n }\n\n wrap.appendChild(over);\n wrap.appendChild(base);\n return wrap;\n}\n","import type { EditorChain, EditorNode } from '../types.js';\n\ntype BuildChain = (chain: EditorChain) => HTMLElement;\n\nexport const UNDERSET_CSS = `\n.underset {\n display: inline-flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n vertical-align: middle;\n margin: 0 2px;\n min-width: 1.2em;\n}\n\n.underset-base {\n display: inline-flex;\n justify-content: center;\n align-items: center;\n min-height: 1.05em;\n padding: 0 2px;\n}\n\n.underset-under {\n display: inline-flex;\n justify-content: center;\n align-items: center;\n min-height: 0.85em;\n padding: 0 2px;\n font-size: 0.72em;\n line-height: 1.1;\n}\n`.trim();\n\nexport function buildUndersetNodeBody(node: EditorNode, buildChain: BuildChain): HTMLElement {\n const wrap = document.createElement('span');\n wrap.className = 'underset';\n\n const base = document.createElement('span');\n base.className = 'underset-base';\n if (node.baseExpr) {\n base.appendChild(buildChain(node.baseExpr));\n }\n\n const under = document.createElement('span');\n under.className = 'underset-under';\n if (node.underExpr) {\n under.appendChild(buildChain(node.underExpr));\n }\n\n wrap.appendChild(base);\n wrap.appendChild(under);\n return wrap;\n}\n","import { accentCommandSpec } from '../accentCommands.js';\nimport type { EditorChain, EditorNode } from '../types.js';\n\ntype BuildChain = (chain: EditorChain) => HTMLElement;\n\nexport const ACCENT_CSS = `\n.math-accent {\n display: inline-flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n vertical-align: middle;\n margin: 0 2px;\n min-width: 1.1em;\n}\n\n.math-accent-chrome {\n display: inline-flex;\n justify-content: center;\n align-items: center;\n min-height: 0.7em;\n padding: 0 2px;\n font-size: 0.85em;\n line-height: 1;\n color: var(--butex-script-color, #475569);\n user-select: none;\n}\n\n.math-accent-base {\n display: inline-flex;\n justify-content: center;\n align-items: center;\n min-height: 1.05em;\n padding: 0 2px;\n}\n\n.math-accent--under .math-accent-chrome {\n min-height: 0.45em;\n border-top: 1.5px solid currentColor;\n width: 100%;\n font-size: 0;\n color: var(--butex-surface-fg, #0f172a);\n}\n`.trim();\n\nexport function buildAccentNodeBody(node: EditorNode, buildChain: BuildChain): HTMLElement {\n const wrap = document.createElement('span');\n const spec = accentCommandSpec(node.expr);\n const placement = spec?.placement ?? 'over';\n wrap.className = placement === 'under' ? 'math-accent math-accent--under' : 'math-accent math-accent--over';\n\n const chrome = document.createElement('span');\n chrome.className = 'math-accent-chrome';\n chrome.setAttribute('aria-hidden', 'true');\n if (placement === 'over') {\n chrome.textContent = spec?.label ?? 'ˆ';\n }\n\n const base = document.createElement('span');\n base.className = 'math-accent-base';\n if (node.baseExpr) {\n base.appendChild(buildChain(node.baseExpr));\n }\n\n if (placement === 'under') {\n wrap.appendChild(base);\n wrap.appendChild(chrome);\n } else {\n wrap.appendChild(chrome);\n wrap.appendChild(base);\n }\n return wrap;\n}\n","import type { EditorChain, EditorNode, EditorSide, MatrixEnvStyle } from '../types.js';\n\ntype BuildChain = (chain: EditorChain) => HTMLElement;\n\nconst WRAPPERS: Record<MatrixEnvStyle, { left: string; right: string }> = {\n matrix: { left: '', right: '' },\n pmatrix: { left: '(', right: ')' },\n bmatrix: { left: '[', right: ']' },\n Bmatrix: { left: '{', right: '}' },\n vmatrix: { left: '|', right: '|' },\n Vmatrix: { left: '||', right: '||' },\n};\n\nexport const MATRIX_ENV_CSS = `\n.matrix-env {\n display: inline-flex;\n align-items: stretch;\n vertical-align: middle;\n margin: 0 3px;\n --butex-matrix-delim-scale: 1.25;\n}\n\n.matrix-env__wrapper {\n display: inline-flex;\n align-self: stretch;\n align-items: center;\n justify-content: center;\n min-width: 0.42em;\n padding: 0 2px;\n color: var(--butex-delim-color, currentColor);\n font-family: ui-serif, \"Cambria Math\", \"Times New Roman\", serif;\n font-size: clamp(22px, 1.35em + 0.8vh, 42px);\n line-height: 1;\n transform: scaleY(var(--butex-matrix-delim-scale));\n transform-origin: center;\n}\n\n.matrix-env__grid {\n display: inline-grid;\n direction: ltr;\n gap: 2px 5px;\n align-items: center;\n justify-items: center;\n padding: 2px 3px;\n}\n\n.matrix-env__cell {\n min-width: 1.35em;\n min-height: 1.45em;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border-radius: 5px;\n border: 1px dashed rgba(148, 163, 184, 0.48);\n padding: 1px 3px;\n}\n\n.matrix-env__cell .chain {\n min-height: auto;\n}\n\n.matrix-env--arabic .matrix-env__cell {\n direction: rtl;\n}\n\n.matrix-env--english .matrix-env__cell {\n direction: ltr;\n}\n`.trim();\n\nconst MATRIX_DELIMITER_BASE_HEIGHT_PX = 20;\nconst MATRIX_DELIMITER_MAX_SCALE = 5.2;\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, value));\n}\n\nfunction applyMatrixDelimiterScale(wrap: HTMLElement, grid: HTMLElement): void {\n const gridHeight = Math.max(grid.getBoundingClientRect().height, MATRIX_DELIMITER_BASE_HEIGHT_PX);\n const scale = clamp((gridHeight / MATRIX_DELIMITER_BASE_HEIGHT_PX) * 1.22, 1.25, MATRIX_DELIMITER_MAX_SCALE);\n wrap.style.setProperty('--butex-matrix-delim-scale', scale.toFixed(3));\n}\n\nexport function buildMatrixEnvNodeBody(node: EditorNode, buildChain: BuildChain, side: EditorSide): HTMLElement {\n const wrap = document.createElement('span');\n wrap.className = `matrix-env matrix-env--${side}`;\n\n const style = node.envName ?? node.matrixStyle ?? 'matrix';\n const glyphs = style === 'array' || style === 'aligned' ? undefined : WRAPPERS[style];\n\n const left = document.createElement('span');\n left.className = 'matrix-env__wrapper matrix-env__wrapper--left';\n left.textContent = glyphs?.left ?? '';\n\n const grid = document.createElement('span');\n grid.className = 'matrix-env__grid';\n\n const rows = node.matrixRows ?? [];\n const columnCount = Math.max(1, ...rows.map((row) => row.length));\n grid.style.gridTemplateColumns = `repeat(${String(columnCount)}, minmax(1.35em, auto))`;\n\n const displayRows = side === 'arabic' ? rows.map((row) => row.slice().reverse()) : rows;\n for (const row of displayRows) {\n for (const cellChain of row) {\n const cell = document.createElement('span');\n cell.className = 'matrix-env__cell';\n cell.dir = side === 'arabic' ? 'rtl' : 'ltr';\n cell.appendChild(buildChain(cellChain));\n grid.appendChild(cell);\n }\n }\n\n const right = document.createElement('span');\n right.className = 'matrix-env__wrapper matrix-env__wrapper--right';\n right.textContent = glyphs?.right ?? '';\n\n wrap.appendChild(left);\n wrap.appendChild(grid);\n wrap.appendChild(right);\n\n applyMatrixDelimiterScale(wrap, grid);\n requestAnimationFrame(() => applyMatrixDelimiterScale(wrap, grid));\n\n return wrap;\n}\n","import diwaniLetterUrl from './fonts/Diwani Letter Regular.ttf';\nimport diwaniOutlineUrl from './fonts/DWNOUTSH.TTF';\nimport maghribiUrl from './fonts/Almaghribi-Warsh-Quran.otf';\nimport takweenUrl from './fonts/Takween.otf';\n\n\nexport const BUTEX_DIWANI_FONT_FAMILY = 'Diwani Letter';\nexport const BUTEX_DIWANI_OUTLINE_FONT_FAMILY = 'BuTeX Diwani Outline';\nexport const BUTEX_MAGHRIBI_FONT_FAMILY = 'Almaghribi Warsh Quran';\nexport const BUTEX_TAKWEEN_FONT_FAMILY = 'BuTeX Takween';\n\nexport const BUTEX_DIWANI_FONT_STACK = `\"${BUTEX_DIWANI_FONT_FAMILY}\", Amiri, \"Segoe UI\", Tahoma, sans-serif`;\nexport const BUTEX_DIWANI_OUTLINE_FONT_STACK = `\"${BUTEX_DIWANI_OUTLINE_FONT_FAMILY}\", \"${BUTEX_DIWANI_FONT_FAMILY}\", Amiri, \"Segoe UI\", Tahoma, sans-serif`;\nexport const BUTEX_MAGHRIBI_FONT_STACK = `\"${BUTEX_MAGHRIBI_FONT_FAMILY}\", Amiri, \"Segoe UI\", Tahoma, sans-serif`;\nexport const BUTEX_TAKWEEN_FONT_STACK = `\"${BUTEX_TAKWEEN_FONT_FAMILY}\", Amiri, \"Segoe UI\", Tahoma, sans-serif`;\n\nexport const BUTEX_DIWANI_FONT_FACE_CSS = `\n@font-face {\n font-family: \"${BUTEX_DIWANI_FONT_FAMILY}\";\n src: url(\"${diwaniLetterUrl}\") format(\"truetype\");\n font-weight: 400;\n font-style: normal;\n font-display: swap;\n}\n`.trim();\n\nexport const BUTEX_TAKWEEN_FONT_FACE_CSS = `\n@font-face {\n font-family: \"${BUTEX_TAKWEEN_FONT_FAMILY}\";\n src: url(\"${takweenUrl}\") format(\"opentype\");\n font-weight: 400;\n font-style: normal;\n font-display: swap;\n}\n`.trim();\n\nexport const BUTEX_DIWANI_OUTLINE_FONT_FACE_CSS = `\n@font-face {\n font-family: \"${BUTEX_DIWANI_OUTLINE_FONT_FAMILY}\";\n src: url(\"${diwaniOutlineUrl}\") format(\"truetype\");\n font-weight: 400;\n font-style: normal;\n font-display: swap;\n}\n`.trim();\n\nexport const BUTEX_MAGHRIBI_FONT_FACE_CSS = `\n@font-face {\n font-family: \"${BUTEX_MAGHRIBI_FONT_FAMILY}\";\n src: url(\"${maghribiUrl}\") format(\"opentype\");\n font-weight: 400;\n font-style: normal;\n font-display: swap;\n}\n`.trim();\n\nexport const BUTEX_FONT_FACE_CSS = `\n${BUTEX_DIWANI_FONT_FACE_CSS}\n\n${BUTEX_DIWANI_OUTLINE_FONT_FACE_CSS}\n\n${BUTEX_TAKWEEN_FONT_FACE_CSS}\n\n${BUTEX_MAGHRIBI_FONT_FACE_CSS}\n`.trim();\n","import { atomicCommandSpec, isSpacingCommandSpec, type AtomicCommandSpec, type SpacingCommandSpec } from '../atomicCommands.js';\nimport { BUTEX_DIWANI_FONT_STACK, BUTEX_DIWANI_OUTLINE_FONT_STACK } from '../../diwani-font.js';\nimport type { EditorNode, EditorSide } from '../types.js';\nimport type { ButexUiLocale } from '../../uiLocale.js';\nimport { atomicCommandTitle } from '../uiLocale.js';\n\nexport const ATOMIC_COMMAND_CSS = `\n/* Shared atomic-command display */\n.atomic-command {\n display: inline-flex;\n align-items: center;\n font-weight: 600;\n line-height: 1;\n}\n\n/* Function-style commands: sin/cos/tan families. */\n.atomic-command--arabic {\n font-family: ${BUTEX_DIWANI_FONT_STACK};\n font-size: 1.15em;\n direction: rtl;\n}\n\n.atomic-command--diwani-outline {\n font-family: ${BUTEX_DIWANI_OUTLINE_FONT_STACK};\n}\n\n.atomic-command--english {\n font-family: \"Cambria Math\", \"Times New Roman\", serif;\n font-size: 0.96em;\n}\n\n.atomic-command-label-with-sub {\n position: relative;\n display: inline-block;\n padding-inline-end: 0.45em;\n padding-block-end: 0.22em;\n line-height: 1;\n}\n\n.atomic-command-label-with-sub__sub {\n position: absolute;\n inset-inline-end: 0;\n inset-block-end: 0;\n font-size: 0.62em;\n line-height: 1;\n}\n\n/* Spacing commands: tiny selectable marker, real spacing remains in LaTeX preview. */\n.atomic-spacing {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 3px;\n min-width: 3px;\n height: 1em;\n color: var(--butex-accent, currentColor);\n opacity: 0.62;\n}\n\n.atomic-spacing__marker {\n display: inline-block;\n width: 3px;\n height: 0.85em;\n border-radius: 999px;\n background: currentColor;\n}\n\n.atomic-spacing--negative {\n color: var(--butex-danger, #dc2626);\n}\n`.trim();\n\nfunction spacingArrowForSide(spec: SpacingCommandSpec, side: EditorSide): string {\n const pointsWithFlow = spec.spacing.direction === 'positive';\n if (pointsWithFlow) {\n return side === 'arabic' ? '\\u2190' : '\\u2192';\n }\n return side === 'arabic' ? '\\u2192' : '\\u2190';\n}\n\nexport function spacingTooltipForSide(spec: SpacingCommandSpec, side: EditorSide, uiLocale: ButexUiLocale = 'ar'): string {\n return `${atomicCommandTitle(spec, uiLocale)} ${spacingArrowForSide(spec, side).repeat(spec.spacing.level)}`;\n}\n\nfunction buildFunctionAtomicCommandBody(node: EditorNode, side: EditorSide, spec: AtomicCommandSpec | null): HTMLElement {\n const value = document.createElement('span');\n value.className = `atomic-command atomic-command--${side}`;\n if (side === 'arabic' && spec?.category === 'groups') {\n value.classList.add('atomic-command--diwani-outline');\n }\n if (side === 'arabic' && node.expr === 'ln') {\n const label = document.createElement('span');\n label.className = 'atomic-command-label-with-sub';\n const base = document.createElement('span');\n base.className = 'atomic-command-label-with-sub__base';\n base.textContent = spec?.arabicLabel ?? node.expr;\n const sub = document.createElement('span');\n sub.className = 'atomic-command-label-with-sub__sub';\n sub.textContent = 'هـ';\n label.append(base, sub);\n value.appendChild(label);\n return value;\n }\n value.textContent = side === 'arabic'\n ? spec?.arabicLabel ?? node.expr\n : spec?.englishLabel ?? spec?.englishTex.replace(/^\\\\/, '') ?? node.expr;\n return value;\n}\n\nfunction buildSpacingAtomicCommandBody(spec: SpacingCommandSpec, side: EditorSide, uiLocale: ButexUiLocale): HTMLElement {\n const value = document.createElement('span');\n value.className = `atomic-spacing atomic-spacing--${spec.spacing.direction} atomic-spacing--level-${String(spec.spacing.level)}`;\n value.title = spacingTooltipForSide(spec, side, uiLocale);\n const marker = document.createElement('span');\n marker.className = 'atomic-spacing__marker';\n value.appendChild(marker);\n return value;\n}\n\nexport function buildAtomicCommandNodeBody(node: EditorNode, side: EditorSide, uiLocale: ButexUiLocale = 'ar'): HTMLElement {\n const spec = atomicCommandSpec(node.expr);\n if (isSpacingCommandSpec(spec)) {\n return buildSpacingAtomicCommandBody(spec, side, uiLocale);\n }\n return buildFunctionAtomicCommandBody(node, side, spec);\n}\n","import { atomicOperatorCommandSpec, shouldMirrorOperatorDisplay, type AtomicOperatorCommandSpec } from '../atomicCommandsOperators.js';\nimport type { EditorNode, EditorSide } from '../types.js';\nimport type { ButexUiLocale } from '../../uiLocale.js';\nimport { atomicOperatorCommandTitle } from '../uiLocale.js';\n\nexport const ATOMIC_OPERATOR_COMMAND_CSS = `\n.atomic-operator-command {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 0.9em;\n font-family: \"Cambria Math\", \"Times New Roman\", serif;\n font-size: 1.05em;\n font-weight: 600;\n line-height: 1;\n}\n\n.atomic-operator-command--mirrored {\n transform: scaleX(-1);\n}\n\n.atomic-operator-command__svg {\n width: 1em;\n height: 1em;\n background: currentColor;\n}\n`.trim();\n\nfunction buildOperatorLabel(spec: AtomicOperatorCommandSpec): HTMLElement {\n const value = document.createElement('span');\n value.className = 'atomic-operator-command__label';\n value.textContent = spec.Label;\n return value;\n}\n\nexport function buildAtomicOperatorCommandNodeBody(node: EditorNode, side: EditorSide, uiLocale: ButexUiLocale = 'ar'): HTMLElement {\n const spec = atomicOperatorCommandSpec(node.expr);\n const value = document.createElement('span');\n value.className = 'atomic-operator-command';\n value.title = spec ? atomicOperatorCommandTitle(spec, uiLocale) : node.expr;\n if (side === 'arabic' && shouldMirrorOperatorDisplay(spec)) {\n value.classList.add('atomic-operator-command--mirrored');\n }\n\n if (spec?.svg_path) {\n const icon = document.createElement('span');\n icon.className = 'atomic-operator-command__svg';\n icon.style.mask = `url(\"${spec.svg_path}\") center / contain no-repeat`;\n icon.style.webkitMask = `url(\"${spec.svg_path}\") center / contain no-repeat`;\n value.appendChild(icon);\n return value;\n }\n\n if (spec) {\n value.appendChild(buildOperatorLabel(spec));\n } else {\n const label = document.createElement('span');\n label.className = 'atomic-operator-command__label';\n label.textContent = node.expr;\n value.appendChild(label);\n }\n return value;\n}\n","import { DELIMITER_CSS } from './display/delimiter.js';\nimport { FRAC_CSS } from './display/frac.js';\nimport { SQRT_CSS } from './display/sqrt.js';\nimport { OVERSET_CSS } from './display/overset.js';\nimport { UNDERSET_CSS } from './display/underset.js';\nimport { ACCENT_CSS } from './display/accent.js';\nimport { MATRIX_ENV_CSS } from './display/env.js';\nimport { ATOMIC_COMMAND_CSS } from './display/atomicCommand.js';\nimport { ATOMIC_OPERATOR_COMMAND_CSS } from './display/atomicCommandsOperators.js';\nimport { BUTEX_FONT_FACE_CSS } from '../diwani-font.js';\nimport { NON_DEFAULT_CHARACTER_FONT_SPECS } from './characterFonts.js';\n\nconst CHARACTER_FONT_CSS = NON_DEFAULT_CHARACTER_FONT_SPECS\n .filter((font) => font.cssClass && font.browserFontStack)\n .map((font) => `.${font.cssClass} {\\n font-family: ${font.browserFontStack};\\n}`)\n .join('\\n\\n');\n\nexport const BUTEX_EDITOR_CSS = `\n${BUTEX_FONT_FACE_CSS}\n\n.surface {\n border: 1px solid var(--butex-border, #e2e8f0);\n border-radius: 12px;\n min-height: 100px;\n padding: 8px 10px;\n background: var(--butex-surface-bg, linear-gradient(180deg, #ffffff 0%, #fafbfc 100%));\n color: var(--butex-surface-fg, #0f172a);\n outline: none;\n cursor: text;\n transition: box-shadow 0.15s ease, border-color 0.15s ease;\n}\n\n.surface:focus,\n.surface.surface--typing-focus {\n border-color: var(--butex-focus-border, rgba(13, 148, 136, 0.45));\n box-shadow: 0 0 0 3px var(--butex-focus-shadow, rgba(13, 148, 136, 0.12));\n}\n\n.surface.surface--arabic {\n direction: rtl;\n}\n\n.surface.surface--english {\n direction: ltr;\n}\n\n${CHARACTER_FONT_CSS}\n\n.chain {\n display: inline-flex;\n align-items: center;\n gap: 0;\n min-height: 28px;\n flex-wrap: wrap;\n row-gap: 2px;\n}\n\n.slot {\n width: 5px;\n min-height: 28px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n border-radius: 3px;\n}\n\n.slot:hover {\n background: var(--butex-slot-hover, rgba(13, 148, 136, 0.08));\n}\n\n.slot.range-highlight {\n background: var(--butex-selection-bg, rgba(13, 148, 136, 0.34));\n width: 11px;\n min-height: 42px;\n border: 2px solid var(--butex-selection-border, rgba(15, 118, 110, 0.9));\n position: relative;\n z-index: 1;\n}\n\n.caret {\n display: inline-block;\n width: 2px;\n height: 20px;\n background: var(--butex-caret, #0f172a);\n border-radius: 1px;\n animation: butex-editor-blink 1s step-end infinite;\n}\n\n@keyframes butex-editor-blink {\n 50% { opacity: 0; }\n}\n\n.node {\n display: inline-flex;\n align-items: stretch;\n gap: 3px;\n border-radius: 8px;\n padding: 2px 4px;\n cursor: pointer;\n border: 1px solid transparent;\n user-select: none;\n}\n\n.node.node--atomic-spacing {\n padding-inline: 0;\n margin-inline: -2px;\n border-color: transparent;\n}\n\n.node:hover {\n border-color: var(--butex-border, #e2e8f0);\n background: var(--butex-node-hover, rgba(148, 163, 184, 0.08));\n}\n\n.node.selected {\n background: var(--butex-node-selected-bg, rgba(13, 148, 136, 0.14));\n border-color: var(--butex-node-selected-border, rgba(13, 148, 136, 0.45));\n}\n\n.node.range-highlight {\n background: var(--butex-selection-bg, rgba(13, 148, 136, 0.34));\n border-color: var(--butex-selection-border, rgba(15, 118, 110, 0.9));\n box-shadow: inset 0 0 0 3px var(--butex-selection-border, rgba(15, 118, 110, 0.9)),\n 0 0 0 1px var(--butex-selection-border, rgba(15, 118, 110, 0.9));\n position: relative;\n z-index: 2;\n}\n\n.chain .slot.range-highlight + .node.range-highlight,\n.chain .node.range-highlight + .slot.range-highlight {\n margin-inline: -1px;\n}\n\n.node-body {\n display: inline-flex;\n align-items: stretch;\n gap: 0;\n min-height: 1.6em;\n}\n\n.node-value {\n font-size: 16px;\n font-weight: 500;\n line-height: 1.25;\n display: inline-flex;\n align-items: center;\n}\n\n.scripts {\n display: flex;\n flex-direction: column;\n flex-shrink: 0;\n justify-content: space-between;\n align-items: center;\n padding: 1px 0;\n min-width: 0.75em;\n}\n\n.scripts.scripts--sup-only {\n justify-content: flex-start;\n padding-bottom: 2px;\n}\n\n.scripts.scripts--sub-only {\n justify-content: flex-end;\n padding-top: 2px;\n}\n\n.script-box {\n min-height: 12px;\n min-width: 10px;\n border-radius: 4px;\n border: 1px dashed var(--butex-script-border, #cbd5e1);\n padding: 0 2px;\n font-size: 0.68em;\n line-height: 1.15;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n background: var(--butex-script-bg, rgba(248, 250, 252, 0.95));\n color: var(--butex-script-color, #475569);\n}\n\n.script-box .chain {\n min-height: auto;\n}\n\n${DELIMITER_CSS}\n\n${FRAC_CSS}\n\n${SQRT_CSS}\n\n${OVERSET_CSS}\n\n${UNDERSET_CSS}\n\n${ACCENT_CSS}\n\n${MATRIX_ENV_CSS}\n\n${ATOMIC_COMMAND_CSS}\n\n${ATOMIC_OPERATOR_COMMAND_CSS}\n`.trim();\n\n/**\n * Injects BuTeX editor surface styles into `document.head` if not already present.\n * Browser-only; no-op if `document` is undefined (Node).\n */\nexport function injectBuTeXEditorStyles(doc?: Document): void {\n const d = doc ?? (typeof document !== 'undefined' ? document : undefined);\n if (!d) {\n return;\n }\n const id = 'butex-editor-styles';\n const existing = d.getElementById(id);\n if (existing) {\n existing.textContent = BUTEX_EDITOR_CSS;\n return;\n }\n const style = d.createElement('style');\n style.id = id;\n style.textContent = BUTEX_EDITOR_CSS;\n d.head.appendChild(style);\n}\n","import type { CharacterFontId } from '../editor/types.js';\nimport { NON_DEFAULT_CHARACTER_FONT_SPECS } from '../editor/characterFonts.js';\n\nexport type NormalizedCharImport = {\n expr: string;\n characterFont: CharacterFontId;\n};\n\ntype WrapperSpec = {\n prefix: string;\n font?: CharacterFontId;\n};\n\nconst WRAPPER_SPECS: WrapperSpec[] = [\n ...NON_DEFAULT_CHARACTER_FONT_SPECS.flatMap((font) => [\n { prefix: font.macro, font: font.id },\n ...(font.importAliases ?? []).map((alias) => ({ prefix: alias, font: font.id })),\n ]),\n { prefix: '\\\\text' },\n];\n\nfunction readBracedArg(source: string, openBraceIndex: number): { inner: string; end: number } | null {\n if (source[openBraceIndex] !== '{') {\n return null;\n }\n\n let depth = 0;\n for (let index = openBraceIndex; index < source.length; index += 1) {\n const char = source[index];\n if (char === '{') {\n depth += 1;\n } else if (char === '}') {\n depth -= 1;\n if (depth === 0) {\n return { inner: source.slice(openBraceIndex + 1, index), end: index + 1 };\n }\n }\n }\n\n return null;\n}\n\nfunction peelWrapper(source: string): { inner: string; font?: CharacterFontId } | null {\n for (const wrapper of WRAPPER_SPECS) {\n if (!source.startsWith(wrapper.prefix)) {\n continue;\n }\n\n const braced = readBracedArg(source, wrapper.prefix.length);\n if (!braced || braced.end !== source.length) {\n continue;\n }\n\n return { inner: braced.inner, font: wrapper.font };\n }\n\n return null;\n}\n\nexport function normalizeCharImportExpr(expr: string): NormalizedCharImport {\n const original = expr;\n let current = expr;\n let characterFont: CharacterFontId = 'default';\n let changed = false;\n\n while (true) {\n const peeled = peelWrapper(current);\n if (!peeled) {\n break;\n }\n\n current = peeled.inner;\n if (peeled.font) {\n characterFont = peeled.font;\n }\n changed = true;\n }\n\n if (!changed) {\n return { expr: original, characterFont: 'default' };\n }\n\n if (current.includes('\\\\')) {\n return { expr: original, characterFont: 'default' };\n }\n\n return { expr: current, characterFont };\n}\n","import {\n BaseAstNode,\n ChainNode,\n CharNode,\n CommandNode,\n DelimiterNode,\n EnvNode,\n NumberNode,\n OperatorNode,\n} from '../ast/arabic_ast.js';\nimport {\n accentCommandIdFromTex,\n accentCommandSpec,\n} from '../editor/accentCommands.js';\nimport {\n ATOMIC_COMMANDS,\n atomicCommandSpec,\n type AtomicCommandId,\n} from '../editor/atomicCommands.js';\nimport {\n ATOMIC_OPERATOR_COMMANDS,\n atomicOperatorCommandSpec,\n type AtomicOperatorCommandId,\n} from '../editor/atomicCommandsOperators.js';\nimport {\n buildInitialSyncMap,\n cloneEditorSession,\n createAccentNode,\n createDelimiterNode,\n createEditorChain,\n createEditorNode,\n createEditorSession,\n createFracNode,\n createGridEnvNode,\n createSqrtNode,\n createOversetNode,\n createUndersetNode,\n renderArabicLatexFromSession,\n} from '../editor/index.js';\nimport { NON_DEFAULT_CHARACTER_FONT_SPECS } from '../editor/characterFonts.js';\nimport type {\n CharacterFontId,\n EditorChain,\n EditorNode,\n EditorSession,\n EnvColumnAlignment,\n GridEnvName,\n MatrixEnvStyle,\n} from '../editor/index.js';\nimport { normalizeCharImportExpr } from './normalizeCharImport.js';\nimport type { MathNode } from './types.js';\n\ntype CommandFontPolicy = CharacterFontId | 'infer';\n\nconst COMMAND_FONT_MAP: Record<string, CommandFontPolicy> = Object.fromEntries([\n ['\\\\text', 'infer'],\n ...NON_DEFAULT_CHARACTER_FONT_SPECS.flatMap((font) => [\n [font.macro, font.id],\n ...(font.importAliases ?? []).map((alias) => [alias, font.id]),\n ]),\n]) as Record<string, CommandFontPolicy>;\n\nconst CHAR_FONT_EXPORT_TEX: Record<Exclude<CharacterFontId, 'default'>, string> = Object.fromEntries(\n NON_DEFAULT_CHARACTER_FONT_SPECS.map((font) => [font.id, font.macro]),\n) as Record<Exclude<CharacterFontId, 'default'>, string>;\n\nfunction charEditorNodeToAstNode(node: EditorNode): BaseAstNode {\n const font = node.characterFont ?? 'default';\n const charNode = new CharNode(node.expr);\n if (font === 'default') {\n return charNode;\n }\n return new CommandNode(CHAR_FONT_EXPORT_TEX[font], [], [new ChainNode([charNode])]);\n}\n\nexport type MathEditorAdapterResult =\n | { editable: true; session: EditorSession }\n | { editable: false; reason: string };\n\ntype NodeAdapterResult =\n | { editable: true; node: EditorNode }\n | { editable: false; reason: string };\n\ntype UnsupportedAdapterResult = { editable: false; reason: string };\n\nexport type MathNodeFromEditorResult =\n | { ok: true; math: MathNode }\n | { ok: false; reason: string };\n\nfunction commandIdForTex(tex: string): AtomicCommandId | null {\n for (const spec of Object.values(ATOMIC_COMMANDS)) {\n const renderTex = (spec as { arabicRenderTex?: string }).arabicRenderTex;\n if (spec.englishTex === tex || spec.arabicTex === tex || renderTex === tex) {\n return spec.id as AtomicCommandId;\n }\n }\n return null;\n}\n\nfunction operatorCommandIdForTex(tex: string): AtomicOperatorCommandId | null {\n for (const spec of Object.values(ATOMIC_OPERATOR_COMMANDS)) {\n if (spec.Tex === tex) {\n return spec.id as AtomicOperatorCommandId;\n }\n }\n return null;\n}\n\nfunction cloneChainWithFreshIds(chain: EditorChain): EditorChain {\n return structuredClone(chain);\n}\n\nfunction attachScripts(astNode: { superscript: ChainNode | null; subscript: ChainNode | null }, editorNode: EditorNode): UnsupportedAdapterResult | null {\n if (astNode.superscript) {\n const sup = chainToEditorChain(astNode.superscript);\n if (!sup.editable) {\n return sup;\n }\n editorNode.superscript = sup.chain;\n }\n if (astNode.subscript) {\n const sub = chainToEditorChain(astNode.subscript);\n if (!sub.editable) {\n return sub;\n }\n editorNode.subscript = sub.chain;\n }\n return null;\n}\n\ntype ChainAdapterResult =\n | { editable: true; chain: EditorChain }\n | { editable: false; reason: string };\n\nconst MATRIX_ENV_NAMES = new Set<GridEnvName>(['matrix', 'pmatrix', 'bmatrix', 'Bmatrix', 'vmatrix', 'Vmatrix']);\n\nfunction isGridEnvName(value: string): value is GridEnvName {\n return MATRIX_ENV_NAMES.has(value as GridEnvName) || value === 'array' || value === 'aligned';\n}\n\nfunction isMatrixEnvName(value: GridEnvName): value is MatrixEnvStyle {\n return MATRIX_ENV_NAMES.has(value);\n}\n\nfunction parseEnvOpening(opening: string): { envName: GridEnvName; alignments?: EnvColumnAlignment[] } | null {\n const match = /^\\\\begin\\{([^}]+)\\}(?:\\{([lcr]+)\\})?$/.exec(opening);\n if (!match) {\n return null;\n }\n\n const envName = match[1] ?? '';\n if (!isGridEnvName(envName)) {\n return null;\n }\n\n if (envName === 'array') {\n const spec = match[2] ?? 'c';\n return {\n envName,\n alignments: spec.split('').map((alignment) => alignment as EnvColumnAlignment),\n };\n }\n\n return { envName };\n}\n\nfunction splitEnvLine(line: ChainNode): ChainNode[] {\n const cells: ChainNode[] = [];\n let current: BaseAstNode[] = [];\n for (const node of line.chain) {\n if (node instanceof OperatorNode && node.expr === '&') {\n cells.push(new ChainNode(current));\n current = [];\n } else {\n current.push(node);\n }\n }\n cells.push(new ChainNode(current));\n return cells;\n}\n\nfunction envToEditorNode(node: EnvNode): NodeAdapterResult {\n const parsed = parseEnvOpening(node.opening);\n if (!parsed) {\n return { editable: false, reason: `بيئة رياضية غير مدعومة حاليا: ${node.opening}` };\n }\n\n const expectedClosing = `\\\\end{${parsed.envName}}`;\n if (node.closing !== expectedClosing) {\n return { editable: false, reason: `إغلاق بيئة رياضية غير مدعوم حاليا: ${node.closing}` };\n }\n\n const rowCells = node.lines.map(splitEnvLine);\n const rows = Math.max(1, rowCells.length);\n const columns = Math.max(1, ...rowCells.map((row) => row.length));\n const env = createGridEnvNode(parsed.envName, rows, columns, parsed.alignments);\n\n for (let rowIndex = 0; rowIndex < rows; rowIndex += 1) {\n const row = rowCells[rowIndex] ?? [];\n for (let columnIndex = 0; columnIndex < columns; columnIndex += 1) {\n const cell = chainToEditorChain(row[columnIndex] ?? new ChainNode());\n if (!cell.editable) {\n return cell;\n }\n env.matrixRows![rowIndex]![columnIndex] = cell.chain;\n }\n }\n\n if (parsed.envName === 'array') {\n env.columnAlignments = Array.from(\n { length: columns },\n (_, index) => parsed.alignments?.[index] ?? 'c',\n );\n }\n if (isMatrixEnvName(parsed.envName)) {\n env.matrixStyle = parsed.envName;\n }\n\n const scripts = attachScripts(node, env);\n return scripts ?? { editable: true, node: env };\n}\n\nfunction charFromTextLikeCommand(node: CommandNode): NodeAdapterResult | null {\n const commandFont = COMMAND_FONT_MAP[node.name];\n if (commandFont === undefined) {\n return null;\n }\n if (node.optionalArgs.length > 0 || node.mandatoryArgs.length !== 1) {\n return null;\n }\n\n const arg = node.mandatoryArgs[0]!;\n if (arg.chain.length !== 1) {\n return null;\n }\n\n const child = arg.chain[0]!;\n if (child instanceof CommandNode) {\n const nested = charFromTextLikeCommand(child);\n if (!nested?.editable) {\n return null;\n }\n if (commandFont !== 'infer') {\n nested.node.characterFont = commandFont;\n }\n const scripts = attachScripts(node, nested.node);\n return scripts ?? nested;\n }\n\n if (!(child instanceof CharNode)) {\n return null;\n }\n\n const normalized = normalizeCharImportExpr(child.expr);\n const characterFont = commandFont === 'infer' ? normalized.characterFont : commandFont;\n const editorNode = createEditorNode('char', normalized.expr);\n if (characterFont !== 'default') {\n editorNode.characterFont = characterFont;\n }\n const scripts = attachScripts(node, editorNode);\n return scripts ?? { editable: true, node: editorNode };\n}\n\nfunction commandToEditorNode(node: CommandNode): NodeAdapterResult {\n if (node.name === '\\\\frac' && node.mandatoryArgs.length >= 2) {\n const frac = createFracNode();\n const numerator = chainToEditorChain(node.mandatoryArgs[0]!);\n const denominator = chainToEditorChain(node.mandatoryArgs[1]!);\n if (!numerator.editable) {\n return numerator;\n }\n if (!denominator.editable) {\n return denominator;\n }\n frac.numerator = numerator.chain;\n frac.denominator = denominator.chain;\n const scripts = attachScripts(node, frac);\n if (scripts) {\n return scripts;\n }\n return { editable: true, node: frac };\n }\n\n if (\n (node.name === '\\\\sqrt' || node.name === '\\\\arabsqrt' || node.name === '\\\\arsqrt') &&\n node.mandatoryArgs.length >= 1\n ) {\n const sqrt = createSqrtNode();\n const radicand = chainToEditorChain(node.mandatoryArgs[0]!);\n if (!radicand.editable) {\n return radicand;\n }\n sqrt.radicand = radicand.chain;\n if (node.optionalArgs[0]) {\n const rootIndex = chainToEditorChain(node.optionalArgs[0]);\n if (!rootIndex.editable) {\n return rootIndex;\n }\n sqrt.rootIndex = rootIndex.chain;\n }\n const scripts = attachScripts(node, sqrt);\n if (scripts) {\n return scripts;\n }\n return { editable: true, node: sqrt };\n }\n\n if (node.name === '\\\\overset' && node.mandatoryArgs.length >= 2) {\n const overset = createOversetNode();\n const overExpr = chainToEditorChain(node.mandatoryArgs[0]!);\n const baseExpr = chainToEditorChain(node.mandatoryArgs[1]!);\n if (!overExpr.editable) {\n return overExpr;\n }\n if (!baseExpr.editable) {\n return baseExpr;\n }\n overset.overExpr = overExpr.chain;\n overset.baseExpr = baseExpr.chain;\n const scripts = attachScripts(node, overset);\n if (scripts) {\n return scripts;\n }\n return { editable: true, node: overset };\n }\n\n if (node.name === '\\\\underset' && node.mandatoryArgs.length >= 2) {\n const underset = createUndersetNode();\n const underExpr = chainToEditorChain(node.mandatoryArgs[0]!);\n const baseExpr = chainToEditorChain(node.mandatoryArgs[1]!);\n if (!underExpr.editable) {\n return underExpr;\n }\n if (!baseExpr.editable) {\n return baseExpr;\n }\n underset.underExpr = underExpr.chain;\n underset.baseExpr = baseExpr.chain;\n const scripts = attachScripts(node, underset);\n if (scripts) {\n return scripts;\n }\n return { editable: true, node: underset };\n }\n\n const accentId = accentCommandIdFromTex(node.name);\n if (accentId && node.mandatoryArgs.length >= 1) {\n const accent = createAccentNode(accentId);\n const baseExpr = chainToEditorChain(node.mandatoryArgs[0]!);\n if (!baseExpr.editable) {\n return baseExpr;\n }\n accent.baseExpr = baseExpr.chain;\n const scripts = attachScripts(node, accent);\n if (scripts) {\n return scripts;\n }\n return { editable: true, node: accent };\n }\n\n const atomicId = commandIdForTex(node.name);\n if (atomicId && node.optionalArgs.length === 0 && node.mandatoryArgs.length === 0) {\n const atomic = createEditorNode('atomicCommand', atomicId);\n const scripts = attachScripts(node, atomic);\n if (scripts) {\n return scripts;\n }\n return { editable: true, node: atomic };\n }\n\n const operatorId = operatorCommandIdForTex(node.name);\n if (operatorId && node.optionalArgs.length === 0 && node.mandatoryArgs.length === 0) {\n const atomicOperator = createEditorNode('atomicOperatorCommand', operatorId);\n const scripts = attachScripts(node, atomicOperator);\n if (scripts) {\n return scripts;\n }\n return { editable: true, node: atomicOperator };\n }\n\n const textLike = charFromTextLikeCommand(node);\n if (textLike) {\n return textLike;\n }\n\n return { editable: false, reason: `أمر رياضي غير مدعوم حاليا: ${node.name}` };\n}\n\nfunction astNodeToEditorNode(node: ChainNode['chain'][number]): NodeAdapterResult {\n if (node instanceof CharNode) {\n const normalized = normalizeCharImportExpr(node.expr);\n const editorNode = createEditorNode('char', normalized.expr);\n if (normalized.characterFont !== 'default') {\n editorNode.characterFont = normalized.characterFont;\n }\n const scripts = attachScripts(node, editorNode);\n return scripts ?? { editable: true, node: editorNode };\n }\n if (node instanceof NumberNode) {\n const editorNode = createEditorNode('number', node.expr);\n const scripts = attachScripts(node, editorNode);\n return scripts ?? { editable: true, node: editorNode };\n }\n if (node instanceof OperatorNode) {\n return { editable: true, node: createEditorNode('operator', node.expr) };\n }\n if (node instanceof DelimiterNode) {\n const editorNode = createDelimiterNode(node.leftDelimExpr, node.rightDelimExpr);\n const inner = chainToEditorChain(node.innerExpr);\n if (!inner.editable) {\n return inner;\n }\n editorNode.innerExpr = inner.chain;\n const scripts = attachScripts(node, editorNode);\n return scripts ?? { editable: true, node: editorNode };\n }\n if (node instanceof CommandNode) {\n return commandToEditorNode(node);\n }\n if (node instanceof EnvNode) {\n return envToEditorNode(node);\n }\n return { editable: false, reason: `عقدة رياضية غير مدعومة حاليا: ${node.nodeType}` };\n}\n\nfunction chainToEditorChain(chain: ChainNode): ChainAdapterResult {\n const nodes: EditorNode[] = [];\n for (const astNode of chain.chain) {\n const converted = astNodeToEditorNode(astNode);\n if (!converted.editable) {\n return converted;\n }\n nodes.push(converted.node);\n }\n return { editable: true, chain: createEditorChain(nodes) };\n}\n\nexport function mathObjectToEditorSession(math: MathNode): MathEditorAdapterResult {\n if (math.lines.length !== 1) {\n return { editable: false, reason: 'تحرير المعادلات متعددة الأسطر داخل المستند غير مدعوم بعد' };\n }\n\n const english = chainToEditorChain(math.lines[0]!);\n if (!english.editable) {\n return english;\n }\n\n const arabic = cloneChainWithFreshIds(english.chain);\n const session = createEditorSession(english.chain, arabic, 'english');\n session.sync = buildInitialSyncMap(session.englishTree, session.arabicTree);\n return { editable: true, session: cloneEditorSession(session) };\n}\n\ntype AstNodeResult =\n | { ok: true; node: BaseAstNode }\n | { ok: false; reason: string };\n\ntype AstChainResult =\n | { ok: true; chain: ChainNode }\n | { ok: false; reason: string };\n\nfunction attachAstScripts(editorNode: EditorNode, astNode: BaseAstNode): AstNodeResult | null {\n if (editorNode.superscript) {\n const sup = editorChainToAstChain(editorNode.superscript);\n if (!sup.ok) {\n return sup;\n }\n astNode.superscript = sup.chain;\n }\n if (editorNode.subscript) {\n const sub = editorChainToAstChain(editorNode.subscript);\n if (!sub.ok) {\n return sub;\n }\n astNode.subscript = sub.chain;\n }\n return null;\n}\n\nfunction editorEnvOpening(node: EditorNode): { opening: string; closing: string } | null {\n const envName = node.envName ?? node.matrixStyle;\n if (!envName) {\n return null;\n }\n if (envName === 'array') {\n const spec = (node.columnAlignments ?? []).slice(0, node.matrixRows?.[0]?.length ?? 0).join('') || 'c';\n return { opening: `\\\\begin{array}{${spec}}`, closing: '\\\\end{array}' };\n }\n return { opening: `\\\\begin{${envName}}`, closing: `\\\\end{${envName}}` };\n}\n\nfunction editorEnvToAstNode(node: EditorNode): AstNodeResult {\n const wrapper = editorEnvOpening(node);\n if (!wrapper || !node.matrixRows) {\n return { ok: false, reason: 'بيئة رياضية غير مدعومة حاليا' };\n }\n const lines: ChainNode[] = [];\n for (const row of node.matrixRows) {\n const lineNodes: BaseAstNode[] = [];\n for (let columnIndex = 0; columnIndex < row.length; columnIndex += 1) {\n if (columnIndex > 0) {\n lineNodes.push(new OperatorNode('&'));\n }\n const cell = editorChainToAstChain(row[columnIndex]!);\n if (!cell.ok) {\n return cell;\n }\n lineNodes.push(...cell.chain.chain);\n }\n lines.push(new ChainNode(lineNodes));\n }\n const env = new EnvNode(wrapper.opening, lines, wrapper.closing);\n const scripts = attachAstScripts(node, env);\n return scripts ?? { ok: true, node: env };\n}\n\nfunction accentChainForExport(accent: EditorChain | null): AstChainResult {\n if (!accent) {\n return { ok: true, chain: new ChainNode([]) };\n }\n return editorChainToAstChain(accent);\n}\n\n/** When accent is empty, unwrap to base (single node or invisible group). */\nfunction nodeFromAccentBase(\n command: '\\\\overset' | '\\\\underset',\n accent: ChainNode,\n base: ChainNode,\n): BaseAstNode {\n if (accent.chain.length > 0) {\n return new CommandNode(command, [], [accent, base]);\n }\n if (base.chain.length === 1) {\n return base.chain[0]!;\n }\n return new DelimiterNode('', base, '');\n}\n\nfunction editorNodeToAstNode(node: EditorNode): AstNodeResult {\n let astNode: BaseAstNode;\n\n if (node.kind === 'char') {\n astNode = charEditorNodeToAstNode(node);\n } else if (node.kind === 'number') {\n astNode = new NumberNode(node.expr);\n } else if (node.kind === 'operator') {\n astNode = new OperatorNode(node.expr);\n } else if (node.kind === 'delimiter' && node.innerExpr) {\n const inner = editorChainToAstChain(node.innerExpr);\n if (!inner.ok) {\n return inner;\n }\n astNode = new DelimiterNode(node.leftDelimExpr, inner.chain, node.rightDelimExpr);\n } else if (node.kind === 'frac' && node.numerator && node.denominator) {\n const numerator = editorChainToAstChain(node.numerator);\n const denominator = editorChainToAstChain(node.denominator);\n if (!numerator.ok) {\n return numerator;\n }\n if (!denominator.ok) {\n return denominator;\n }\n astNode = new CommandNode('\\\\frac', [], [numerator.chain, denominator.chain]);\n } else if (node.kind === 'sqrt' && node.radicand) {\n const radicand = editorChainToAstChain(node.radicand);\n if (!radicand.ok) {\n return radicand;\n }\n const optionalArgs: ChainNode[] = [];\n if (node.rootIndex && node.rootIndex.nodes.length > 0) {\n const rootIndex = editorChainToAstChain(node.rootIndex);\n if (!rootIndex.ok) {\n return rootIndex;\n }\n optionalArgs.push(rootIndex.chain);\n }\n astNode = new CommandNode('\\\\sqrt', optionalArgs, [radicand.chain]);\n } else if (node.kind === 'overset' && node.baseExpr) {\n const accent = accentChainForExport(node.overExpr);\n if (!accent.ok) {\n return accent;\n }\n const baseExpr = editorChainToAstChain(node.baseExpr);\n if (!baseExpr.ok) {\n return baseExpr;\n }\n astNode = nodeFromAccentBase('\\\\overset', accent.chain, baseExpr.chain);\n } else if (node.kind === 'underset' && node.baseExpr) {\n const accent = accentChainForExport(node.underExpr);\n if (!accent.ok) {\n return accent;\n }\n const baseExpr = editorChainToAstChain(node.baseExpr);\n if (!baseExpr.ok) {\n return baseExpr;\n }\n astNode = nodeFromAccentBase('\\\\underset', accent.chain, baseExpr.chain);\n } else if (node.kind === 'accent' && node.baseExpr) {\n const tex = accentCommandSpec(node.expr)?.englishTex;\n if (!tex) {\n return { ok: false, reason: `لكنة رياضية غير مدعومة حاليا: ${node.expr}` };\n }\n const baseExpr = editorChainToAstChain(node.baseExpr);\n if (!baseExpr.ok) {\n return baseExpr;\n }\n astNode = new CommandNode(tex, [], [baseExpr.chain]);\n } else if (node.kind === 'atomicCommand') {\n const tex = atomicCommandSpec(node.expr)?.englishTex;\n if (!tex) {\n return { ok: false, reason: `أمر رياضي غير مدعوم حاليا: ${node.expr}` };\n }\n astNode = new CommandNode(tex);\n } else if (node.kind === 'atomicOperatorCommand') {\n const tex = atomicOperatorCommandSpec(node.expr)?.Tex;\n if (!tex) {\n return { ok: false, reason: `رمز رياضي غير مدعوم حاليا: ${node.expr}` };\n }\n astNode = new CommandNode(tex);\n } else if (node.kind === 'env') {\n return editorEnvToAstNode(node);\n } else {\n return { ok: false, reason: `عقدة رياضية غير مدعومة حاليا: ${node.kind}` };\n }\n\n const scripts = attachAstScripts(node, astNode);\n return scripts ?? { ok: true, node: astNode };\n}\n\nfunction editorChainToAstChain(chain: EditorChain): AstChainResult {\n const nodes: BaseAstNode[] = [];\n for (const editorNode of chain.nodes) {\n const converted = editorNodeToAstNode(editorNode);\n if (!converted.ok) {\n return converted;\n }\n nodes.push(converted.node);\n }\n return { ok: true, chain: new ChainNode(nodes) };\n}\n\nexport function mathNodeFromEditorSession(\n session: EditorSession,\n mathMode = '$',\n closing = '$',\n): MathNodeFromEditorResult {\n const converted = editorChainToAstChain(session.englishTree);\n if (!converted.ok) {\n return converted;\n }\n return {\n ok: true,\n math: {\n nodeType: 'MathObject',\n mathMode,\n lines: [converted.chain],\n closing,\n },\n };\n}\n\n/** Delimited Arabic TeX for document text/preview — matches `<ButexEditor />` arabic output. */\nexport function mathSourceFromEditorSession(\n session: EditorSession,\n mathMode = '$',\n closing = '$',\n): string {\n const inner = renderArabicLatexFromSession(session);\n if (mathMode === '$' || mathMode === '\\\\(') {\n return mathMode + inner + closing;\n }\n if (mathMode === '$$' || mathMode === '\\\\[') {\n if (!inner.includes('\\n')) {\n return `${mathMode}\\n${inner}\\n${closing}`;\n }\n return `${mathMode}\\n${inner.split('\\n').map((line) => ` ${line}`).join(' \\\\\\\\\\n')}\\n${closing}`;\n }\n return `${mathMode}\\n ${inner}\\n${closing}`;\n}\n\nexport function mathSourceWithReplacement(source: string, replacementInnerLatex: string): string {\n if (source.startsWith('$$') && source.endsWith('$$')) {\n return `$$${replacementInnerLatex}$$`;\n }\n if (source.startsWith('$') && source.endsWith('$')) {\n return `$${replacementInnerLatex}$`;\n }\n if (source.startsWith('\\\\(') && source.endsWith('\\\\)')) {\n return `\\\\(${replacementInnerLatex}\\\\)`;\n }\n if (source.startsWith('\\\\[') && source.endsWith('\\\\]')) {\n return `\\\\[${replacementInnerLatex}\\\\]`;\n }\n const begin = /^\\\\begin\\{([A-Za-z*]+)\\}/.exec(source);\n if (begin) {\n const opening = begin[0] ?? '';\n const closing = `\\\\end{${begin[1] ?? ''}}`;\n if (source.endsWith(closing)) {\n return `${opening}${replacementInnerLatex}${closing}`;\n }\n }\n return replacementInnerLatex;\n}\n","import { mathNodeFromEditorSession, mathObjectToEditorSession } from '../document/mathEditorAdapter.js';\nimport type { MathNode } from '../document/types.js';\nimport {\n buildInitialSyncMap,\n createEditorChain,\n createEditorSession,\n renderArabicLatexFromSession,\n renderEnglishLatexFromSession,\n setCurrentDigitForm,\n type DigitFormId,\n type EditorSide,\n type EditorSession,\n} from '../editor/index.js';\nimport type { MathToken2 } from './types.js';\n\nexport type Document2MathBridgeResult =\n | { editable: true; session: EditorSession }\n | { editable: false; reason: string };\n\nexport function createEmptyEquationSession(side: EditorSide = 'arabic'): EditorSession {\n const english = createEditorChain();\n const arabic = createEditorChain();\n arabic.id = english.id;\n const session = createEditorSession(english, arabic, side);\n session.sync = buildInitialSyncMap(session.englishTree, session.arabicTree);\n return session;\n}\n\nexport function createEmptyArabicEquationSession(): EditorSession {\n return createEmptyEquationSession('arabic');\n}\n\nexport function mathTokenToEditorSession(math: MathNode | null, side: EditorSide = 'arabic'): Document2MathBridgeResult {\n if (!math) {\n return { editable: false, reason: 'هذه المعادلة محفوظة كنص خام فقط حاليا' };\n }\n const result = mathObjectToEditorSession(math);\n if (!result.editable) {\n return result;\n }\n result.session.activeSide = side;\n result.session.sync = buildInitialSyncMap(result.session.englishTree, result.session.arabicTree);\n return result;\n}\n\nexport function mathTokenToArabicEditorSession(math: MathNode | null): Document2MathBridgeResult {\n return mathTokenToEditorSession(math, 'arabic');\n}\n\nexport function mathSourceFromSession(\n session: EditorSession,\n side: EditorSide,\n opening = '$',\n closing = '$',\n): string {\n const inner = side === 'english'\n ? renderEnglishLatexFromSession(session)\n : renderArabicLatexFromSession(session);\n if (opening === '$' || opening === '\\\\(') {\n return opening + inner + closing;\n }\n if (opening === '$$' || opening === '\\\\[') {\n return `${opening}\\n${inner}\\n${closing}`;\n }\n return `${opening}\\n ${inner}\\n${closing}`;\n}\n\nexport function mathSourceFromArabicSession(session: EditorSession, opening = '$', closing = '$'): string {\n return mathSourceFromSession(session, 'arabic', opening, closing);\n}\n\nexport function mathNodeFromSession(session: EditorSession, opening = '$', closing = '$'): MathNode {\n const converted = mathNodeFromEditorSession(session, opening, closing);\n if (converted.ok) {\n return converted.math;\n }\n return { nodeType: 'MathObject', mathMode: opening, lines: [], closing };\n}\n\nexport function mathNodeFromArabicSession(session: EditorSession, opening = '$', closing = '$'): MathNode {\n return mathNodeFromSession(session, opening, closing);\n}\n\nexport function mathTokenSourceForSide(token: MathToken2, side: EditorSide, digitForm?: DigitFormId): string {\n if (!token.math || token.sourceOwner === 'raw') {\n return token.source;\n }\n if (token.sourceSide === side && digitForm === undefined) {\n return token.source;\n }\n const result = mathTokenToEditorSession(token.math, side);\n if (!result.editable) {\n return token.source;\n }\n const session = digitForm === undefined\n ? result.session\n : setCurrentDigitForm(result.session, digitForm);\n return mathSourceFromSession(session, side, token.opening, token.closing);\n}\n","import { document2Id } from './ids.js';\nimport { cloneDocument2Meta, emptyDocument2Meta, normalizeDocument2HijriDate } from './articleMeta.js';\nimport { createEmptyReference2 } from './citations.js';\nimport { createInlineField2 } from './importJson.js';\nimport { applyFloatMetaPatch, defaultFloatMeta, type FloatMetaPatch } from './labels.js';\nimport { mathNodeFromSession, mathSourceFromSession } from './mathBridge.js';\nimport type {\n BibliographyBlock2,\n CiteToken2,\n Document2Block,\n Document2Node,\n ImageBlock2,\n InlineField2,\n InlineToken2,\n ListBlock2,\n MathToken2,\n Reference2,\n Reference2Json,\n RefToken2,\n TableBlock2,\n TextStyle2,\n TextToken2,\n} from './types.js';\nimport type { Document2MetaProp } from './articleMeta.js';\nimport type { EditorSession, EditorSide } from '../editor/index.js';\n\nexport type Document2ImageAssetRef = {\n assetId: string;\n value?: string;\n};\n\ntype Document2ImageInput = string | Document2ImageAssetRef | undefined;\n\nfunction cloneToken(token: InlineToken2): InlineToken2 {\n return token.kind === 'text' ? { ...token } : { ...token };\n}\n\nfunction cloneField(field: InlineField2): InlineField2 {\n return { id: field.id, tokens: field.tokens.map(cloneToken) };\n}\n\nfunction cloneBlock(block: Document2Block): Document2Block {\n if (block.kind === 'textBlock') {\n return { ...block, field: cloneField(block.field) };\n }\n if (block.kind === 'list') {\n return {\n ...block,\n items: block.items.map((item) => ({\n ...item,\n field: cloneField(item.field),\n blocks: item.blocks.map(cloneBlock),\n })),\n };\n }\n if (block.kind === 'table') {\n return { ...block, rows: block.rows.map((row) => row.map(cloneField)) };\n }\n if (block.kind === 'image') {\n return { ...block, options: { ...block.options } };\n }\n return { ...block };\n}\n\nfunction cloneDocument(document: Document2Node): Document2Node {\n return {\n nodeType: 'DocumentObject',\n meta: cloneDocument2Meta(document.meta ?? emptyDocument2Meta()),\n references: document.references.map((reference) => ({ ...reference })),\n blocks: document.blocks.map(cloneBlock),\n diagnostics: document.diagnostics.map((diagnostic) => ({ ...diagnostic })),\n };\n}\n\nfunction visitFields(blocks: Document2Block[], visitor: (field: InlineField2) => boolean): boolean {\n for (const block of blocks) {\n if (block.kind === 'textBlock') {\n if (visitor(block.field)) {\n return true;\n }\n } else if (block.kind === 'list') {\n for (const item of block.items) {\n if (visitor(item.field) || visitFields(item.blocks, visitor)) {\n return true;\n }\n }\n } else if (block.kind === 'table') {\n for (const row of block.rows) {\n for (const cell of row) {\n if (visitor(cell)) {\n return true;\n }\n }\n }\n }\n }\n return false;\n}\n\nexport function findFirstInlineField(document: Document2Node): InlineField2 | null {\n let found: InlineField2 | null = null;\n visitFields(document.blocks, (field) => {\n found = field;\n return true;\n });\n return found;\n}\n\nexport function updateTextToken(document: Document2Node, fieldId: string, tokenId: string, text: string): Document2Node {\n const next = cloneDocument(document);\n visitFields(next.blocks, (field) => {\n if (field.id !== fieldId) {\n return false;\n }\n const token = field.tokens.find((entry): entry is TextToken2 => entry.id === tokenId && entry.kind === 'text');\n if (!token) {\n return true;\n }\n token.text = text;\n return true;\n });\n return next;\n}\n\nfunction mathTokenFromSession(session: EditorSession, opening = '$', closing = '$', side: EditorSide = 'arabic'): MathToken2 {\n return {\n id: document2Id('math'),\n kind: 'math',\n display: opening === '$$' || opening === '\\\\[' || opening.startsWith('\\\\begin{'),\n opening,\n closing,\n source: mathSourceFromSession(session, side, opening, closing),\n sourceSide: side,\n math: mathNodeFromSession(session, opening, closing),\n editable: true,\n sourceOwner: 'editor',\n };\n}\n\nfunction splitTextForInsertion(token: TextToken2): InlineToken2[] | null {\n const gap = token.text.indexOf(' ');\n if (gap < 0) {\n return null;\n }\n return [\n { id: token.id, kind: 'text', text: token.text.slice(0, gap + 1) },\n { id: document2Id('text'), kind: 'text', text: token.text.slice(gap + 1) },\n ];\n}\n\nexport function cloneDocument2Node(document: Document2Node): Document2Node {\n return cloneDocument(document);\n}\n\nfunction insertBlockAfter(blocks: Document2Block[], afterBlockId: string | null | undefined, block: Document2Block): void {\n if (!afterBlockId) {\n blocks.push(block);\n return;\n }\n const index = blocks.findIndex((entry) => entry.id === afterBlockId);\n if (index < 0) {\n blocks.push(block);\n return;\n }\n blocks.splice(index + 1, 0, block);\n}\n\nexport function insertDocument2BlockAfter(\n document: Document2Node,\n afterBlockId: string | null | undefined,\n block: Document2Block,\n): Document2Node {\n const next = cloneDocument(document);\n insertBlockAfter(next.blocks, afterBlockId, block);\n return next;\n}\n\nexport function moveDocument2BlockById(document: Document2Node, blockId: string, direction: -1 | 1): Document2Node {\n const next = cloneDocument(document);\n const index = next.blocks.findIndex((block) => block.id === blockId);\n const targetIndex = index + direction;\n if (index < 0 || targetIndex < 0 || targetIndex >= next.blocks.length) {\n return document;\n }\n const [block] = next.blocks.splice(index, 1);\n if (!block) {\n return document;\n }\n next.blocks.splice(targetIndex, 0, block);\n return next;\n}\n\nexport function moveDocument2BlockRange(\n document: Document2Node,\n from: number,\n to: number,\n direction: -1 | 1,\n): Document2Node {\n const count = document.blocks.length;\n if (from < 0 || to < 0 || from >= count || to >= count || from > to) {\n return document;\n }\n const insertAt = from + direction;\n if (insertAt < 0 || to + direction >= count) {\n return document;\n }\n const next = cloneDocument(document);\n const slice = next.blocks.splice(from, to - from + 1);\n next.blocks.splice(insertAt, 0, ...slice);\n return next;\n}\n\nexport function removeDocument2BlockRange(document: Document2Node, from: number, to: number): Document2Node {\n const count = document.blocks.length;\n if (from < 0 || to < 0 || from >= count || to >= count || from > to) {\n return document;\n }\n const next = cloneDocument(document);\n next.blocks = [...next.blocks.slice(0, from), ...next.blocks.slice(to + 1)];\n return next;\n}\n\nfunction normalizeFieldTokens(tokens: InlineToken2[]): InlineToken2[] {\n if (tokens.length === 0) {\n return [{ id: document2Id('text'), kind: 'text', text: '' }];\n }\n return tokens;\n}\n\nfunction textStylesEqual(a: TextStyle2 | undefined, b: TextStyle2 | undefined): boolean {\n return Boolean(a?.bold) === Boolean(b?.bold) && Boolean(a?.italic) === Boolean(b?.italic) && Boolean(a?.underline) === Boolean(b?.underline);\n}\n\nfunction compactAdjacentTextTokens(tokens: InlineToken2[]): InlineToken2[] {\n const compacted: InlineToken2[] = [];\n for (const token of tokens) {\n const previous = compacted[compacted.length - 1];\n if (previous?.kind === 'text' && token.kind === 'text' && textStylesEqual(previous.style, token.style)) {\n previous.text += token.text;\n } else {\n compacted.push(token);\n }\n }\n return normalizeFieldTokens(compacted);\n}\n\nfunction withoutEmptyStyle(style: TextStyle2): TextStyle2 | undefined {\n const next: TextStyle2 = {};\n if (style.bold) {\n next.bold = true;\n }\n if (style.italic) {\n next.italic = true;\n }\n if (style.underline) {\n next.underline = true;\n }\n return next.bold || next.italic || next.underline ? next : undefined;\n}\n\nfunction textTokenPart(text: string, style: TextStyle2 | undefined, id = document2Id('text')): TextToken2 {\n return { id, kind: 'text', text, ...(style ? { style } : {}) };\n}\n\nexport function toggleTextTokenStyle(\n document: Document2Node,\n fieldId: string,\n tokenId: string,\n selectionStart: number,\n selectionEnd: number,\n styleName: keyof TextStyle2,\n): Document2Node {\n if (selectionEnd <= selectionStart) {\n return document;\n }\n const next = cloneDocument(document);\n visitFields(next.blocks, (field) => {\n if (field.id !== fieldId) {\n return false;\n }\n const tokenIndex = field.tokens.findIndex((entry) => entry.id === tokenId && entry.kind === 'text');\n if (tokenIndex < 0) {\n return true;\n }\n const token = field.tokens[tokenIndex] as TextToken2;\n const start = Math.max(0, Math.min(token.text.length, selectionStart));\n const end = Math.max(0, Math.min(token.text.length, selectionEnd));\n if (end <= start) {\n return true;\n }\n const selectedStyle = token.style ?? {};\n const enabled = selectedStyle[styleName] === true;\n const nextStyle = withoutEmptyStyle({ ...selectedStyle, [styleName]: enabled ? undefined : true });\n const parts: InlineToken2[] = [];\n const before = token.text.slice(0, start);\n const selected = token.text.slice(start, end);\n const after = token.text.slice(end);\n if (before.length > 0) {\n parts.push(textTokenPart(before, token.style, token.id));\n }\n parts.push(textTokenPart(selected, nextStyle, before.length > 0 ? document2Id('text') : token.id));\n if (after.length > 0) {\n parts.push(textTokenPart(after, token.style));\n }\n field.tokens = compactAdjacentTextTokens([\n ...field.tokens.slice(0, tokenIndex),\n ...parts,\n ...field.tokens.slice(tokenIndex + 1),\n ]);\n return true;\n });\n return next;\n}\n\nfunction stitchTextAroundRemovedToken(tokens: InlineToken2[], index: number): InlineToken2[] {\n const before = tokens[index - 1];\n const after = tokens[index + 1];\n if (before?.kind === 'text' && after?.kind === 'text') {\n return [\n ...tokens.slice(0, index - 1),\n { ...before, text: before.text + after.text },\n ...tokens.slice(index + 2),\n ];\n }\n return [...tokens.slice(0, index), ...tokens.slice(index + 1)];\n}\n\nexport function removeMathTokenById(document: Document2Node, tokenId: string): Document2Node {\n const next = cloneDocument(document);\n visitFields(next.blocks, (field) => {\n const index = field.tokens.findIndex((token) => token.id === tokenId && token.kind === 'math');\n if (index < 0) {\n return false;\n }\n field.tokens = normalizeFieldTokens(stitchTextAroundRemovedToken(field.tokens, index));\n return true;\n });\n return next;\n}\n\nfunction splitTextTokenAt(token: TextToken2, offset: number): [TextToken2, TextToken2] {\n const safeOffset = Math.max(0, Math.min(offset, token.text.length));\n return [\n { id: token.id, kind: 'text', text: token.text.slice(0, safeOffset), ...(token.style ? { style: token.style } : {}) },\n { id: document2Id('text'), kind: 'text', text: token.text.slice(safeOffset), ...(token.style ? { style: token.style } : {}) },\n ];\n}\n\nexport function insertMathTokenAtCaret(\n document: Document2Node,\n fieldId: string,\n textTokenId: string | null,\n caretOffset: number,\n session: EditorSession,\n opening = '$',\n closing = '$',\n side: EditorSide = 'arabic',\n): Document2Node {\n const next = cloneDocument(document);\n const mathToken = mathTokenFromSession(session, opening, closing, side);\n visitFields(next.blocks, (field) => {\n if (field.id !== fieldId) {\n return false;\n }\n\n const textIndex = textTokenId\n ? field.tokens.findIndex((token) => token.id === textTokenId && token.kind === 'text')\n : field.tokens.findIndex((token) => token.kind === 'text');\n\n if (textIndex < 0) {\n field.tokens.push(mathToken);\n field.tokens.push({ id: document2Id('text'), kind: 'text', text: '' });\n return true;\n }\n\n const current = field.tokens[textIndex] as TextToken2;\n const [before, after] = splitTextTokenAt(current, caretOffset);\n const parts: InlineToken2[] = [...field.tokens.slice(0, textIndex)];\n if (before.text.length > 0) {\n parts.push(before);\n }\n parts.push(mathToken);\n parts.push(after);\n parts.push(...field.tokens.slice(textIndex + 1));\n field.tokens = normalizeFieldTokens(parts);\n return true;\n });\n return next;\n}\n\nexport function insertMathToken(\n document: Document2Node,\n fieldId: string,\n insertIndex: number,\n session: EditorSession,\n opening = '$',\n closing = '$',\n side: EditorSide = 'arabic',\n): Document2Node {\n const next = cloneDocument(document);\n const mathToken = mathTokenFromSession(session, opening, closing, side);\n visitFields(next.blocks, (field) => {\n if (field.id !== fieldId) {\n return false;\n }\n\n if (field.tokens.length === 1 && field.tokens[0]?.kind === 'text') {\n const split = splitTextForInsertion(field.tokens[0]);\n if (split) {\n field.tokens = [split[0]!, mathToken, split[1]!];\n return true;\n }\n }\n\n const safeIndex = Math.max(0, Math.min(insertIndex, field.tokens.length));\n field.tokens.splice(safeIndex, 0, mathToken);\n return true;\n });\n return next;\n}\n\nexport function replaceMathTokenFromSession(\n document: Document2Node,\n tokenId: string,\n session: EditorSession,\n opening?: string,\n closing?: string,\n side: EditorSide = 'arabic',\n): Document2Node {\n const next = cloneDocument(document);\n visitFields(next.blocks, (field) => {\n const index = field.tokens.findIndex((token) => token.id === tokenId && token.kind === 'math');\n if (index < 0) {\n return false;\n }\n const current = field.tokens[index] as MathToken2;\n const open = opening ?? current.opening;\n const close = closing ?? current.closing;\n const replaced = mathTokenFromSession(session, open, close, side);\n replaced.id = current.id;\n if (current.labelEnabled !== undefined) {\n replaced.labelEnabled = current.labelEnabled;\n }\n if (current.label !== undefined) {\n replaced.label = current.label;\n }\n field.tokens[index] = replaced;\n return true;\n });\n return next;\n}\n\nexport function addDocument2TextBlock(\n document: Document2Node,\n command: '\\\\section' | '\\\\subsection' | '\\\\subsubsection' | '\\\\paragraph' = '\\\\paragraph',\n afterBlockId?: string | null,\n): Document2Node {\n const block = {\n id: document2Id('block'),\n kind: 'textBlock' as const,\n command,\n field: createInlineField2(''),\n ...(command === '\\\\paragraph' ? { centered: false } : {}),\n };\n return insertDocument2BlockAfter(document, afterBlockId, block);\n}\n\nexport function updateDocument2TextBlockCentered(\n document: Document2Node,\n blockId: string,\n centered: boolean,\n): Document2Node {\n const next = cloneDocument(document);\n function visit(blocks: Document2Block[]): boolean {\n for (const block of blocks) {\n if (block.id === blockId && block.kind === 'textBlock' && block.command === '\\\\paragraph') {\n block.centered = centered;\n return true;\n }\n if (block.kind === 'list') {\n for (const item of block.items) {\n if (visit(item.blocks)) {\n return true;\n }\n }\n }\n }\n return false;\n }\n visit(next.blocks);\n return next;\n}\n\nexport function removeDocument2BlockById(document: Document2Node, blockId: string): Document2Node {\n const next = cloneDocument(document);\n next.blocks = next.blocks.filter((block) => block.id !== blockId);\n return next;\n}\n\nfunction newListBlock(ordered: boolean): ListBlock2 {\n const command: ListBlock2['command'] = ordered ? '\\\\begin{enumerate}' : '\\\\begin{itemize}';\n const closing = ordered ? '\\\\end{enumerate}' : '\\\\end{itemize}';\n return {\n id: document2Id('block'),\n kind: 'list',\n command,\n closing,\n items: [{ id: document2Id('item'), field: createInlineField2(''), blocks: [] }],\n };\n}\n\nexport function addDocument2ListBlock(document: Document2Node, ordered: boolean, afterBlockId?: string | null): Document2Node {\n return insertDocument2BlockAfter(document, afterBlockId, newListBlock(ordered));\n}\n\nexport function addDocument2TableBlock(\n document: Document2Node,\n columns = 'lll',\n rowCount = 3,\n colCount = 3,\n afterBlockId?: string | null,\n): Document2Node {\n const rows = Math.max(1, rowCount);\n const cols = Math.max(1, colCount);\n const tableRows: InlineField2[][] = [];\n for (let r = 0; r < rows; r += 1) {\n const row: InlineField2[] = [];\n for (let c = 0; c < cols; c += 1) {\n row.push(createInlineField2(''));\n }\n tableRows.push(row);\n }\n const block: TableBlock2 = {\n id: document2Id('block'),\n kind: 'table',\n command: '\\\\begin{tabular}',\n closing: '\\\\end{tabular}',\n columns: columns || 'l'.repeat(cols),\n rows: tableRows,\n ...defaultFloatMeta(),\n };\n return insertDocument2BlockAfter(document, afterBlockId, block);\n}\n\nfunction normalizeImageInput(srcOrAsset?: Document2ImageInput): { value: string; assetId?: string } {\n if (typeof srcOrAsset === 'string') {\n return srcOrAsset.length > 0 ? { value: srcOrAsset, assetId: srcOrAsset } : { value: '' };\n }\n if (srcOrAsset && srcOrAsset.assetId.length > 0) {\n return { value: srcOrAsset.value ?? srcOrAsset.assetId, assetId: srcOrAsset.assetId };\n }\n return { value: '' };\n}\n\nexport function addDocument2ImageBlock(\n document: Document2Node,\n srcOrAsset?: Document2ImageInput,\n afterBlockId?: string | null,\n): Document2Node {\n const image = normalizeImageInput(srcOrAsset);\n const block: ImageBlock2 = {\n id: document2Id('block'),\n kind: 'image',\n command: '\\\\includegraphics',\n value: image.value,\n ...(image.assetId !== undefined ? { assetId: image.assetId } : {}),\n options: { width: '0.8\\\\columnwidth' },\n ...defaultFloatMeta(),\n };\n return insertDocument2BlockAfter(document, afterBlockId, block);\n}\n\nexport function updateDocument2ImageValue(document: Document2Node, blockId: string, value: string): Document2Node {\n const next = cloneDocument(document);\n function visit(blocks: Document2Block[]): boolean {\n for (const block of blocks) {\n if (block.id === blockId && block.kind === 'image') {\n block.value = value;\n return true;\n }\n if (block.kind === 'list') {\n for (const item of block.items) {\n if (visit(item.blocks)) {\n return true;\n }\n }\n }\n }\n return false;\n }\n visit(next.blocks);\n return next;\n}\n\nexport function updateDocument2ImageAsset(document: Document2Node, blockId: string, asset: Document2ImageAssetRef): Document2Node {\n const next = cloneDocument(document);\n const image = normalizeImageInput(asset);\n function visit(blocks: Document2Block[]): boolean {\n for (const block of blocks) {\n if (block.id === blockId && block.kind === 'image') {\n block.value = image.value;\n if (image.assetId !== undefined) {\n block.assetId = image.assetId;\n } else {\n delete block.assetId;\n }\n return true;\n }\n if (block.kind === 'list') {\n for (const item of block.items) {\n if (visit(item.blocks)) {\n return true;\n }\n }\n }\n }\n return false;\n }\n visit(next.blocks);\n return next;\n}\n\nexport function clearDocument2ImageAsset(document: Document2Node, blockId: string): Document2Node {\n const next = cloneDocument(document);\n function visit(blocks: Document2Block[]): boolean {\n for (const block of blocks) {\n if (block.id === blockId && block.kind === 'image') {\n block.value = '';\n delete block.assetId;\n return true;\n }\n if (block.kind === 'list') {\n for (const item of block.items) {\n if (visit(item.blocks)) {\n return true;\n }\n }\n }\n }\n return false;\n }\n visit(next.blocks);\n return next;\n}\n\nexport function updateDocument2ImageMeta(document: Document2Node, blockId: string, patch: FloatMetaPatch): Document2Node {\n const next = cloneDocument(document);\n function visit(blocks: Document2Block[]): boolean {\n for (const block of blocks) {\n if (block.id === blockId && block.kind === 'image') {\n applyFloatMetaPatch(block, patch);\n return true;\n }\n if (block.kind === 'list') {\n for (const item of block.items) {\n if (visit(item.blocks)) {\n return true;\n }\n }\n }\n }\n return false;\n }\n visit(next.blocks);\n return next;\n}\n\nexport function updateDocument2TableMeta(document: Document2Node, blockId: string, patch: FloatMetaPatch): Document2Node {\n const next = cloneDocument(document);\n function visit(blocks: Document2Block[]): boolean {\n for (const block of blocks) {\n if (block.id === blockId && block.kind === 'table') {\n applyFloatMetaPatch(block, patch);\n return true;\n }\n if (block.kind === 'list') {\n for (const item of block.items) {\n if (visit(item.blocks)) {\n return true;\n }\n }\n }\n }\n return false;\n }\n visit(next.blocks);\n return next;\n}\n\nexport function updateMathTokenLabel(\n document: Document2Node,\n tokenId: string,\n patch: { labelEnabled?: boolean; label?: string },\n): Document2Node {\n const next = cloneDocument(document);\n visitFields(next.blocks, (field) => {\n const token = field.tokens.find((entry): entry is MathToken2 => entry.id === tokenId && entry.kind === 'math');\n if (!token) {\n return false;\n }\n if (typeof patch.labelEnabled === 'boolean') {\n token.labelEnabled = patch.labelEnabled;\n }\n if (typeof patch.label === 'string') {\n token.label = patch.label;\n }\n return true;\n });\n return next;\n}\n\nfunction refTokenFromKeys(keys: string[], refCommand: 'ref' | 'eqref'): RefToken2 {\n return { id: document2Id('ref'), kind: 'ref', keys: [...keys], refCommand };\n}\n\nexport function insertRefTokenAtCaret(\n document: Document2Node,\n fieldId: string,\n textTokenId: string | null,\n caretOffset: number,\n keys: string[],\n refCommand: 'ref' | 'eqref' = 'ref',\n): Document2Node {\n if (keys.length === 0) {\n return document;\n }\n const next = cloneDocument(document);\n const refToken = refTokenFromKeys(keys, refCommand);\n visitFields(next.blocks, (field) => {\n if (field.id !== fieldId) {\n return false;\n }\n\n const textIndex = textTokenId\n ? field.tokens.findIndex((token) => token.id === textTokenId && token.kind === 'text')\n : field.tokens.findIndex((token) => token.kind === 'text');\n\n if (textIndex < 0) {\n field.tokens.push(refToken);\n field.tokens.push({ id: document2Id('text'), kind: 'text', text: '' });\n return true;\n }\n\n const current = field.tokens[textIndex] as TextToken2;\n const [before, after] = splitTextTokenAt(current, caretOffset);\n const parts: InlineToken2[] = [...field.tokens.slice(0, textIndex)];\n if (before.text.length > 0) {\n parts.push(before);\n }\n parts.push(refToken);\n parts.push(after);\n parts.push(...field.tokens.slice(textIndex + 1));\n field.tokens = normalizeFieldTokens(parts);\n return true;\n });\n return next;\n}\n\nexport function updateRefTokenKeys(\n document: Document2Node,\n tokenId: string,\n keys: string[],\n refCommand?: 'ref' | 'eqref',\n): Document2Node {\n if (keys.length === 0) {\n return document;\n }\n const next = cloneDocument(document);\n visitFields(next.blocks, (field) => {\n const token = field.tokens.find((entry): entry is RefToken2 => entry.id === tokenId && entry.kind === 'ref');\n if (!token) {\n return false;\n }\n token.keys = [...keys];\n if (refCommand) {\n token.refCommand = refCommand;\n }\n return true;\n });\n return next;\n}\n\nexport function removeRefTokenById(document: Document2Node, tokenId: string): Document2Node {\n const next = cloneDocument(document);\n visitFields(next.blocks, (field) => {\n const index = field.tokens.findIndex((token) => token.id === tokenId && token.kind === 'ref');\n if (index < 0) {\n return false;\n }\n field.tokens = normalizeFieldTokens(stitchTextAroundRemovedToken(field.tokens, index));\n return true;\n });\n return next;\n}\n\nfunction mutateListBlockById(blocks: Document2Block[], listBlockId: string, mutator: (list: ListBlock2) => void): boolean {\n for (const block of blocks) {\n if (block.id === listBlockId && block.kind === 'list') {\n mutator(block);\n return true;\n }\n if (block.kind === 'list') {\n for (const item of block.items) {\n if (mutateListBlockById(item.blocks, listBlockId, mutator)) {\n return true;\n }\n }\n }\n }\n return false;\n}\n\nexport function addDocument2ListItem(document: Document2Node, listBlockId: string): Document2Node {\n const next = cloneDocument(document);\n mutateListBlockById(next.blocks, listBlockId, (list) => {\n list.items.push({ id: document2Id('item'), field: createInlineField2(''), blocks: [] });\n });\n return next;\n}\n\nexport function removeDocument2ListItem(document: Document2Node, listBlockId: string, itemId: string): Document2Node {\n const next = cloneDocument(document);\n mutateListBlockById(next.blocks, listBlockId, (list) => {\n if (list.items.length < 2) {\n return;\n }\n const index = list.items.findIndex((item) => item.id === itemId);\n if (index >= 0) {\n list.items.splice(index, 1);\n }\n });\n return next;\n}\n\nfunction citeTokenFromKeys(keys: string[]): CiteToken2 {\n return { id: document2Id('cite'), kind: 'cite', keys: [...keys] };\n}\n\nexport function insertCiteTokenAtCaret(\n document: Document2Node,\n fieldId: string,\n textTokenId: string | null,\n caretOffset: number,\n keys: string[],\n): Document2Node {\n if (keys.length === 0) {\n return document;\n }\n const next = cloneDocument(document);\n const citeToken = citeTokenFromKeys(keys);\n visitFields(next.blocks, (field) => {\n if (field.id !== fieldId) {\n return false;\n }\n\n const textIndex = textTokenId\n ? field.tokens.findIndex((token) => token.id === textTokenId && token.kind === 'text')\n : field.tokens.findIndex((token) => token.kind === 'text');\n\n if (textIndex < 0) {\n field.tokens.push(citeToken);\n field.tokens.push({ id: document2Id('text'), kind: 'text', text: '' });\n return true;\n }\n\n const current = field.tokens[textIndex] as TextToken2;\n const [before, after] = splitTextTokenAt(current, caretOffset);\n const parts: InlineToken2[] = [...field.tokens.slice(0, textIndex)];\n if (before.text.length > 0) {\n parts.push(before);\n }\n parts.push(citeToken);\n parts.push(after);\n parts.push(...field.tokens.slice(textIndex + 1));\n field.tokens = normalizeFieldTokens(parts);\n return true;\n });\n return next;\n}\n\nexport function updateCiteTokenKeys(document: Document2Node, tokenId: string, keys: string[]): Document2Node {\n if (keys.length === 0) {\n return document;\n }\n const next = cloneDocument(document);\n visitFields(next.blocks, (field) => {\n const token = field.tokens.find((entry): entry is CiteToken2 => entry.id === tokenId && entry.kind === 'cite');\n if (!token) {\n return false;\n }\n token.keys = [...keys];\n return true;\n });\n return next;\n}\n\nexport function removeCiteTokenById(document: Document2Node, tokenId: string): Document2Node {\n const next = cloneDocument(document);\n visitFields(next.blocks, (field) => {\n const index = field.tokens.findIndex((token) => token.id === tokenId && token.kind === 'cite');\n if (index < 0) {\n return false;\n }\n field.tokens = normalizeFieldTokens(stitchTextAroundRemovedToken(field.tokens, index));\n return true;\n });\n return next;\n}\n\nexport function ensureDocument2BibliographyBlock(document: Document2Node, afterBlockId?: string | null): Document2Node {\n if (document.blocks.some((block) => block.kind === 'bibliography')) {\n return document;\n }\n const block: BibliographyBlock2 = {\n id: document2Id('block'),\n kind: 'bibliography',\n command: '\\\\begin{thebibliography}',\n closing: '\\\\end{thebibliography}',\n };\n return insertDocument2BlockAfter(document, afterBlockId ?? null, block);\n}\n\nexport function addDocument2Reference(document: Document2Node, partial: Partial<Reference2Json> = {}): Document2Node {\n const next = cloneDocument(document);\n next.references.push(createEmptyReference2(partial));\n return next;\n}\n\nexport function updateDocument2Reference(document: Document2Node, referenceId: string, patch: Partial<Reference2Json>): Document2Node {\n const next = cloneDocument(document);\n const reference = next.references.find((entry) => entry.id === referenceId);\n if (!reference) {\n return document;\n }\n if (typeof patch.key === 'string' && patch.key.trim().length > 0) {\n reference.key = patch.key.trim();\n }\n if (typeof patch.authors === 'string') {\n reference.authors = patch.authors;\n }\n if (typeof patch.title === 'string') {\n reference.title = patch.title;\n }\n if (typeof patch.year === 'string') {\n reference.year = patch.year;\n }\n if (typeof patch.url === 'string') {\n reference.url = patch.url;\n }\n if (typeof patch.venue === 'string') {\n reference.venue = patch.venue;\n }\n if (patch.field_separator === ',' || patch.field_separator === '،') {\n reference.fieldSeparator = patch.field_separator;\n }\n return next;\n}\n\nexport function removeDocument2Reference(document: Document2Node, referenceId: string): Document2Node {\n const next = cloneDocument(document);\n next.references = next.references.filter((reference) => reference.id !== referenceId);\n return next;\n}\n\nexport function moveDocument2Reference(document: Document2Node, referenceId: string, direction: -1 | 1): Document2Node {\n const next = cloneDocument(document);\n const index = next.references.findIndex((reference) => reference.id === referenceId);\n const targetIndex = index + direction;\n if (index < 0 || targetIndex < 0 || targetIndex >= next.references.length) {\n return document;\n }\n const [reference] = next.references.splice(index, 1);\n if (!reference) {\n return document;\n }\n next.references.splice(targetIndex, 0, reference);\n return next;\n}\n\nexport function setDocument2References(document: Document2Node, references: Reference2[]): Document2Node {\n const next = cloneDocument(document);\n next.references = references.map((reference) => ({ ...reference }));\n return next;\n}\n\nexport function updateDocument2Meta(document: Document2Node, patch: Document2MetaProp): Document2Node {\n const next = cloneDocument(document);\n const current = next.meta ?? emptyDocument2Meta();\n next.meta = {\n title: typeof patch.title === 'string' ? patch.title : current.title,\n authors: typeof patch.authors === 'string' ? patch.authors : current.authors,\n abstract: typeof patch.abstract === 'string' ? patch.abstract : current.abstract,\n date: patch.date\n ? normalizeDocument2HijriDate({ ...current.date, ...patch.date })\n : { ...current.date },\n };\n return next;\n}\n","import { toMathObjectJson } from '../document/mathObject.js';\nimport { citeTokenLatex } from './citations.js';\nimport { refTokenLatex } from './labels.js';\nimport type {\n Document2Block,\n Document2BlockJson,\n Document2Json,\n Document2ListItemJson,\n Document2MathObjectJson,\n Document2Node,\n InlineField2,\n Reference2Json,\n TextFormatSpan2Json,\n} from './types.js';\n\ntype SerializedField2 = {\n value: string;\n formats: TextFormatSpan2Json[];\n mathObjects: Array<Document2MathObjectJson | null>;\n hasPersistedMath: boolean;\n};\n\nfunction serializeField(field: InlineField2): SerializedField2 {\n let value = '';\n let hasPersistedMath = false;\n const formats: TextFormatSpan2Json[] = [];\n const mathObjects: Array<Document2MathObjectJson | null> = [];\n\n for (const token of field.tokens) {\n if (token.kind === 'text') {\n const start = value.length;\n value += token.text;\n if (token.text.length > 0 && (token.style?.bold || token.style?.italic || token.style?.underline)) {\n formats.push({\n start,\n end: value.length,\n ...(token.style.bold ? { bold: true } : {}),\n ...(token.style.italic ? { italic: true } : {}),\n ...(token.style.underline ? { underline: true } : {}),\n });\n }\n continue;\n }\n if (token.kind === 'cite') {\n value += citeTokenLatex(token.keys);\n continue;\n }\n if (token.kind === 'ref') {\n value += refTokenLatex(token.keys, token.refCommand);\n continue;\n }\n\n value += token.source;\n if (!token.math || token.sourceOwner === 'raw') {\n if (token.labelEnabled !== undefined || token.label !== undefined) {\n hasPersistedMath = true;\n mathObjects.push({\n node_type: 'RawMathObject',\n ...(token.labelEnabled !== undefined ? { label_enabled: token.labelEnabled } : {}),\n ...(token.label !== undefined ? { label: token.label } : {}),\n });\n } else {\n mathObjects.push(null);\n }\n continue;\n }\n\n hasPersistedMath = true;\n mathObjects.push({\n ...toMathObjectJson(token.math),\n ...(token.sourceSide ? { source_side: token.sourceSide } : {}),\n source_owner: token.sourceOwner,\n ...(token.labelEnabled !== undefined ? { label_enabled: token.labelEnabled } : {}),\n ...(token.label !== undefined ? { label: token.label } : {}),\n });\n }\n\n return { value, formats, mathObjects, hasPersistedMath };\n}\n\nfunction fieldJson(field: InlineField2): Pick<Document2BlockJson, 'value' | 'formats' | 'math_objects'> {\n const serialized = serializeField(field);\n return {\n value: serialized.value,\n ...(serialized.formats.length > 0 ? { formats: serialized.formats } : {}),\n ...(serialized.hasPersistedMath ? { math_objects: serialized.mathObjects } : {}),\n };\n}\n\nfunction listItemJson(item: Extract<Document2Block, { kind: 'list' }>['items'][number]): Document2ListItemJson {\n const field = fieldJson(item.field);\n return {\n value: field.value ?? '',\n ...(field.formats ? { formats: field.formats } : {}),\n ...(field.math_objects ? { math_objects: field.math_objects } : {}),\n ...(item.blocks.length > 0 ? { blocks: item.blocks.map(blockJson) } : {}),\n };\n}\n\nfunction blockJson(block: Document2Block): Document2BlockJson {\n if (block.kind === 'textBlock') {\n return {\n id: block.id,\n command: block.command,\n ...fieldJson(block.field),\n ...(block.command === '\\\\paragraph' ? { centered: block.centered === true } : {}),\n };\n }\n if (block.kind === 'list') {\n return {\n id: block.id,\n command: block.command,\n closing: block.closing,\n items: block.items.map(listItemJson),\n };\n }\n if (block.kind === 'table') {\n const fields = block.rows.map((row) => row.map(serializeField));\n const hasPersistedMath = fields.some((row) => row.some((field) => field.hasPersistedMath));\n return {\n id: block.id,\n command: block.command,\n closing: block.closing,\n columns: block.columns,\n rows: fields.map((row) => row.map((field) => field.value)),\n ...(fields.some((row) => row.some((field) => field.formats.length > 0))\n ? { cell_formats: fields.map((row) => row.map((field) => field.formats)) }\n : {}),\n ...(hasPersistedMath\n ? { math_objects: fields.flatMap((row) => row.flatMap((field) => field.mathObjects)) }\n : {}),\n centered: block.centered,\n caption_enabled: block.captionEnabled,\n caption: block.caption,\n label_enabled: block.labelEnabled,\n label: block.label,\n };\n }\n if (block.kind === 'image') {\n return {\n id: block.id,\n command: block.command,\n value: block.value,\n ...(block.assetId !== undefined ? { asset_id: block.assetId } : {}),\n options: { ...block.options },\n centered: block.centered,\n caption_enabled: block.captionEnabled,\n caption: block.caption,\n label_enabled: block.labelEnabled,\n label: block.label,\n };\n }\n if (block.kind === 'bibliography') {\n return { id: block.id, command: block.command, closing: block.closing };\n }\n return { id: block.id, command: block.command, value: block.value };\n}\n\nfunction referenceJson(reference: Document2Node['references'][number]): Reference2Json {\n return {\n key: reference.key,\n authors: reference.authors,\n title: reference.title,\n year: reference.year,\n url: reference.url,\n venue: reference.venue,\n field_separator: reference.fieldSeparator,\n };\n}\n\n/** Convert the live editor AST to the canonical JSON wire format. */\nexport function toDocumentJson2(document: Document2Node): Document2Json {\n if (document.nodeType !== 'DocumentObject' || !Array.isArray(document.blocks)) {\n throw new Error('toDocumentJson2 requires a live Document2Node');\n }\n return {\n node_type: 'DocumentObject',\n meta: {\n title: document.meta.title,\n authors: document.meta.authors,\n date: { ...document.meta.date },\n abstract: document.meta.abstract,\n },\n references: document.references.map(referenceJson),\n blocks: document.blocks.map(blockJson),\n };\n}\n","import {\n addDocument2ImageBlock,\n addDocument2TextBlock,\n removeDocument2BlockById,\n} from './commands.js';\nimport { createInlineField2, fromDocumentJson2 } from './importJson.js';\nimport { toDocumentJson2 } from './exportJson.js';\nimport type { Document2Block, Document2Json, Document2Node, TextBlock2 } from './types.js';\n\nexport type Document2TextBlockKind = 'section' | 'subsection' | 'subsubsection' | 'paragraph';\n\nexport type Document2Anchor =\n | { after_block_id: string }\n | { end: true };\n\nexport type Document2Command =\n | {\n op: 'insert_text_block';\n kind: Document2TextBlockKind;\n text: string;\n anchor: Document2Anchor;\n }\n | {\n op: 'replace_text_block';\n block_id: string;\n text: string;\n }\n | {\n op: 'remove_block';\n block_id: string;\n }\n | {\n op: 'insert_figure';\n asset_id: string;\n value?: string;\n caption?: string;\n label?: string;\n anchor: Document2Anchor;\n };\n\nexport type Document2CommandErrorCode =\n | 'invalid_document'\n | 'invalid_command'\n | 'missing_block_id'\n | 'duplicate_block_id'\n | 'anchor_not_found'\n | 'block_not_found'\n | 'block_kind_mismatch'\n | 'unsupported_inline_content';\n\nexport class Document2CommandError extends Error {\n readonly code: Document2CommandErrorCode;\n\n constructor(code: Document2CommandErrorCode, message: string) {\n super(message);\n this.name = 'Document2CommandError';\n this.code = code;\n }\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction requireString(value: unknown, field: string, allowEmpty = true): string {\n if (typeof value !== 'string' || (!allowEmpty && value.trim().length === 0)) {\n throw new Document2CommandError('invalid_command', `${field} must be a${allowEmpty ? '' : ' non-empty'} string`);\n }\n return value;\n}\n\nfunction parseAnchor(value: unknown): Document2Anchor {\n if (!isObject(value)) {\n throw new Document2CommandError('invalid_command', 'anchor must be an object');\n }\n const hasEnd = value.end === true;\n const afterBlockId = typeof value.after_block_id === 'string' ? value.after_block_id.trim() : '';\n const hasAfterBlock = afterBlockId.length > 0;\n if (hasEnd && hasAfterBlock) {\n throw new Document2CommandError('invalid_command', 'anchor cannot contain both end and after_block_id');\n }\n if (hasEnd) {\n return { end: true };\n }\n if (hasAfterBlock) {\n return { after_block_id: afterBlockId };\n }\n throw new Document2CommandError('invalid_command', 'anchor requires end: true or a non-empty after_block_id');\n}\n\nfunction optionalString(value: Record<string, unknown>, field: string): string | undefined {\n if (!(field in value)) {\n return undefined;\n }\n if (typeof value[field] !== 'string') {\n throw new Document2CommandError('invalid_command', `${field} must be a string when provided`);\n }\n return value[field];\n}\n\nfunction parseTextBlockKind(value: unknown): Document2TextBlockKind {\n if (value === 'section' || value === 'subsection' || value === 'subsubsection' || value === 'paragraph') {\n return value;\n }\n throw new Document2CommandError('invalid_command', 'kind must be section, subsection, subsubsection, or paragraph');\n}\n\nfunction parseCommand(value: unknown): Document2Command {\n if (!isObject(value) || typeof value.op !== 'string') {\n throw new Document2CommandError('invalid_command', 'command requires an op');\n }\n\n if (value.op === 'insert_text_block') {\n return {\n op: value.op,\n kind: parseTextBlockKind(value.kind),\n text: requireString(value.text, 'text'),\n anchor: parseAnchor(value.anchor),\n };\n }\n if (value.op === 'replace_text_block') {\n return {\n op: value.op,\n block_id: requireString(value.block_id, 'block_id', false).trim(),\n text: requireString(value.text, 'text'),\n };\n }\n if (value.op === 'remove_block') {\n return {\n op: value.op,\n block_id: requireString(value.block_id, 'block_id', false).trim(),\n };\n }\n if (value.op === 'insert_figure') {\n const figureValue = optionalString(value, 'value');\n const caption = optionalString(value, 'caption');\n const label = optionalString(value, 'label');\n return {\n op: value.op,\n asset_id: requireString(value.asset_id, 'asset_id', false).trim(),\n ...(figureValue !== undefined ? { value: figureValue } : {}),\n ...(caption !== undefined ? { caption } : {}),\n ...(label !== undefined ? { label } : {}),\n anchor: parseAnchor(value.anchor),\n };\n }\n\n throw new Document2CommandError('invalid_command', `Unsupported document command: ${value.op}`);\n}\n\nfunction parseDocument(json: Document2Json): Document2Node {\n try {\n return fromDocumentJson2(json);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Invalid DocumentObject JSON';\n throw new Document2CommandError('invalid_document', message);\n }\n}\n\nfunction commandForKind(kind: Document2TextBlockKind): TextBlock2['command'] {\n if (kind === 'section') {\n return '\\\\section';\n }\n if (kind === 'subsection') {\n return '\\\\subsection';\n }\n if (kind === 'subsubsection') {\n return '\\\\subsubsection';\n }\n return '\\\\paragraph';\n}\n\nfunction insertionIndex(document: Document2Node, anchor: Document2Anchor): number {\n if ('end' in anchor) {\n return document.blocks.length;\n }\n const index = document.blocks.findIndex((block) => block.id === anchor.after_block_id);\n if (index < 0) {\n throw new Document2CommandError('anchor_not_found', `Anchor block was not found: ${anchor.after_block_id}`);\n }\n return index + 1;\n}\n\nfunction afterBlockId(document: Document2Node, index: number): string | null {\n return index > 0 ? document.blocks[index - 1]?.id ?? null : null;\n}\n\nfunction insertedBlock(document: Document2Node, index: number): Document2Block {\n const block = document.blocks[index];\n if (!block) {\n throw new Document2CommandError('invalid_command', 'Document command did not insert a block');\n }\n return block;\n}\n\nfunction insertTextBlock(document: Document2Node, command: Extract<Document2Command, { op: 'insert_text_block' }>): Document2Node {\n const index = insertionIndex(document, command.anchor);\n const next = addDocument2TextBlock(document, commandForKind(command.kind), afterBlockId(document, index));\n const block = insertedBlock(next, index);\n if (block.kind !== 'textBlock') {\n throw new Document2CommandError('block_kind_mismatch', 'Inserted block is not a text block');\n }\n block.field = createInlineField2(command.text);\n return next;\n}\n\nfunction replaceTextBlock(document: Document2Node, command: Extract<Document2Command, { op: 'replace_text_block' }>): Document2Node {\n const index = document.blocks.findIndex((block) => block.id === command.block_id);\n if (index < 0) {\n throw new Document2CommandError('block_not_found', `Document block was not found: ${command.block_id}`);\n }\n const block = document.blocks[index];\n if (!block || block.kind !== 'textBlock') {\n throw new Document2CommandError('block_kind_mismatch', `Document block is not a text block: ${command.block_id}`);\n }\n if (block.field.tokens.some((token) => token.kind !== 'text' || token.style !== undefined)) {\n throw new Document2CommandError(\n 'unsupported_inline_content',\n 'Whole-block replacement is not supported for formatted or structured inline content',\n );\n }\n const next = parseDocument(toDocumentJson2(document));\n const nextBlock = next.blocks[index];\n if (!nextBlock || nextBlock.kind !== 'textBlock') {\n throw new Document2CommandError('block_kind_mismatch', `Document block is not a text block: ${command.block_id}`);\n }\n nextBlock.field = createInlineField2(command.text);\n return next;\n}\n\nfunction removeBlock(document: Document2Node, command: Extract<Document2Command, { op: 'remove_block' }>): Document2Node {\n if (!document.blocks.some((block) => block.id === command.block_id)) {\n throw new Document2CommandError('block_not_found', `Document block was not found: ${command.block_id}`);\n }\n return removeDocument2BlockById(document, command.block_id);\n}\n\nfunction insertFigure(document: Document2Node, command: Extract<Document2Command, { op: 'insert_figure' }>): Document2Node {\n const index = insertionIndex(document, command.anchor);\n const next = addDocument2ImageBlock(\n document,\n { assetId: command.asset_id, ...(command.value !== undefined ? { value: command.value } : {}) },\n afterBlockId(document, index),\n );\n const block = insertedBlock(next, index);\n if (block.kind !== 'image') {\n throw new Document2CommandError('block_kind_mismatch', 'Inserted block is not a figure');\n }\n if (command.caption !== undefined) {\n block.caption = command.caption;\n block.captionEnabled = command.caption.trim().length > 0;\n }\n if (command.label !== undefined) {\n block.label = command.label;\n block.labelEnabled = command.label.trim().length > 0;\n }\n return next;\n}\n\n/** Apply one validated, top-level command and return canonical JSON. */\nexport function applyDocument2Command(json: Document2Json, commandInput: Document2Command): Document2Json {\n const document = parseDocument(json);\n const command = parseCommand(commandInput);\n let next: Document2Node;\n\n if (command.op === 'insert_text_block') {\n next = insertTextBlock(document, command);\n } else if (command.op === 'replace_text_block') {\n next = replaceTextBlock(document, command);\n } else if (command.op === 'remove_block') {\n next = removeBlock(document, command);\n } else {\n next = insertFigure(document, command);\n }\n\n return toDocumentJson2(next);\n}\n","import { Document2CommandError } from './jsonCommands.js';\nimport type { Document2BlockJson, Document2Json } from './types.js';\n\nexport type Document2OutlineKind =\n | 'section'\n | 'subsection'\n | 'subsubsection'\n | 'paragraph'\n | 'list'\n | 'table'\n | 'figure'\n | 'bibliography'\n | 'raw';\n\nexport type Document2OutlineEntry = {\n id: string;\n kind: Document2OutlineKind;\n command: string;\n excerpt: string;\n};\n\nconst EXCERPT_LIMIT = 160;\n\nfunction normalizeExcerpt(value: string): string {\n const normalized = value.replace(/\\s+/g, ' ').trim();\n if (normalized.length <= EXCERPT_LIMIT) {\n return normalized;\n }\n return `${normalized.slice(0, EXCERPT_LIMIT - 3)}...`;\n}\n\nfunction outlineKind(command: string): Document2OutlineKind {\n if (command === '\\\\section') {\n return 'section';\n }\n if (command === '\\\\subsection') {\n return 'subsection';\n }\n if (command === '\\\\subsubsection') {\n return 'subsubsection';\n }\n if (command === '\\\\paragraph') {\n return 'paragraph';\n }\n if (command === '\\\\begin{itemize}' || command === '\\\\begin{enumerate}') {\n return 'list';\n }\n if (command === '\\\\begin{tabular}') {\n return 'table';\n }\n if (command === '\\\\includegraphics') {\n return 'figure';\n }\n if (command === '\\\\begin{thebibliography}' || command === '\\\\bibliography') {\n return 'bibliography';\n }\n return 'raw';\n}\n\nfunction blockExcerpt(block: Document2BlockJson): string {\n if (block.command === '\\\\begin{itemize}' || block.command === '\\\\begin{enumerate}') {\n return normalizeExcerpt((block.items ?? []).map((item) => item.value).join(' '));\n }\n if (block.command === '\\\\begin{tabular}') {\n return normalizeExcerpt((block.rows ?? []).flat().join(' '));\n }\n if (block.command === '\\\\includegraphics') {\n return normalizeExcerpt(block.caption || block.asset_id || block.value || '');\n }\n return normalizeExcerpt(block.value ?? '');\n}\n\n/** Return a compact top-level outline for a canonical document. */\nexport function document2Outline(json: Document2Json): Document2OutlineEntry[] {\n if (!json || json.node_type !== 'DocumentObject' || !Array.isArray(json.blocks)) {\n throw new Document2CommandError('invalid_document', 'DocumentObject requires a blocks array');\n }\n\n const usedIds = new Set<string>();\n return json.blocks.map((block) => {\n if (!block || typeof block !== 'object' || typeof block.command !== 'string') {\n throw new Document2CommandError('invalid_document', 'Document outline requires blocks with string commands');\n }\n const id = typeof block.id === 'string' ? block.id.trim() : '';\n if (id.length === 0) {\n throw new Document2CommandError('missing_block_id', 'Document outline requires canonical block IDs');\n }\n if (usedIds.has(id)) {\n throw new Document2CommandError('duplicate_block_id', `Duplicate document block ID: ${id}`);\n }\n usedIds.add(id);\n return {\n id,\n kind: outlineKind(block.command),\n command: block.command,\n excerpt: blockExcerpt(block),\n };\n });\n}\n","import type { Document2LabelEntry } from './labels.js';\nimport type { Reference2 } from './types.js';\n\nexport type Document2KeyError = 'empty' | 'invalid' | 'duplicate';\n\nconst DOCUMENT2_KEY_PATTERN = /^[\\p{L}\\p{M}0-9:._-]+$/u;\n\n/** NFC-normalize and trim a document key (label or bibliography). */\nexport function normalizeDocument2Key(key: string): string {\n return key.normalize('NFC').trim();\n}\n\n/** True when key matches Unicode letters/marks, ASCII digits, and :._- with no spaces. */\nexport function isValidDocument2Key(key: string): boolean {\n const normalized = normalizeDocument2Key(key);\n return normalized.length > 0 && DOCUMENT2_KEY_PATTERN.test(normalized);\n}\n\nexport type Document2KeyNamespace = {\n references?: Array<Pick<Reference2, 'id' | 'key'>>;\n labels?: Array<Pick<Document2LabelEntry, 'ownerId' | 'key'>>;\n /** Skip this reference id when checking (editing that entry). */\n excludeReferenceId?: string;\n /** Skip this label owner id when checking (editing that float/eq). */\n excludeOwnerId?: string;\n};\n\n/** Returns true if another reference or label already uses this key (NFC match). */\nexport function isDuplicateDocument2Key(key: string, namespace: Document2KeyNamespace): boolean {\n const normalized = normalizeDocument2Key(key);\n if (normalized.length === 0) {\n return false;\n }\n for (const reference of namespace.references ?? []) {\n if (namespace.excludeReferenceId && reference.id === namespace.excludeReferenceId) {\n continue;\n }\n if (normalizeDocument2Key(reference.key) === normalized) {\n return true;\n }\n }\n for (const label of namespace.labels ?? []) {\n if (namespace.excludeOwnerId && label.ownerId === namespace.excludeOwnerId) {\n continue;\n }\n if (normalizeDocument2Key(label.key) === normalized) {\n return true;\n }\n }\n return false;\n}\n\n/** Classify a key for UI messaging: empty, invalid charset, or duplicate. */\nexport function document2KeyError(key: string, namespace: Document2KeyNamespace = {}): Document2KeyError | null {\n const normalized = normalizeDocument2Key(key);\n if (normalized.length === 0) {\n return 'empty';\n }\n if (!DOCUMENT2_KEY_PATTERN.test(normalized)) {\n return 'invalid';\n }\n if (isDuplicateDocument2Key(normalized, namespace)) {\n return 'duplicate';\n }\n return null;\n}\n","/** Arabic XeLaTeX preamble fragments for full-document export. */\nimport { NON_DEFAULT_CHARACTER_FONT_SPECS } from '../editor/characterFonts.js';\n\nexport type ArabicDigitsMapping = 'arabicdigits' | 'farsidigits' | 'digits';\n\nexport type ArabicXeLatexPreambleOptions = {\n digitsMapping?: ArabicDigitsMapping;\n /** When true, add the article class twocolumn option. Default false. */\n twocolumn?: boolean;\n};\n\nfunction fontOptions(digitsMapping: ArabicDigitsMapping, includeScript = true): string {\n const parts: string[] = [];\n if (includeScript) {\n parts.push('Script=Arabic');\n }\n if (digitsMapping !== 'digits') {\n parts.push(`Mapping=${digitsMapping}`);\n }\n if (parts.length === 0) {\n return '';\n }\n return `[${parts.join(',')}]`;\n}\n\nexport function arabicXeLatexPreamblePkg(twocolumn = false): string {\n const classOptions = twocolumn\n ? '12pt,a4paper,notitlepage,twocolumn'\n : '12pt,a4paper,notitlepage';\n return (\n `\n\\\\documentclass[${classOptions}]{article}\n` +\n String.raw`\\usepackage{amsmath,amsfonts,amssymb,mathrsfs,tikz,fancyhdr, mathtools}\n\\usepackage{fontspec} % For loading OpenType fonts\n\\usepackage{unicode-math} % For setting the math font\n\\usepackage{polyglossia} % For Arabic support\n\\usepackage{array}\n\\usepackage{cancel}\n\\usepackage{bidi}\n\\usepackage{multirow}\n\\usepackage{booktabs}\n\\usepackage{graphicx} % For \\reflectbox\n\\usepackage{xcolor}\n\\usepackage{tikz}\n\\usepackage{tcolorbox} % For tcolorbox environment\n\\usepackage{textcomp} % For \\textrightarrow command\n\\usepackage{url}\n\n\n% visit : https://www.symbolcopy.com/punctuation-symbol.html\n% for inversed punctuation\n\n% save inverted comma for use - copy paste -> ،\n% save back tick for use - copy paste -> ` + '`'\n );\n}\n\nexport function arabicXeLatexPreambleFont(digitsMapping: ArabicDigitsMapping = 'arabicdigits'): string {\n const customFonts = NON_DEFAULT_CHARACTER_FONT_SPECS\n .filter((font) => font.latexFontCommand && font.latexFontFamily)\n .map((font) => `\\\\newfontfamily${font.latexFontCommand}${fontOptions(digitsMapping)}{${font.latexFontFamily}}`)\n .join('\\n');\n const mathFontOptions = fontOptions(digitsMapping, false);\n return `\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n% Persian digits: Mapping=farsidigits\n% Arabic-Indic digits: Mapping=arabicdigits\n% Western digits: omit Mapping entirely\n\\\\setdefaultlanguage[calendar=gregorian]{arabic} % from polyglossia\n\\\\setmainfont${fontOptions(digitsMapping)}{Amiri}\n${customFonts}\n\\\\newfontfamily\\\\boldarabic${fontOptions(digitsMapping)}{Amiri Bold}\n\\\\newfontfamily\\\\italicarabic${fontOptions(digitsMapping)}{Amiri Italic}\n\n% for polyglossia url I dont know, sugggested by cursor\n\\\\newfontfamily\\\\arabicfonttt${fontOptions(digitsMapping)}{Amiri}\n\\\\newfontfamily\\\\arabicfontsf${fontOptions(digitsMapping)}{Amiri}\n\n\n% Explicitly set math font to XITS Math\n\\\\setmathfont${mathFontOptions}{XITS Math} % Ensure XITS Math is correctly installed and available\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n`;\n}\n\nexport function arabicXeLatexPreambleCmd(): string {\n const fontCommands = NON_DEFAULT_CHARACTER_FONT_SPECS\n .filter((font) => font.macro && font.latexFontCommand)\n .map((font) => `\\\\newcommand{${font.macro}}[1]{\\\\text{${font.latexFontCommand}{#1}}}`)\n .join('\\n');\n return String.raw`\n% Run with XeLaTeX compiler\n${fontCommands}\n\\newcommand{\\butexmirror}[1]{\\reflectbox{\\(#1\\)}}\n\n\\newcommand{\\arabN}{\\text{\\diwanioutlineshaded{ط}}}\n\\newcommand{\\arabZ}{\\text{\\diwanioutlineshaded{ص}}}\n\\newcommand{\\arabQ}{\\text{\\diwanioutlineshaded{ن}}}\n\\newcommand{\\arabR}{\\text{\\diwanioutlineshaded{ح}}}\n\\newcommand{\\arabC}{\\text{\\diwanioutlineshaded{ع}}}\n\\newcommand{\\arabH}{\\text{\\diwanioutlineshaded{ر}}}\n\n\n\\newcommand{\\lowerscript}[1]{\\raisebox{-4pt}{\\scriptsize #1}}\n\\newcommand{\\llowerscript}[1]{\\raisebox{-8pt}{\\scriptsize #1}}\n\\newcommand{\\lllowerscript}[2]{\\raisebox{#2pt}{\\scriptsize #1}}\n\n\\newcommand{\\arabdsub}[3]{\\prescript{}{#1}{\\prescript{}{#2}{#3}}} % arabic double subscript\n\\newcommand{\\arabsub}[2]{\\prescript{}{#1}{#2}} % arabic single subscript\n\n\n\n\\newcommand{\\upperscript}[1]{\\raisebox{8pt}{\\scriptsize #1}}\n\\newcommand{\\uupperscript}[2]{\\raisebox{#2pt}{\\scriptsize #1}}\n\\newcommand{\\vertbar}{\\rule[-1ex]{0.5pt}{2.5ex}}\n\\newcommand{\\horzbar}{\\rule[.5ex]{2.5ex}{0.5pt}}\n\n\n\\newcommand{\\arsqrt}[2][]{\\reflectbox{\\(\\sqrt[\\reflectbox{\\(#1\\)}]{\\reflectbox{\\(#2\\)}}\\)}}\n\\newcommand{\\arabsqrt}[2][]{\\arsqrt[#1]{#2}}\n\\newcommand{\\arabvec}[1]{\\reflectbox{$\\vec{\\reflectbox{$#1$}}$}}\n\n\\newcommand{\\arabexp}[1]{{}^{#1}\\!\\raisebox{-4.5pt}{\\text{\\diwani{ه}}}}\n\\newcommand{\\arablog}[2]{\\left(\\text{#2}\\right)\\!\\prescript{}{\\text{#1}}{\\text{\\diwani{لو}}}}\n\\newcommand{\\arabnlog}[1]{\\left(\\text{#1}\\right)\\!\\prescript{}{\\text{\\diwani{ه}}}{\\text{\\diwani{لو}}}}\n\n\\newcommand{\\arabcos}[1]{\\left(#1\\right)\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{جتا}}}}\n\\newcommand{\\arabsin}[1]{\\left(#1\\right)\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{جا}}}}\n\\newcommand{\\arabtan}[1]{\\left(#1\\right)\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{ظا}}}}\n\\newcommand{\\arabcot}[1]{\\left(#1\\right)\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{ظتا}}}}\n\\newcommand{\\arabsec}[1]{\\left(#1\\right)\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{قا}}}}\n\\newcommand{\\arabcsc}[1]{\\left(#1\\right)\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{قتا}}}}\n\n\\newcommand{\\arabacos}[1]{\\left(#1\\right)\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{قجتا}}}}\n\\newcommand{\\arabasin}[1]{\\left(#1\\right)\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{قجا}}}}\n\\newcommand{\\arabatan}[1]{\\left(#1\\right)\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{قظا}}}}\n\\newcommand{\\arabacot}[1]{\\left(#1\\right)\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{قظتا}}}}\n\\newcommand{\\arabasec}[1]{\\left(#1\\right)\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{ققا}}}}\n\\newcommand{\\arabacsc}[1]{\\left(#1\\right)\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{ققتا}}}}\n\n\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n% summation\n\\newcommand{\\arablim}[2]{\\underset{#2 \\leftarrow #1}{\\text{نـــــها}}}\n\\newcommand{\\arabsum}[2]{\\underset{#1}{\\overset{#2}{\\text{مجـــ}}}}\n\\newcommand{\\arabprod}[2]{\\underset{#1}{\\overset{#2}{\\text{جـــذ}}}}\n\\newcommand{\\arabint}[2]{\\prescript{#2}{#1\\!\\!\\!}\\int}\n\n\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n% we define this command to make it ease for change of notation later\n\\newcommand{\\ad}[0]{\\text{ء}} % \"ad\" for arabic differentiation or derivative (ء\" لإشتقاق\")\n\\newcommand{\\arpi}[0]{\\!\\text{\\diwani{ط}}}\n\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n% differentials\n\n\\newcommand{\\arabdiff}[2]{\\frac{#1\\ad}{#2\\ad}} % arabic differential\n\\newcommand{\\arabddiff}[2]{\\frac{#1{}^{2}\\ad}{{}^{2}#2\\ad}} % arabic second differential\n\n\\newcommand{\\arabode}[2][-5pt]{\\stackrel{\\raisebox{#1}{$\\cdot$}}{\\text{#2}}}\n\\newcommand{\\arabodde}[2][-5pt]{\\stackrel{\\raisebox{#1}{$\\vcenter{\\hbox{$\\cdot\\!\\cdot$}}$}}{\\text{#2}}}\n\\newcommand{\\araboddde}[2][-5pt]{\\stackrel{\\raisebox{#1}{$\\vcenter{\\hbox{$\\cdot\\!\\cdot\\!\\cdot$}}$}}{\\text{#2}}}\n\\newcommand{\\arabpde}[1]{\\prescript{}{#1\\!\\!}{\\nabla}} % arabic partial differential equation (PDE)\n\n\\newcommand{\\arabprime}[0]{\\reflectbox{$\\prime$}\\!} % arabic prime notation\n\\newcommand{\\arabpprime}[0]{\\reflectbox{$\\prime$}\\reflectbox{$\\prime$}\\!} % arabic prime notation\n\\newcommand{\\arabppprime}[0]{\\reflectbox{$\\prime$}\\reflectbox{$\\prime$}\\reflectbox{$\\prime$}\\!} % arabic prime notation\n\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n% probability\n\\newcommand{\\ap}[0]{\\!\\text{\\diwani{حـ}}} % arabic Probability - used a lot so short form\n\\newcommand{\\arabExpct}[0]{\\text{\\diwani{توقـ}}} % arabic Expectation\n\\newcommand{\\arabVar}[0]{\\!\\text{\\diwani{با}}} % arabic Variance\n\\newcommand{\\arabCov}[0]{\\!\\text{\\diwani{ت}}} % arabic Covariance\n\n\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n% custom commands specific to lesson\n\\newcommand{\\lagrange}[2]{\\left(#2\\right)\\!\\prescript{}{#1}{\\text{\\diwani{لا}}}}\n\\newcommand{\\xii}[0]{\\left(\\prescript{}{\\text{يـ}}{\\text{س}}\\right)\\!}\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n\n\n\\newcommand{\\arexp}[0]{\\!\\raisebox{-4.5pt}{\\text{\\diwani{ه}}}}\n\\newcommand{\\arlog}[0]{\\!\\!\\text{\\diwani{لو}}}\n\\newcommand{\\arln}[0]{\\!\\!\\prescript{}{\\text{\\diwani{ه}}}{\\text{\\diwani{لو}}}}\n\\newcommand{\\ardet}[0]{\\!\\!\\text{\\diwani{محدد}}}\n\n\\newcommand{\\arsum}[0]{\\text{مجـــ}}\n\\newcommand{\\arprod}[0]{\\text{جـــذ}}\n\n\\newcommand{\\arlim}[0]{\\text{نـــــها}}\n\\newcommand{\\armax}[0]{\\text{أكبر}}\n\\newcommand{\\armin}[0]{\\text{أصغر}}\n\\newcommand{\\arsup}[0]{\\text{أعلى}}\n\\newcommand{\\arinf}[0]{\\text{أدنى}}\n\n\\newcommand{\\arsin}[0]{\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{جا}}}}\n\\newcommand{\\arcos}[0]{\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{جتا}}}}\n\\newcommand{\\artan}[0]{\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{ظا}}}}\n\\newcommand{\\arcot}[0]{\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{ظتا}}}}\n\\newcommand{\\arsec}[0]{\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{قا}}}}\n\\newcommand{\\arcsc}[0]{\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{قتا}}}} \n\n\\newcommand{\\arasin}[0]{\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{قجا}}}}\n\\newcommand{\\aracos}[0]{\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{قجتا}}}}\n\\newcommand{\\aratan}[0]{\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{قظا}}}}\n\\newcommand{\\aracot}[0]{\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{قظتا}}}}\n\\newcommand{\\arasec}[0]{\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{ققا}}}}\n\\newcommand{\\aracsc}[0]{\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{ققتا}}}}\n\n\\newcommand{\\arsinh}[0]{\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{جزا}}}}\n\\newcommand{\\arcosh}[0]{\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{جتزا}}}}\n\\newcommand{\\artanh}[0]{\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{ظزا}}}}\n\\newcommand{\\arcoth}[0]{\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{ظتزا}}}}\n\\newcommand{\\arsech}[0]{\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{قزا}}}}\n\\newcommand{\\arcsch}[0]{\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{قتزا}}}}\n\n\\newcommand{\\arasinh}[0]{\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{قجزا}}}}\n\\newcommand{\\aracosh}[0]{\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{قجتزا}}}} \n\\newcommand{\\aratanh}[0]{\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{قظزا}}}}\n\\newcommand{\\aracoth}[0]{\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{قظتزا}}}}\n\\newcommand{\\arasech}[0]{\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{ققزا}}}}\n\\newcommand{\\aracsch}[0]{\\!\\!\\raisebox{-2.5pt}{\\text{\\diwani{ققتزا}}}}\n\n\\newcommand{\\unit}[1]{\\text{#1}}\n\\newcommand{\\idx}[1]{#1}\n\\newcommand{\\arbinom}[2]{\\left(\\begin{array}{c} #1 \\\\ #2 \\end{array} \\right)}\n`;\n}\n\nexport function getArabicXeLatexPreamble(\n digitsMappingOrOptions: ArabicDigitsMapping | ArabicXeLatexPreambleOptions = 'arabicdigits',\n): string {\n const options: ArabicXeLatexPreambleOptions =\n typeof digitsMappingOrOptions === 'string'\n ? { digitsMapping: digitsMappingOrOptions }\n : digitsMappingOrOptions;\n const digitsMapping = options.digitsMapping ?? 'arabicdigits';\n const twocolumn = options.twocolumn === true;\n return (\n arabicXeLatexPreamblePkg(twocolumn) +\n arabicXeLatexPreambleFont(digitsMapping) +\n arabicXeLatexPreambleCmd()\n );\n}\n","import { renderMathNodeLatex } from '../document/mathObject.js';\nimport { mirrorBuTeXOperatorsInTex } from '../editor/atomicCommandsOperators.js';\nimport type { DigitFormId } from '../editor/types.js';\nimport {\n getArabicXeLatexPreamble,\n type ArabicDigitsMapping,\n} from './arabicPreamble.js';\nimport {\n BUTEX_CLOSING_HAMDALA,\n butexBasmalaDisplayLatex,\n butexBasmalaTitlingPreamble,\n butexMaghribiDisplayLatex,\n document2HasAbstract,\n document2HasMaketitle,\n emptyDocument2Meta,\n formatHijriDate,\n} from './articleMeta.js';\nimport { bibliographyEntryLatex, citeTokenLatex } from './citations.js';\nimport { refTokenLatex, stripDisplayMathDelimiters } from './labels.js';\nimport type {\n Document2Block,\n Document2Meta,\n Document2Node,\n ImageBlock2,\n InlineField2,\n InlineToken2,\n ListBlock2,\n MathToken2,\n TableBlock2,\n TextStyle2,\n TextBlock2,\n} from './types.js';\n\nexport type Document2LatexOptions = {\n /**\n * When true (default), emit a complete Arabic XeLaTeX file:\n * preamble + \\\\begin{document} + body + \\\\end{document}.\n * Pass false for body-only blocks.\n */\n wrapDocument?: boolean;\n /** Font digit Mapping when wrapping. Default 'arabicdigits'. */\n digitsMapping?: ArabicDigitsMapping;\n /** Document-level digit form for XeLaTeX font Mapping. Ignored when digitsMapping is set. */\n digitForm?: DigitFormId;\n /** When true, use article class option twocolumn. Default false. */\n twocolumn?: boolean;\n};\n\nfunction digitsMappingFromDigitForm(digitForm: DigitFormId | undefined): ArabicDigitsMapping {\n if (digitForm === 'western') {\n return 'digits';\n }\n if (digitForm === 'persianIndic') {\n return 'farsidigits';\n }\n return 'arabicdigits';\n}\n\nfunction mathBodyLatex(token: MathToken2): string {\n if (token.sourceOwner === 'editor') {\n return stripDisplayMathDelimiters(mirrorBuTeXOperatorsInTex(token.source, { target: 'compile' }));\n }\n if (!token.math || token.sourceOwner === 'raw') {\n return stripDisplayMathDelimiters(token.source);\n }\n const rendered = renderMathNodeLatex(token.math);\n return stripDisplayMathDelimiters(rendered);\n}\n\nfunction styledTextLatex(text: string, style: TextStyle2 | undefined): string {\n let output = text;\n if (style?.bold) {\n output = `\\\\textbf{${output}}`;\n }\n if (style?.italic) {\n output = `\\\\textit{${output}}`;\n }\n if (style?.underline) {\n output = `\\\\underline{${output}}`;\n }\n return output;\n}\n\nfunction tokenLatex(token: InlineToken2): string {\n if (token.kind === 'text') {\n return styledTextLatex(token.text, token.style);\n }\n if (token.kind === 'cite') {\n return citeTokenLatex(token.keys);\n }\n if (token.kind === 'ref') {\n return refTokenLatex(token.keys, token.refCommand);\n }\n if (token.display && token.labelEnabled && token.label && token.label.trim().length > 0) {\n const body = mathBodyLatex(token);\n return `\\\\begin{equation}\\n${body}\\n\\\\label{${token.label.trim()}}\\n\\\\end{equation}`;\n }\n if (token.sourceOwner === 'editor') {\n return mirrorBuTeXOperatorsInTex(token.source, { target: 'compile' });\n }\n if (!token.math || token.sourceOwner === 'raw') {\n return token.source;\n }\n return renderMathNodeLatex(token.math);\n}\n\nexport function inlineFieldLatex(field: InlineField2): string {\n return field.tokens.map((token) => tokenLatex(token)).join('');\n}\n\nfunction textBlockLatex(block: TextBlock2): string {\n const content = inlineFieldLatex(block.field);\n const body = block.command === '\\\\paragraph' ? `\\\\par\\n${content}` : `${block.command}{${content}}`;\n if (block.command === '\\\\paragraph' && block.centered) {\n return `\\\\begin{center}\\n${body}\\n\\\\end{center}`;\n }\n return body;\n}\n\nfunction indent(value: string): string {\n return value\n .split('\\n')\n .map((line) => ` ${line}`)\n .join('\\n');\n}\n\nfunction listBlockLatex(block: ListBlock2, references: Document2Node['references']): string {\n const items = block.items\n .map((item) => {\n const nested = item.blocks.map((child) => '\\n' + indent(blockLatex(child, references))).join('');\n return ` \\\\item ${inlineFieldLatex(item.field)}${nested}`;\n })\n .join('\\n');\n return `${block.command}\\n${items}\\n${block.closing}`;\n}\n\nfunction tabularInnerLatex(block: TableBlock2): string {\n const rows = block.rows\n .map((row) => ` ${row.map((cell) => inlineFieldLatex(cell)).join(' & ')}`)\n .join(' \\\\\\\\\\n');\n return `${block.command}{${block.columns}}\\n${rows}\\n${block.closing}`;\n}\n\nfunction floatCaptionLabelLines(block: ImageBlock2 | TableBlock2): string[] {\n const lines: string[] = [];\n if (block.captionEnabled && block.caption.trim().length > 0) {\n lines.push(` \\\\caption{${block.caption.trim()}}`);\n }\n if (block.labelEnabled && block.label.trim().length > 0) {\n lines.push(` \\\\label{${block.label.trim()}}`);\n }\n return lines;\n}\n\nfunction tableBlockLatex(block: TableBlock2): string {\n const lines = ['\\\\begin{table}[htbp]'];\n if (block.centered) {\n lines.push(' \\\\centering');\n }\n lines.push(...floatCaptionLabelLines(block));\n lines.push(indent(tabularInnerLatex(block)));\n lines.push('\\\\end{table}');\n return lines.join('\\n');\n}\n\n/** Prefer \\\\columnwidth so figures fit a column (equals \\\\textwidth in one-column). */\nfunction remapImageWidthForColumns(value: string): string {\n return value.replace(/\\\\textwidth\\b/g, '\\\\columnwidth');\n}\n\nfunction imageOptionsLatex(block: ImageBlock2, constrainToColumn: boolean): string {\n const entries = Object.entries(block.options).map(([key, value]) => {\n if (constrainToColumn && key === 'width') {\n return [key, remapImageWidthForColumns(value)] as const;\n }\n return [key, value] as const;\n });\n if (entries.length === 0) {\n return '';\n }\n return `[${entries.map(([key, value]) => `${key}=${value}`).join(',')}]`;\n}\n\nfunction imageBlockLatex(block: ImageBlock2): string {\n const lines = ['\\\\begin{figure}[htbp]'];\n if (block.centered) {\n lines.push(' \\\\centering');\n }\n // Remap textwidth→columnwidth: safe in one-column, required in twocolumn.\n lines.push(` ${block.command}${imageOptionsLatex(block, true)}{${block.value}}`);\n lines.push(...floatCaptionLabelLines(block));\n lines.push('\\\\end{figure}');\n return lines.join('\\n');\n}\n\nfunction blockLatex(block: Document2Block, references: Document2Node['references']): string {\n if (block.kind === 'textBlock') {\n return textBlockLatex(block);\n }\n if (block.kind === 'list') {\n return listBlockLatex(block, references);\n }\n if (block.kind === 'table') {\n return tableBlockLatex(block);\n }\n if (block.kind === 'image') {\n return imageBlockLatex(block);\n }\n if (block.kind === 'bibliography') {\n const width = String(Math.max(references.length, 9));\n const items = references.map((reference) => ` ${bibliographyEntryLatex(reference)}`).join('\\n');\n return `${block.command}{${width}}\\n${items}\\n${block.closing}`;\n }\n return block.value;\n}\n\nfunction authorLatex(authors: string): string {\n return authors\n .split(/\\n+/)\n .map((line) => line.trim())\n .filter((line) => line.length > 0)\n .join(' \\\\\\\\ ');\n}\n\n/** Title metadata + titling hooks for the XeLaTeX preamble (before \\\\begin{document}). */\nfunction articleMaketitlePreamble(meta: Document2Meta, twocolumn = false): string {\n if (!document2HasMaketitle(meta)) {\n return '';\n }\n const parts: string[] = [butexBasmalaTitlingPreamble({ twocolumn })];\n if (meta.title.trim().length > 0) {\n parts.push(`\\\\title{${meta.title.trim()}}`);\n }\n if (meta.authors.trim().length > 0) {\n parts.push(`\\\\author{${authorLatex(meta.authors)}}`);\n }\n parts.push(`\\\\date{${formatHijriDate(meta.date, { locale: 'ar', digitForm: 'western' })}}`);\n return parts.join('\\n');\n}\n\nfunction articleFrontMatterLatex(meta: Document2Meta): string[] {\n const parts: string[] = [];\n if (document2HasMaketitle(meta)) {\n parts.push('\\\\maketitle');\n } else {\n parts.push(butexBasmalaDisplayLatex());\n }\n if (document2HasAbstract(meta)) {\n parts.push(`\\\\begin{abstract}\\n${meta.abstract.trim()}\\n\\\\end{abstract}`);\n }\n return parts;\n}\n\nexport function document2Latex(\n document: Document2Node,\n options: Document2LatexOptions = {},\n): string {\n const meta = document.meta ?? emptyDocument2Meta();\n const twocolumn = options.twocolumn === true;\n const front = articleFrontMatterLatex(meta);\n const bodyBlocks = document.blocks.map((block) => blockLatex(block, document.references));\n const closing = butexMaghribiDisplayLatex(BUTEX_CLOSING_HAMDALA);\n const body = [...front, ...bodyBlocks, closing].filter((part) => part.length > 0).join('\\n\\n');\n const wrapDocument = options.wrapDocument !== false;\n if (!wrapDocument) {\n // Body-only: include title metadata so callers still see \\\\title / titling when present.\n const metaPreamble = articleMaketitlePreamble(meta, twocolumn);\n return metaPreamble.length > 0 ? `${metaPreamble}\\n\\n${body}` : body;\n }\n const preamble =\n getArabicXeLatexPreamble({\n digitsMapping: options.digitsMapping ?? digitsMappingFromDigitForm(options.digitForm),\n twocolumn,\n }) +\n '\\n' +\n articleMaketitlePreamble(meta, twocolumn);\n return `${preamble}\\n\\\\begin{document}\\n\\n${body}\\n\\n\\\\end{document}\\n`;\n}\n","import type { Document2Node } from './types.js';\nimport { cloneDocument2Node } from './commands.js';\n\nexport const DEFAULT_DOCUMENT2_HISTORY_MAX_DEPTH = 100;\n\nexport type Document2HistoryStacks = {\n past: Document2Node[];\n future: Document2Node[];\n maxDepth: number;\n};\n\nexport function createDocument2History(maxDepth: number = DEFAULT_DOCUMENT2_HISTORY_MAX_DEPTH): Document2HistoryStacks {\n return { past: [], future: [], maxDepth };\n}\n\nexport function pushDocument2Snapshot(stacks: Document2HistoryStacks, documentBeforeEdit: Document2Node): void {\n stacks.past.push(cloneDocument2Node(documentBeforeEdit));\n if (stacks.past.length > stacks.maxDepth) {\n stacks.past.splice(0, stacks.past.length - stacks.maxDepth);\n }\n stacks.future = [];\n}\n\nexport function restoreDocument2Undo(stacks: Document2HistoryStacks, documentNow: Document2Node): Document2Node | null {\n if (stacks.past.length === 0) {\n return null;\n }\n stacks.future.push(cloneDocument2Node(documentNow));\n return stacks.past.pop() ?? null;\n}\n\nexport function restoreDocument2Redo(stacks: Document2HistoryStacks, documentNow: Document2Node): Document2Node | null {\n if (stacks.future.length === 0) {\n return null;\n }\n stacks.past.push(cloneDocument2Node(documentNow));\n return stacks.future.pop() ?? null;\n}\n\nexport function document2HistoryCanUndo(stacks: Document2HistoryStacks): boolean {\n return stacks.past.length > 0;\n}\n\nexport function document2HistoryCanRedo(stacks: Document2HistoryStacks): boolean {\n return stacks.future.length > 0;\n}\n","export type BlockSelectionRange = { from: number; to: number };\n\nexport type BlockSelectionState = {\n selection: BlockSelectionRange | null;\n anchor: number | null;\n};\n\nexport function emptyBlockSelection(): BlockSelectionState {\n return { selection: null, anchor: null };\n}\n\nexport function normalizeBlockSelection(\n selection: BlockSelectionRange | null,\n blockCount: number,\n): BlockSelectionRange | null {\n if (!selection) {\n return null;\n }\n const { from, to } = selection;\n if (\n blockCount <= 0 ||\n from < 0 ||\n to < 0 ||\n from >= blockCount ||\n to >= blockCount ||\n from > to\n ) {\n return null;\n }\n return { from, to };\n}\n\nfunction inRange(selection: BlockSelectionRange, index: number): boolean {\n return index >= selection.from && index <= selection.to;\n}\n\n/** Checkbox click without Shift */\nexport function toggleBlockInSelection(\n state: BlockSelectionState,\n index: number,\n blockCount: number,\n): BlockSelectionState {\n if (index < 0 || index >= blockCount) {\n return state;\n }\n\n const selection = normalizeBlockSelection(state.selection, blockCount);\n if (!selection) {\n return { selection: { from: index, to: index }, anchor: index };\n }\n\n if (inRange(selection, index)) {\n if (selection.from === selection.to) {\n return emptyBlockSelection();\n }\n if (index === selection.from) {\n return { selection: { from: selection.from + 1, to: selection.to }, anchor: state.anchor };\n }\n if (index === selection.to) {\n return { selection: { from: selection.from, to: selection.to - 1 }, anchor: state.anchor };\n }\n return emptyBlockSelection();\n }\n\n if (index === selection.from - 1) {\n return { selection: { from: index, to: selection.to }, anchor: state.anchor ?? index };\n }\n if (index === selection.to + 1) {\n return { selection: { from: selection.from, to: index }, anchor: state.anchor ?? index };\n }\n\n return { selection: { from: index, to: index }, anchor: index };\n}\n\n/** Shift+click on checkbox or header label */\nexport function extendBlockSelectionFromAnchor(\n state: BlockSelectionState,\n index: number,\n blockCount: number,\n): BlockSelectionState {\n if (index < 0 || index >= blockCount) {\n return state;\n }\n\n const anchor = state.anchor ?? index;\n const from = Math.min(anchor, index);\n const to = Math.max(anchor, index);\n return {\n selection: { from, to },\n anchor: state.anchor ?? index,\n };\n}\n\nexport function remapSelectionAfterRangeMove(\n selection: BlockSelectionRange,\n direction: -1 | 1,\n): BlockSelectionRange {\n return { from: selection.from + direction, to: selection.to + direction };\n}\n","import { formatBibliographyNumber, formatCiteLabel } from './citations.js';\nimport {\n BUTEX_BASMALA,\n BUTEX_CLOSING_HAMDALA,\n butexBasmalaDisplayTex,\n butexMaghribiDisplayTex,\n document2HasAbstract,\n document2HasMaketitle,\n emptyDocument2Meta,\n formatHijriDate,\n} from './articleMeta.js';\nimport { formatFloatCaptionTitle, formatRefLabel, labelNumberMap } from './labels.js';\nimport { mathTokenSourceForSide } from './mathBridge.js';\nimport type { DigitFormId } from '../editor/types.js';\nimport type { EditorSide } from '../editor/index.js';\nimport type { ButexUiLocale } from '../uiLocale.js';\nimport type {\n Document2Block,\n Document2Direction,\n Document2MathOutput,\n Document2Node,\n Document2Preview,\n InlineField2,\n MathIsland2,\n PreviewBlock2,\n PreviewInline2,\n TextBlock2,\n} from './types.js';\n\nexport type Document2PreviewOptions = {\n documentDirection?: Document2Direction;\n digitForm?: DigitFormId;\n uiLocale?: ButexUiLocale;\n};\n\nfunction mathTex(\n token: Extract<InlineField2['tokens'][number], { kind: 'math' }>,\n equationSide: EditorSide,\n digitForm: DigitFormId | undefined,\n): string {\n return mathTokenSourceForSide(token, equationSide, digitForm);\n}\n\nfunction previewInlines(\n field: InlineField2,\n islands: MathIsland2[],\n output: Document2MathOutput,\n equationSide: EditorSide,\n document: Document2Node,\n previewOptions: Document2PreviewOptions,\n): PreviewInline2[] {\n return field.tokens.map((token) => {\n if (token.kind === 'text') {\n return { kind: 'text', text: token.text, ...(token.style ? { style: token.style } : {}) };\n }\n if (token.kind === 'cite') {\n return {\n kind: 'cite',\n id: token.id,\n keys: [...token.keys],\n label: formatCiteLabel(token.keys, document.references, {\n documentDirection: previewOptions.documentDirection,\n digitForm: previewOptions.digitForm,\n }),\n };\n }\n if (token.kind === 'ref') {\n return {\n kind: 'ref',\n id: token.id,\n keys: [...token.keys],\n refCommand: token.refCommand,\n label: formatRefLabel(token.keys, document, token.refCommand, {\n documentDirection: previewOptions.documentDirection,\n digitForm: previewOptions.digitForm,\n }),\n };\n }\n const island = {\n id: token.id,\n tex: mathTex(token, equationSide, previewOptions.digitForm),\n display: token.display,\n output,\n editable: token.editable,\n };\n islands.push(island);\n return { kind: 'math', ...island };\n });\n}\n\nfunction textBlockPreview(\n block: TextBlock2,\n islands: MathIsland2[],\n output: Document2MathOutput,\n equationSide: EditorSide,\n document: Document2Node,\n previewOptions: Document2PreviewOptions,\n): PreviewBlock2 {\n const inlines = previewInlines(block.field, islands, output, equationSide, document, previewOptions);\n if (block.command === '\\\\section') {\n return { kind: 'heading', id: block.id, level: 1, inlines };\n }\n if (block.command === '\\\\subsection') {\n return { kind: 'heading', id: block.id, level: 2, inlines };\n }\n if (block.command === '\\\\subsubsection') {\n return { kind: 'heading', id: block.id, level: 3, inlines };\n }\n return {\n kind: 'paragraph',\n id: block.id,\n inlines,\n ...(block.centered ? { centered: true } : {}),\n };\n}\n\nfunction floatNumberLabel(\n document: Document2Node,\n key: string | undefined,\n previewOptions: Document2PreviewOptions,\n): string | undefined {\n if (!key || key.trim().length === 0) {\n return undefined;\n }\n const hit = labelNumberMap(document).get(key.trim());\n if (!hit || (hit.kind !== 'fig' && hit.kind !== 'tab')) {\n return undefined;\n }\n return formatFloatCaptionTitle(hit.kind, hit.number, {\n uiLocale: previewOptions.uiLocale ?? 'ar',\n documentDirection: previewOptions.documentDirection,\n digitForm: previewOptions.digitForm,\n });\n}\n\nfunction blockPreview(\n block: Document2Block,\n islands: MathIsland2[],\n output: Document2MathOutput,\n equationSide: EditorSide,\n document: Document2Node,\n previewOptions: Document2PreviewOptions,\n): PreviewBlock2 {\n if (block.kind === 'textBlock') {\n return textBlockPreview(block, islands, output, equationSide, document, previewOptions);\n }\n if (block.kind === 'list') {\n return {\n kind: 'list',\n id: block.id,\n ordered: block.command === '\\\\begin{enumerate}',\n items: block.items.map((item) => ({\n id: item.id,\n inlines: previewInlines(item.field, islands, output, equationSide, document, previewOptions),\n blocks: item.blocks.map((child) => blockPreview(child, islands, output, equationSide, document, previewOptions)),\n })),\n };\n }\n if (block.kind === 'table') {\n const label = block.labelEnabled ? block.label.trim() : '';\n return {\n kind: 'table',\n id: block.id,\n rows: block.rows.map((row) => row.map((cell) => previewInlines(cell, islands, output, equationSide, document, previewOptions))),\n ...(block.captionEnabled && block.caption.trim().length > 0 ? { caption: block.caption.trim() } : {}),\n ...(label.length > 0 ? { label, numberLabel: floatNumberLabel(document, label, previewOptions) } : {}),\n };\n }\n if (block.kind === 'image') {\n const label = block.labelEnabled ? block.label.trim() : '';\n return {\n kind: 'image',\n id: block.id,\n src: block.value,\n ...(block.assetId !== undefined ? { assetId: block.assetId } : {}),\n options: block.options,\n ...(block.captionEnabled && block.caption.trim().length > 0 ? { caption: block.caption.trim() } : {}),\n ...(label.length > 0 ? { label, numberLabel: floatNumberLabel(document, label, previewOptions) } : {}),\n };\n }\n if (block.kind === 'bibliography') {\n return {\n kind: 'bibliography',\n id: block.id,\n items: document.references.map((reference, index) => ({\n id: reference.id,\n numberLabel: formatBibliographyNumber(index + 1, {\n documentDirection: previewOptions.documentDirection,\n digitForm: previewOptions.digitForm,\n }),\n key: reference.key,\n authors: reference.authors,\n title: reference.title,\n year: reference.year,\n url: reference.url,\n venue: reference.venue,\n fieldSeparator: reference.fieldSeparator,\n })),\n };\n }\n return { kind: 'omit', id: block.id };\n}\n\nfunction articleChromePreview(\n document: Document2Node,\n uiLocale: ButexUiLocale,\n previewOptions: Document2PreviewOptions,\n): PreviewBlock2[] {\n const meta = document.meta ?? emptyDocument2Meta();\n const blocks: PreviewBlock2[] = [\n { kind: 'basmala', id: 'article-basmala', text: BUTEX_BASMALA, tex: butexBasmalaDisplayTex() },\n ];\n if (document2HasMaketitle(meta)) {\n blocks.push({\n kind: 'titleBlock',\n id: 'article-title',\n ...(meta.title.trim().length > 0 ? { title: meta.title.trim() } : {}),\n ...(meta.authors.trim().length > 0 ? { authors: meta.authors.trim() } : {}),\n date: formatHijriDate(meta.date, {\n locale: uiLocale,\n digitForm: previewOptions.digitForm,\n }),\n });\n }\n if (document2HasAbstract(meta)) {\n blocks.push({ kind: 'abstract', id: 'article-abstract', text: meta.abstract.trim() });\n }\n return blocks;\n}\n\nexport function document2Preview(\n document: Document2Node,\n output: Document2MathOutput = 'svg',\n equationSide: EditorSide = 'arabic',\n previewOptions: Document2PreviewOptions = {},\n): Document2Preview {\n const mathIslands: MathIsland2[] = [];\n const options: Document2PreviewOptions = {\n documentDirection: previewOptions.documentDirection ?? 'rtl',\n digitForm:\n previewOptions.digitForm ??\n (previewOptions.documentDirection === 'ltr' ? 'western' : 'arabicIndic'),\n uiLocale: previewOptions.uiLocale ?? 'ar',\n };\n const body = document.blocks.map((block) => blockPreview(block, mathIslands, output, equationSide, document, options));\n return {\n blocks: [\n ...articleChromePreview(document, options.uiLocale ?? 'ar', options),\n ...body,\n { kind: 'closing', id: 'article-closing', text: BUTEX_CLOSING_HAMDALA, tex: butexMaghribiDisplayTex(BUTEX_CLOSING_HAMDALA) },\n ],\n mathIslands,\n };\n}\n"],"mappings":"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","names":["value","node","parseChain","document","isObject","nextId","scripts","document","afterBlockId","block","textStylesEqual","reference","document","isObject","requireString","afterBlockId","parseCommand","document","block","document","document"]}