@medyat/vue-data-table 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/sheet.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"sheet.js","names":["fold","_hoisted_1","_hoisted_2","_hoisted_3","_openBlock","_createElementBlock","_createElementVNode","_toDisplayString","_createCommentVNode","_sfc_main","_openBlock","_createBlock","_unref","_withCtx","_createVNode","_createElementBlock","_Fragment","_renderList","_createElementVNode","_createTextVNode","_toDisplayString","_sfc_main","_hoisted_1","_hoisted_2","_openBlock","_createElementBlock","_sfc_main","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_openBlock","_createElementBlock","_createElementVNode","_createVNode","_unref","_withCtx","_toDisplayString","_createCommentVNode","_Fragment","_renderList","_createBlock","_createTextVNode","_sfc_main","_openBlock","_createBlock","_unref","_withCtx","_createVNode","_createElementBlock","_Fragment","_renderList","_createElementVNode","_sfc_main","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","_hoisted_13","_hoisted_14","_hoisted_15","_hoisted_16","_hoisted_17","_hoisted_18","_hoisted_19","_hoisted_20","_hoisted_21","_hoisted_22","_hoisted_23","_hoisted_24","_hoisted_25","_hoisted_26","_hoisted_27","_hoisted_28","_hoisted_29","_hoisted_30","_hoisted_31","_hoisted_32","_hoisted_33","_hoisted_34","_hoisted_35","_hoisted_36","_hoisted_37","_hoisted_38","_hoisted_39","_hoisted_40","_hoisted_41","_hoisted_42","_useModel","_openBlock","_createBlock","_unref","_withCtx","_createVNode","_createElementVNode","_createTextVNode","_toDisplayString","_createElementBlock","_normalizeClass","_withModifiers","_Fragment","_withDirectives","_renderList","_vModelSelect","_createCommentVNode","_vModelCheckbox","_sfc_main","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_useModel","_openBlock","_createBlock","_unref","_withCtx","_createVNode","_createTextVNode","_toDisplayString","_createElementVNode","_createElementBlock","_Fragment","_renderList","_sfc_main","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_openBlock","_createBlock","_unref","_withCtx","_createVNode","_createTextVNode","_toDisplayString","_createElementVNode","_createElementBlock","_Fragment","_createCommentVNode","_sfc_main","$slots","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","_hoisted_13","_hoisted_14","_hoisted_15","_openBlock","_createBlock","_unref","_withCtx","_createVNode","_createElementVNode","_normalizeClass","_createElementBlock","_toDisplayString","_createCommentVNode","_Fragment","_renderList","_normalizeStyle","SkeletonRow","SheetRow","_renderSlot","SheetMenu","_sfc_main","TextCell","NumberCell","OptionCell","MultiCell","DateCell","_openBlock","_createElementBlock","_normalizeClass","_unref","_createVNode","_createElementVNode","_toDisplayString","_createTextVNode","_createCommentVNode","_normalizeStyle","SearchBox","_Fragment","_withCtx","_renderList","DisplayPopover","_mergeProps","_toHandlers","_createBlock","SheetGrid","_createSlots","_renderSlot","StateMessage","_withDirectives","_vShow","ConfirmDialog","ImportDialog","SaveErrorsDialog","_sfc_main","getFormat","badge","INTERACTIVE_SELECTOR","isTextInput","TYPE_SPECS","renderCellContent","typeLabelKey","alignOf","optionLabel","parseNumber","mac","useColumnLayout","cellFillStyle","readPath","formatCell","RemoteLabels","isEmptyValue","DisplayPopover_default","SAVE_KBD","StateMessage_default","SkeletonRow_default","toDate","FIND_KBD","FILL_KBD","SearchBox_default","isoDay","usePreferences","comparator","withFill","isNumericType","ConfirmDialog_default","ME","useDelegatedTooltip","REDO_KBD","isInteractive","UNDO_KBD","REMOVE_KBD","useDataTableContext","tsvCell","s","toTsv","matrix","r","escapeHtml","toHtml","c","parseTsv","rows","row","cell","quoted","i","text","ch","parseHtmlTable","html","tr","td","matrixFromClipboard","data","matchOption","o","options","fold$1","opt","locale","splitList","p","inferDecimal","raw","texts","comma","dot","validDay","dt","y","m","d","parseDateInput","low","env","rel","iso","dmy","parseInput","def","part","v","inputText","value","useParseEnv","i18n","focusEnd","el","n","_hoisted_1$7","_hoisted_2$7","_hoisted_3$6","NumberCell_default","defineComponent","__emit","props","__props","emit","ref","suffix","computed","onInput","openBlock","createElementBlock","createElementVNode","toDisplayString","createCommentVNode","OptionCell_default","open","listId","nextTick","input","inputEl","onText","onSelect","onKeydown","Item","createBlock","unref","ComboboxRoot","_cache","$event","withCtx","createVNode","ComboboxAnchor","ComboboxInput","ComboboxPortal","ComboboxContent","ComboboxViewport","Fragment","renderList","ComboboxItem","ComboboxEmpty","createTextVNode","_hoisted_1$6","_hoisted_2$6","TextCell_default","_hoisted_1$5","_hoisted_2$5","_hoisted_3$5","_hoisted_4$5","DateCell_default","fmt","dayFmt","tz","getLocalTimeZone","now","today","weekStartsOn","getDayOfWeek","startOfWeek","safe","parseDate","single","resolved","onPick","refocus","PopoverRoot","PopoverTrigger","PhCalendarBlank","PopoverPortal","PopoverContent","CalendarRoot","CalendarHeader","CalendarPrev","PhCaretLeft","CalendarHeading","CalendarNext","PhCaretRight","grid","CalendarGrid","month","CalendarGridHead","CalendarGridRow","weekDays","CalendarHeadCell","day","CalendarGridBody","week","CalendarCell","CalendarCellTrigger","SHEET_EDITOR_KEY","useSheetEditor","inject","MultiCell_default","lower","t","sheet","values","suggestions","search","shown","q","wantOpen","reveal","ComboboxItemIndicator","PhCheck","fillValues","source","count","nums","step","base","up","dir","round","cellText","TR","normalizeHeader","isNumberLike","detectHeaderRow","best","bestScore","cells","first","matchColumns","out","names","columns","headers","h","hits","j","_hoisted_1$4","_hoisted_2$4","_hoisted_3$4","_hoisted_4$4","_hoisted_5$4","_hoisted_6$4","_hoisted_7$3","_hoisted_8$2","_hoisted_9$2","_hoisted_10$2","_hoisted_11$2","_hoisted_12$2","_hoisted_13$2","_hoisted_14$2","_hoisted_15$2","_hoisted_16$1","_hoisted_17$1","_hoisted_18$1","_hoisted_19$1","_hoisted_20$1","_hoisted_21$1","_hoisted_22$1","_hoisted_23$1","_hoisted_24$1","_hoisted_25$1","_hoisted_26$1","_hoisted_27$1","_hoisted_28$1","_hoisted_29$1","_hoisted_30$1","_hoisted_31$1","_hoisted_32$1","_hoisted_33$1","_hoisted_34$1","_hoisted_35$1","_hoisted_36$1","_hoisted_37$1","_hoisted_38$1","_hoisted_39$1","_hoisted_40$1","_hoisted_41$1","_hoisted_42$1","SKIP","ImportDialog_default","\"open\"","\"openModifiers\"","useModel","keyDef","keyHeader","fields","file","shallowRef","workbook","loading","failed","failReason","sheetIndex","headerRow","mapping","keyCol","addNew","showNew","dragging","dataRows","headerOptions","rebuild","auto","key","id","f","load","wb","onHeaderRow","onDrop","reset","keyTexts","lookup","ctl","unknown","keys","k","map","chunk","res","summary","seen","inList","server","news","overLimit","canApply","localeFor","dec","col","convert","preview","apply","sheetInfo","DialogRoot","DialogPortal","DialogOverlay","DialogContent","DialogTitle","DialogDescription","DialogClose","PhX","PhTable","withDirectives","vModelSelect","PhLock","PhArrowLeft","normalizeClass","PhWarningCircle","PhArrowRight","PhInfo","vModelCheckbox","withModifiers","PhUploadSimple","_hoisted_1$3","_hoisted_2$3","_hoisted_3$3","_hoisted_4$3","_hoisted_5$3","_hoisted_6$3","SaveErrorsDialog_default","save","AlertDialogRoot","AlertDialogPortal","AlertDialogOverlay","AlertDialogContent","AlertDialogTitle","AlertDialogDescription","AlertDialogCancel","_hoisted_1$2","_hoisted_2$2","_hoisted_3$2","_hoisted_4$2","_hoisted_5$2","_hoisted_6$2","_hoisted_7$2","SheetMenu_default","K","ContextMenuPortal","ContextMenuContent","ContextMenuItem","ContextMenuSeparator","plainDefs","plain","SheetRow_default","params","renderCell","editable","issue","changed","isActive","sel","inSel","fill","inFill","ed","isKey","content","Editor","children","PhCircleNotch","tipId","gutter","hasError","PhPlus","index","_hoisted_1$1","_hoisted_2$1","_hoisted_3$1","\"left\"","_hoisted_4$1","_hoisted_5$1","_hoisted_6$1","_hoisted_7$1","_hoisted_8$1","_hoisted_9$1","_hoisted_10$1","_hoisted_11$1","_hoisted_12$1","_hoisted_13$1","_hoisted_14$1","_hoisted_15$1","GUTTER_FULL","EDGE","SCROLL_STEP","SheetGrid_default","__expose","ctx","uid","useId","root","scrollEl","layout","table","store","keyOf","coarse","density","GUTTER_W","g","startVars","name","rowHeight","headH","barH","readBarH","readRowHeight","onMounted","watch","labels","defById","indexByKey","active","activeIndex","multi","b","selectionFor","handleFor","fillDrag","editingFor","e","foundFor","virtualizer","useVirtualizer","start","range","end","a","virtualRows","totalSize","scrolledStart","onScroll","cellEl","columnId","pinnedWidth","w","revealX","sc","left","revealEnd","focusActive","focusNow","tryFocus","attempt","focusCell","cols","ci","ri","jump","pageSize","DIR","target","mod","widget","openMenuAt","clipboard","action","hitAt","rowEl","hit","fillLabel","pointer","scrollRaf","extendTo","updateFillLabel","autoScroll","dy","dx","onMousemove","last","rootRect","onDocMouseup","onBeforeUnmount","rowAnchor","onMousedown","hr","from","onMouseover","onDblclick","fillFor","down","onContextmenuCapture","menuHref","sortOf","unitOf","headTip","resize","requiredLabel","ContextMenuRoot","ContextMenuTrigger","normalizeStyle","PhArrowUp","item","_ctx","renderSlot","useSheetEditing","editing","opts","inCell","HISTORY","same","x","setPath","path","obj","next","fold","closest","dist","prev","tmp","useSheetStore","defs","toValue","draft","shallowReactive","issues","serverErrors","rowErrors","added","removed","keyStates","version","undoStack","redoStack","canUndo","canRedo","newCounter","batch","batchIndex","allRows","byKey","addedByKey","isNew","rowNoOf","original","readFrom","read","readUntracked","toRaw","current","keyIndex","set","typeIssue","error","bad","optionIssue","optionEnabled","duplicateIssue","others","other","validateRow","isNewRow","cur","required","err","warn","revalidateKeys","write","patches","touched","keyValues","changes","before","entry","se","syncHistory","record","addedRows","addRows","dropAdded","drop","removeRows","restoreRows","replay","undo","redo","clearHistory","rowDraft","rowIssues","client","merged","message","rowError","keyState","setKeyState","state","setBase","counts","changedCells","changedKeys","errorRows","warningRows","errorKeys","newRows","changedOrNewRows","byId","create","created","updated","errors","results","fe","features","tableFeatures","useSheetTable","useTable","ranges","bounds","rangeEnd","rowId","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","_hoisted_13","_hoisted_14","_hoisted_15","_hoisted_16","_hoisted_17","_hoisted_18","_hoisted_19","_hoisted_20","_hoisted_21","_hoisted_22","_hoisted_23","_hoisted_24","_hoisted_25","_hoisted_26","_hoisted_27","_hoisted_28","_hoisted_29","_hoisted_30","_hoisted_31","_hoisted_32","_hoisted_33","_hoisted_34","_hoisted_35","_hoisted_36","_hoisted_37","_hoisted_38","_hoisted_39","_hoisted_40","_hoisted_41","_hoisted_42","_hoisted_43","_hoisted_44","_hoisted_45","_hoisted_46","DataSheet_default","entity","pref","loadedRows","loadingNow","savingNow","progress","percent","readOnlyDevice","sheetColumns","primaryDef","sortRules","order","view","viewKeys","matchesView","refreshView","union","setView","orderedBatch","rowsAll","all","visibleCols","readOnlyNow","EDITORS","editorFor","canEdit","parseEnv","edit","useTemplateRef","fmtEnv","selectCells","r1","r2","c1","c2","selectedCells","toggle","clearSelected","errorKeysInOrder","goToError","showToast","copyText","copyMatrix","line","copy","cut","copyToClipboard","clip","tsv","cutAfter","pasteMatrix","width","l","startRow","startCol","targets","lastRow","overflow","localeByCol","minR","minC","maxC","dims","paste","pasteFromClipboard","fillPlan","fromRow","toRow","fillDown","afterStep","idx","useSuggestion","addRow","defaults","at","pos","insertRow","where","removeSelectedRows","sort","existing","rest","additive","cmps","cmp","sign","sortMap","looked","pending","lookupTimer","lookupCtl","runLookup","batchKeys","rowKey","result","found","errorDialogOpen","errorItems","saveTotals","savedSummary","partly","emitSave","fixFirst","finishSave","resultVersion","applyResult","partlyIndex","copyErrors","lines","keyText","rowErr","openHref","importOpen","keyIndexSet","applyImport","byKeyValue","bases","payload","firstKey","firstRow","exportRows","scope","exportLabel","copyLink","onDocPointerdown","isDirty","onBeforeUnload","toastTimer","findBox","onRootKeydown","findText","findIndex","matches","list","goToMatch","findStep","onFindKeydown","findCount","viewCounts","activeRow","activeDef","rangeDims","rangeText","nameKey","formulaText","formulaEditable","onFormulaInput","onFormulaKeydown","hint","parts","valueAria","sum","numeric","status","changesText","saveTip","undoTip","redoTip","canSave","toast","toastUndo","toastAction","run","polite","assertive","announcedQuarter","discardOpen","discard","displayProps","displayOn","on","visible","delta","rootEl","tooltip","PhMonitor","PhLink","ToggleGroupRoot","ToggleGroupItem","PhArrowUUpLeft","PhArrowUUpRight","PhDownloadSimple","DropdownMenuRoot","DropdownMenuTrigger","PhExport","DropdownMenuPortal","DropdownMenuContent","DropdownMenuSub","DropdownMenuSubTrigger","DropdownMenuSubContent","DropdownMenuItem","mergeProps","toHandlers","PhCaretUp","PhCaretDown","PhCopy","PhWarning","createSlots","vShow"],"sources":["../src/sheet/clipboard.ts","../src/sheet/parse.ts","../src/sheet/editors/useParseEnv.ts","../src/sheet/editors/NumberCell.vue","../src/sheet/editors/NumberCell.vue","../src/sheet/editors/OptionCell.vue","../src/sheet/editors/OptionCell.vue","../src/sheet/editors/TextCell.vue","../src/sheet/editors/TextCell.vue","../src/sheet/editors/DateCell.vue","../src/sheet/editors/DateCell.vue","../src/sheet/editors/context.ts","../src/sheet/editors/MultiCell.vue","../src/sheet/editors/MultiCell.vue","../src/sheet/fill.ts","../src/sheet/import/model.ts","../src/sheet/ImportDialog.vue","../src/sheet/ImportDialog.vue","../src/sheet/SaveErrorsDialog.vue","../src/sheet/SaveErrorsDialog.vue","../src/sheet/SheetMenu.vue","../src/sheet/SheetMenu.vue","../src/sheet/SheetRow.ts","../src/sheet/SheetGrid.vue","../src/sheet/SheetGrid.vue","../src/sheet/useSheetEditing.ts","../src/sheet/useSheetStore.ts","../src/sheet/useSheetTable.ts","../src/sheet/DataSheet.vue","../src/sheet/DataSheet.vue"],"sourcesContent":["// Pano biçimleri (07 §7): kopyada TSV (`text/plain`) + `<table>` (`text/html`), görüntülenen biçimde; yapıştırmada TSV\n// çözümleme (Excel'in tırnaklı, içinde sekme/satır sonu olan hücreleri dahil), `text/html` yalnızca TSV yoksa.\n\n/** Excel kuralı: sekme/satır sonu/tırnak içeren hücre çift tırnağa alınır, içteki tırnak ikilenir. */\nconst tsvCell = (s: string): string => (/[\\t\\n\\r\"]/.test(s) ? `\"${s.replace(/\"/g, '\"\"')}\"` : s)\nexport const toTsv = (matrix: string[][]): string => matrix.map((r) => r.map(tsvCell).join('\\t')).join('\\n')\n\nconst escapeHtml = (s: string): string =>\n s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\\n/g, '<br>')\nexport const toHtml = (matrix: string[][]): string =>\n `<table><tbody>${matrix.map((r) => `<tr>${r.map((c) => `<td>${escapeHtml(c)}</td>`).join('')}</tr>`).join('')}</tbody></table>`\n\n/** TSV → matris; sondaki tek boş satır (Excel'in eklediği) atılır. */\nexport function parseTsv(text: string): string[][] {\n const rows: string[][] = []\n let row: string[] = []\n let cell = ''\n let quoted = false\n for (let i = 0; i < text.length; i++) {\n const ch = text[i]!\n if (quoted) {\n if (ch === '\"') {\n if (text[i + 1] === '\"') {\n cell += '\"'\n i++\n } else quoted = false\n } else cell += ch\n continue\n }\n if (ch === '\"' && cell === '') quoted = true\n else if (ch === '\\t') {\n row.push(cell)\n cell = ''\n } else if (ch === '\\n' || ch === '\\r') {\n if (ch === '\\r' && text[i + 1] === '\\n') i++\n row.push(cell)\n rows.push(row)\n row = []\n cell = ''\n } else cell += ch\n }\n if (cell !== '' || row.length) {\n row.push(cell)\n rows.push(row)\n }\n if (rows.length > 1 && rows[rows.length - 1]!.every((c) => c === '')) rows.pop()\n return rows\n}\n\n/** `<table>` → matris (yalnızca TSV yokken). */\nexport function parseHtmlTable(html: string): string[][] {\n if (typeof DOMParser === 'undefined') return []\n const doc = new DOMParser().parseFromString(html, 'text/html')\n return [...doc.querySelectorAll('tr')].map((tr) =>\n [...tr.querySelectorAll('td, th')].map((td) => (td.textContent ?? '').replace(/\\u00a0/g, ' ').trim()),\n )\n}\n\n/** Pano olayından matris: TSV öncelikli, sonra HTML tablosu, sonra düz metin tek hücre. */\nexport function matrixFromClipboard(data: DataTransfer | null): string[][] {\n const text = data?.getData('text/plain') ?? ''\n if (text) return parseTsv(text)\n const html = data?.getData('text/html') ?? ''\n return html ? parseHtmlTable(html) : []\n}\n","// Hücre girişlerinin çözümlenmesi (07 §5, §7): sayı yerel ayara göre (\"2240\", \"2.240,00\", \"2,240.00\"; \"%20\" → 20),\n// tarih \"24.10\", \"24.10.2026\", \"+7d\", \"today\"/\"bugün\", ISO; seçenek etiketle (büyük/küçük harf ve İ/ı duyarsız).\n// Çözülemeyen giriş ham metin olarak kalır; doğrulama onu tip hatası sayar (useSheetStore).\nimport { optionLabel } from '../core/cells/format'\nimport { TYPE_SPECS } from '../core/cells/specs'\nimport { isoDay } from '../core/filters/model'\nimport { parseNumber } from '../core/format/parse'\nimport type { ColumnDef, OptionDef } from '../types/columns'\n\nexport interface ParseEnv {\n locale: string\n today: Date\n /** i18n `date.today` (\"Today\" / \"Bugün\"); \"today\" her dilde kabul edilir. */\n todayWord: string\n /** i18n `common.yes` / `common.no` (boolean yapıştırma); true/false/1/0/yes/no her dilde. */\n yesWord: string\n noWord: string\n}\n\n/** Seçenek etiketle (büyük/küçük harf, İ/ı ve boşluk duyarsız) ya da değerle; eşleşmeyen ham metin (hata). */\nconst matchOption = (options: OptionDef[], text: string, locale: string): unknown => {\n const o = options.find((opt) => fold(opt.label, locale) === fold(text, locale) || String(opt.value) === text.trim())\n return o ? o.value : text.trim()\n}\n/** `;` veya `,` ayrılmış liste (07 §5). */\nconst splitList = (s: string): string[] =>\n s\n .split(/[;,]/)\n .map((p) => p.trim())\n .filter(Boolean)\n\n/** Yapıştırılan bir sütunun ondalık ayırıcısı (07 §7): `1.234,56` / `12,5` → virgül; `1,234.56` / `12.5` → nokta; belirsizse null. */\nexport function inferDecimal(texts: string[]): ',' | '.' | null {\n for (const raw of texts) {\n const s = raw.replace(/[\\s%\\u00a0A-Za-z₺€$£]/g, '')\n const comma = s.lastIndexOf(',')\n const dot = s.lastIndexOf('.')\n if (comma >= 0 && dot >= 0) return comma > dot ? ',' : '.'\n if (comma >= 0 && /,\\d{1,2}$/.test(s) && !/^\\d{1,3}(,\\d{3})+$/.test(s)) return ','\n if (dot >= 0 && /\\.\\d{1,2}$/.test(s) && !/^\\d{1,3}(\\.\\d{3})+$/.test(s)) return '.'\n }\n return null\n}\n\nconst fold = (s: string, locale: string): string => s.trim().toLocaleLowerCase(locale).replace(/ı|i̇/g, 'i')\n\nconst validDay = (y: number, m: number, d: number): string | null => {\n const dt = new Date(y, m - 1, d)\n return dt.getFullYear() === y && dt.getMonth() === m - 1 && dt.getDate() === d ? isoDay(dt) : null\n}\n\n/** \"24.10\" (bu yıl), \"24.10.2026\", \"24/10/26\", \"+7d\", \"-3d\", \"today\", ISO. Çözülemezse null. */\nexport function parseDateInput(text: string, env: ParseEnv): string | null {\n const s = text.trim()\n if (!s) return null\n const low = fold(s, env.locale)\n if (low === 'today' || low === fold(env.todayWord, env.locale)) return isoDay(env.today)\n const rel = /^([+-])(\\d+)d$/i.exec(s)\n if (rel) {\n const d = new Date(env.today)\n d.setDate(d.getDate() + (rel[1] === '-' ? -1 : 1) * Number(rel[2]))\n return isoDay(d)\n }\n const iso = /^(\\d{4})-(\\d{2})-(\\d{2})/.exec(s)\n if (iso) return validDay(+iso[1]!, +iso[2]!, +iso[3]!)\n const dmy = /^(\\d{1,2})[./](\\d{1,2})(?:[./](\\d{2}|\\d{4}))?$/.exec(s)\n if (dmy) {\n const y = dmy[3] ? (dmy[3].length === 2 ? 2000 + +dmy[3] : +dmy[3]) : env.today.getFullYear()\n return validDay(y, +dmy[2]!, +dmy[1]!)\n }\n return null\n}\n\n/** Editör / formül çubuğu metni → hücre değeri. Boş → null; çözülemeyen → ham metin (tip hatası). */\nexport function parseInput(def: ColumnDef, text: string, env: ParseEnv): unknown {\n const s = text.trim()\n if (s === '') return null\n if (TYPE_SPECS[def.type].numeric || def.type === 'star') {\n // Formül desteklenmez (07 §2): \"=\" ile başlayan giriş sayı sütununda hata olarak kalır.\n if (s.startsWith('=')) return s\n return parseNumber(env.locale, s) ?? s\n }\n switch (def.type) {\n case 'date':\n case 'datetime':\n return parseDateInput(s, env) ?? s\n case 'select':\n return matchOption(def.options, s, env.locale)\n case 'multiselect':\n return splitList(s).map((part) => matchOption(def.options, part, env.locale))\n case 'boolean': {\n const v = fold(s, env.locale)\n if (['true', '1', 'yes', fold(env.yesWord, env.locale)].includes(v)) return true\n if (['false', '0', 'no', fold(env.noWord, env.locale)].includes(v)) return false\n return s\n }\n case 'uppercase':\n return s.toLocaleUpperCase(env.locale)\n case 'lowercase':\n return s.toLocaleLowerCase(env.locale)\n default:\n return s\n }\n}\n\n/** Hücre değeri → editör / formül çubuğunun ham metni. */\nexport function inputText(def: ColumnDef, value: unknown): string {\n if (value === null || value === undefined) return ''\n if (def.type === 'select') return optionLabel(def.options, value)\n if (Array.isArray(value)) return value.join(', ')\n if (typeof value === 'object') return JSON.stringify(value)\n return String(value)\n}\n","// Yerleşik hücre editörlerinin ortak çözümleme bağlamı (parse.ts): yerel ayar, bugün, \"Today\" sözcüğü.\nimport { useDataTableContext } from '../../core/plugin'\nimport type { ParseEnv } from '../parse'\n\nexport function useParseEnv(): () => ParseEnv {\n const { i18n, locale } = useDataTableContext()\n return () => ({\n locale,\n today: new Date(),\n todayWord: i18n.t('date.today'),\n yesWord: i18n.t('common.yes'),\n noWord: i18n.t('common.no'),\n })\n}\n\n/** Odak editöre, imleç sonda (F2 / yazarak açılış, 07 §5). */\nexport function focusEnd(el: HTMLInputElement | HTMLTextAreaElement | null) {\n if (!el) return\n el.focus({ preventScroll: true })\n const n = el.value.length\n el.setSelectionRange(n, n)\n}\n","<script setup lang=\"ts\">\n// Sayı / para / yüzde hücre editörü (07 §5, T11-07): sağa yaslı; \"2240\", \"2.240,00\", \"2,240.00\" yerel ayara göre okunur,\n// \"%20\"/\"20%\" → 20. Sabit para kodu ve \"%\" soluk sağda. Çözülemeyen metin ham kalır (hata, kayıttan önce).\nimport { computed, onMounted, ref } from 'vue'\nimport type { ColumnDef } from '../../types/columns'\nimport { inputText, parseInput } from '../parse'\nimport { focusEnd, useParseEnv } from './useParseEnv'\n\nconst props = defineProps<{ modelValue: unknown; row: object; column: ColumnDef }>()\nconst emit = defineEmits<{ 'update:modelValue': [value: unknown] }>()\nconst env = useParseEnv()\nconst el = ref<HTMLInputElement | null>(null)\nconst text = ref(inputText(props.column, props.modelValue))\nconst suffix = computed(() => {\n const c = props.column\n return c.type === 'currency' && typeof c.currency === 'string' ? c.currency : c.type === 'percentage' ? '%' : ''\n})\nonMounted(() => focusEnd(el.value))\nconst onInput = () => {\n text.value = el.value!.value\n emit('update:modelValue', parseInput(props.column, text.value, env()))\n}\n</script>\n\n<template>\n <span class=\"dt-cell-editor is-number\">\n <input\n ref=\"el\"\n class=\"dt-cell-input is-right\"\n type=\"text\"\n inputmode=\"decimal\"\n :value=\"text\"\n :aria-label=\"column.header\"\n autocomplete=\"off\"\n @input=\"onInput\"\n />\n <span v-if=\"suffix\" class=\"dt-ccy\" aria-hidden=\"true\">{{ suffix }}</span>\n </span>\n</template>\n","<script setup lang=\"ts\">\n// Sayı / para / yüzde hücre editörü (07 §5, T11-07): sağa yaslı; \"2240\", \"2.240,00\", \"2,240.00\" yerel ayara göre okunur,\n// \"%20\"/\"20%\" → 20. Sabit para kodu ve \"%\" soluk sağda. Çözülemeyen metin ham kalır (hata, kayıttan önce).\nimport { computed, onMounted, ref } from 'vue'\nimport type { ColumnDef } from '../../types/columns'\nimport { inputText, parseInput } from '../parse'\nimport { focusEnd, useParseEnv } from './useParseEnv'\n\nconst props = defineProps<{ modelValue: unknown; row: object; column: ColumnDef }>()\nconst emit = defineEmits<{ 'update:modelValue': [value: unknown] }>()\nconst env = useParseEnv()\nconst el = ref<HTMLInputElement | null>(null)\nconst text = ref(inputText(props.column, props.modelValue))\nconst suffix = computed(() => {\n const c = props.column\n return c.type === 'currency' && typeof c.currency === 'string' ? c.currency : c.type === 'percentage' ? '%' : ''\n})\nonMounted(() => focusEnd(el.value))\nconst onInput = () => {\n text.value = el.value!.value\n emit('update:modelValue', parseInput(props.column, text.value, env()))\n}\n</script>\n\n<template>\n <span class=\"dt-cell-editor is-number\">\n <input\n ref=\"el\"\n class=\"dt-cell-input is-right\"\n type=\"text\"\n inputmode=\"decimal\"\n :value=\"text\"\n :aria-label=\"column.header\"\n autocomplete=\"off\"\n @input=\"onInput\"\n />\n <span v-if=\"suffix\" class=\"dt-ccy\" aria-hidden=\"true\">{{ suffix }}</span>\n </span>\n</template>\n","<script setup lang=\"ts\">\n// Seçenek hücre editörü (07 §5, T11-07): reka Combobox; yazmak listeyi süzer, Enter seçer, ilk Esc listeyi kapatır\n// (ikinci Esc düzenlemeyi iptal eder — sheet, `aria-expanded` ve `defaultPrevented` üzerinden anlar). Listede olmayan\n// metin ham kalır → \"“Pump” isn't an option\". Liste portalda: `dt-sheet-layer` dışarı tık sayılmaz. Alt↓ listeyi açar.\nimport {\n ComboboxAnchor,\n ComboboxContent,\n ComboboxEmpty,\n ComboboxInput,\n ComboboxItem,\n ComboboxPortal,\n ComboboxRoot,\n ComboboxViewport,\n} from 'reka-ui'\nimport { computed, nextTick, onMounted, ref, watch } from 'vue'\nimport { optionLabel } from '../../core/cells/format'\nimport { badge } from '../../core/cells/renderCell'\nimport { useDataTableContext } from '../../core/plugin'\nimport type { ColumnDef, OptionDef } from '../../types/columns'\nimport { inputText, parseInput } from '../parse'\nimport { focusEnd, useParseEnv } from './useParseEnv'\n\nconst props = defineProps<{ modelValue: unknown; row: object; column: ColumnDef }>()\nconst emit = defineEmits<{ 'update:modelValue': [value: unknown] }>()\nconst { i18n } = useDataTableContext()\nconst env = useParseEnv()\nconst def = computed(() => props.column as Extract<ColumnDef, { type: 'select' }>)\n// Satıra göre kapalı seçenekler listede yok (`row` taslak satır); etiket çözümü tam listeden.\nconst options = computed(() => {\n const d = def.value\n return d.optionEnabled ? d.options.filter((o) => d.optionEnabled!(o, props.row)) : d.options\n})\nconst open = ref(true)\n// reka listenin id'sini input'a geç yazıyor (aria-controls=\"\"): açılınca DOM'daki gerçek id okunur (axe aria-valid-attr-value).\nconst listId = ref<string | undefined>()\nwatch(\n open,\n (o) => {\n if (!o) return\n void nextTick(() => {\n listId.value = document.querySelector<HTMLElement>('.dt-cell-list[role=\"listbox\"]')?.id || undefined\n })\n },\n { immediate: true },\n)\nconst text = ref(inputText(props.column, props.modelValue))\nconst input = ref<{ $el: HTMLInputElement } | null>(null)\nconst inputEl = () => input.value?.$el ?? null\nonMounted(() => void nextTick(() => focusEnd(inputEl())))\n\nconst onText = (v: string) => {\n text.value = v\n emit('update:modelValue', parseInput(props.column, v, env()))\n}\nconst onSelect = (v: unknown) => {\n if (v === undefined || v === null) return\n emit('update:modelValue', v)\n text.value = optionLabel(def.value.options, v)\n open.value = false\n void nextTick(() => focusEnd(inputEl()))\n}\nconst onKeydown = (e: KeyboardEvent) => {\n if (e.altKey && e.key === 'ArrowDown') {\n e.preventDefault()\n open.value = true\n }\n}\n// Sabit bileşen: her render'da yeni bileşen üretmek rozeti mousedown–mouseup arasında DOM'da değiştirir, click kaybolur.\nconst Item = (p: { o: OptionDef }) => badge(p.o.tone, p.o.label)\n</script>\n\n<template>\n <ComboboxRoot\n v-model:open=\"open\"\n class=\"dt-cell-editor is-option\"\n :model-value=\"(modelValue as string | number | undefined) ?? undefined\"\n :reset-search-term-on-blur=\"false\"\n @update:model-value=\"onSelect\"\n >\n <!-- Liste hücreye göre konumlanır (altında, sağa hizalı): çapa editörün kendisi. -->\n <ComboboxAnchor class=\"dt-cell-anchor\">\n <ComboboxInput\n ref=\"input\"\n class=\"dt-cell-input\"\n autocomplete=\"off\"\n :aria-label=\"column.header\"\n :aria-controls=\"listId\"\n :model-value=\"text\"\n :display-value=\"() => text\"\n @update:model-value=\"onText\"\n @keydown=\"onKeydown\"\n />\n </ComboboxAnchor>\n <ComboboxPortal>\n <ComboboxContent\n class=\"dt-pop dt-cell-list dt-sheet-layer\"\n position=\"popper\"\n align=\"end\"\n :side-offset=\"2\"\n :aria-label=\"column.header\"\n >\n <ComboboxViewport>\n <ComboboxItem\n v-for=\"o in options\"\n :key=\"String(o.value)\"\n class=\"dt-pop-item dt-cell-option\"\n :value=\"o.value\"\n :text-value=\"o.label\"\n >\n <Item :o=\"o\" />\n <kbd class=\"dt-kbd dt-cell-option-enter\" aria-hidden=\"true\">↵</kbd>\n </ComboboxItem>\n <ComboboxEmpty class=\"dt-options-empty\">{{ i18n.t('picker.noMatch') }}</ComboboxEmpty>\n </ComboboxViewport>\n </ComboboxContent>\n </ComboboxPortal>\n </ComboboxRoot>\n</template>\n","<script setup lang=\"ts\">\n// Seçenek hücre editörü (07 §5, T11-07): reka Combobox; yazmak listeyi süzer, Enter seçer, ilk Esc listeyi kapatır\n// (ikinci Esc düzenlemeyi iptal eder — sheet, `aria-expanded` ve `defaultPrevented` üzerinden anlar). Listede olmayan\n// metin ham kalır → \"“Pump” isn't an option\". Liste portalda: `dt-sheet-layer` dışarı tık sayılmaz. Alt↓ listeyi açar.\nimport {\n ComboboxAnchor,\n ComboboxContent,\n ComboboxEmpty,\n ComboboxInput,\n ComboboxItem,\n ComboboxPortal,\n ComboboxRoot,\n ComboboxViewport,\n} from 'reka-ui'\nimport { computed, nextTick, onMounted, ref, watch } from 'vue'\nimport { optionLabel } from '../../core/cells/format'\nimport { badge } from '../../core/cells/renderCell'\nimport { useDataTableContext } from '../../core/plugin'\nimport type { ColumnDef, OptionDef } from '../../types/columns'\nimport { inputText, parseInput } from '../parse'\nimport { focusEnd, useParseEnv } from './useParseEnv'\n\nconst props = defineProps<{ modelValue: unknown; row: object; column: ColumnDef }>()\nconst emit = defineEmits<{ 'update:modelValue': [value: unknown] }>()\nconst { i18n } = useDataTableContext()\nconst env = useParseEnv()\nconst def = computed(() => props.column as Extract<ColumnDef, { type: 'select' }>)\n// Satıra göre kapalı seçenekler listede yok (`row` taslak satır); etiket çözümü tam listeden.\nconst options = computed(() => {\n const d = def.value\n return d.optionEnabled ? d.options.filter((o) => d.optionEnabled!(o, props.row)) : d.options\n})\nconst open = ref(true)\n// reka listenin id'sini input'a geç yazıyor (aria-controls=\"\"): açılınca DOM'daki gerçek id okunur (axe aria-valid-attr-value).\nconst listId = ref<string | undefined>()\nwatch(\n open,\n (o) => {\n if (!o) return\n void nextTick(() => {\n listId.value = document.querySelector<HTMLElement>('.dt-cell-list[role=\"listbox\"]')?.id || undefined\n })\n },\n { immediate: true },\n)\nconst text = ref(inputText(props.column, props.modelValue))\nconst input = ref<{ $el: HTMLInputElement } | null>(null)\nconst inputEl = () => input.value?.$el ?? null\nonMounted(() => void nextTick(() => focusEnd(inputEl())))\n\nconst onText = (v: string) => {\n text.value = v\n emit('update:modelValue', parseInput(props.column, v, env()))\n}\nconst onSelect = (v: unknown) => {\n if (v === undefined || v === null) return\n emit('update:modelValue', v)\n text.value = optionLabel(def.value.options, v)\n open.value = false\n void nextTick(() => focusEnd(inputEl()))\n}\nconst onKeydown = (e: KeyboardEvent) => {\n if (e.altKey && e.key === 'ArrowDown') {\n e.preventDefault()\n open.value = true\n }\n}\n// Sabit bileşen: her render'da yeni bileşen üretmek rozeti mousedown–mouseup arasında DOM'da değiştirir, click kaybolur.\nconst Item = (p: { o: OptionDef }) => badge(p.o.tone, p.o.label)\n</script>\n\n<template>\n <ComboboxRoot\n v-model:open=\"open\"\n class=\"dt-cell-editor is-option\"\n :model-value=\"(modelValue as string | number | undefined) ?? undefined\"\n :reset-search-term-on-blur=\"false\"\n @update:model-value=\"onSelect\"\n >\n <!-- Liste hücreye göre konumlanır (altında, sağa hizalı): çapa editörün kendisi. -->\n <ComboboxAnchor class=\"dt-cell-anchor\">\n <ComboboxInput\n ref=\"input\"\n class=\"dt-cell-input\"\n autocomplete=\"off\"\n :aria-label=\"column.header\"\n :aria-controls=\"listId\"\n :model-value=\"text\"\n :display-value=\"() => text\"\n @update:model-value=\"onText\"\n @keydown=\"onKeydown\"\n />\n </ComboboxAnchor>\n <ComboboxPortal>\n <ComboboxContent\n class=\"dt-pop dt-cell-list dt-sheet-layer\"\n position=\"popper\"\n align=\"end\"\n :side-offset=\"2\"\n :aria-label=\"column.header\"\n >\n <ComboboxViewport>\n <ComboboxItem\n v-for=\"o in options\"\n :key=\"String(o.value)\"\n class=\"dt-pop-item dt-cell-option\"\n :value=\"o.value\"\n :text-value=\"o.label\"\n >\n <Item :o=\"o\" />\n <kbd class=\"dt-kbd dt-cell-option-enter\" aria-hidden=\"true\">↵</kbd>\n </ComboboxItem>\n <ComboboxEmpty class=\"dt-options-empty\">{{ i18n.t('picker.noMatch') }}</ComboboxEmpty>\n </ComboboxViewport>\n </ComboboxContent>\n </ComboboxPortal>\n </ComboboxRoot>\n</template>\n","<script setup lang=\"ts\">\n// Metin hücre editörü (07 §5, T11-07): hücrenin yerinde input; `text` tipinde daha yüksek kutu (⇧↵ yeni satır). Değer\n// her tuşta çözümlenir ve yayılır; Enter/Tab/Esc'i sheet yönetir (editör sözleşmesi: props { modelValue, row, column }).\nimport { onMounted, ref } from 'vue'\nimport type { ColumnDef } from '../../types/columns'\nimport { inputText, parseInput } from '../parse'\nimport { focusEnd, useParseEnv } from './useParseEnv'\n\nconst props = defineProps<{ modelValue: unknown; row: object; column: ColumnDef }>()\nconst emit = defineEmits<{ 'update:modelValue': [value: unknown] }>()\nconst env = useParseEnv()\nconst el = ref<HTMLInputElement | HTMLTextAreaElement | null>(null)\nconst text = ref(inputText(props.column, props.modelValue))\nonMounted(() => focusEnd(el.value))\nconst onInput = () => {\n text.value = el.value!.value\n emit('update:modelValue', parseInput(props.column, text.value, env()))\n}\n</script>\n\n<template>\n <textarea\n v-if=\"column.type === 'text'\"\n ref=\"el\"\n class=\"dt-cell-input is-multiline\"\n :value=\"text\"\n :aria-label=\"column.header\"\n rows=\"3\"\n @input=\"onInput\"\n />\n <input\n v-else\n ref=\"el\"\n class=\"dt-cell-input\"\n type=\"text\"\n :value=\"text\"\n :aria-label=\"column.header\"\n autocomplete=\"off\"\n @input=\"onInput\"\n />\n</template>\n","<script setup lang=\"ts\">\n// Metin hücre editörü (07 §5, T11-07): hücrenin yerinde input; `text` tipinde daha yüksek kutu (⇧↵ yeni satır). Değer\n// her tuşta çözümlenir ve yayılır; Enter/Tab/Esc'i sheet yönetir (editör sözleşmesi: props { modelValue, row, column }).\nimport { onMounted, ref } from 'vue'\nimport type { ColumnDef } from '../../types/columns'\nimport { inputText, parseInput } from '../parse'\nimport { focusEnd, useParseEnv } from './useParseEnv'\n\nconst props = defineProps<{ modelValue: unknown; row: object; column: ColumnDef }>()\nconst emit = defineEmits<{ 'update:modelValue': [value: unknown] }>()\nconst env = useParseEnv()\nconst el = ref<HTMLInputElement | HTMLTextAreaElement | null>(null)\nconst text = ref(inputText(props.column, props.modelValue))\nonMounted(() => focusEnd(el.value))\nconst onInput = () => {\n text.value = el.value!.value\n emit('update:modelValue', parseInput(props.column, text.value, env()))\n}\n</script>\n\n<template>\n <textarea\n v-if=\"column.type === 'text'\"\n ref=\"el\"\n class=\"dt-cell-input is-multiline\"\n :value=\"text\"\n :aria-label=\"column.header\"\n rows=\"3\"\n @input=\"onInput\"\n />\n <input\n v-else\n ref=\"el\"\n class=\"dt-cell-input\"\n type=\"text\"\n :value=\"text\"\n :aria-label=\"column.header\"\n autocomplete=\"off\"\n @input=\"onInput\"\n />\n</template>\n","<script setup lang=\"ts\">\n// Tarih hücre editörü (07 §5, T11-07): yazılabilir (\"24.10\", \"+7d\", \"today\") + takvim popover'ı (reka Popover + Calendar).\n// Popover üstünde çözümlenen tarih (\"Wed, Oct 28 · in 7 days\"); kapanınca odak input'a döner (ikinci Esc düzenlemeyi\n// iptal eder). Popover portalda: `dt-sheet-layer` dışarı tık sayılmaz. Alt↓ takvimi açar.\nimport { getDayOfWeek, getLocalTimeZone, parseDate, startOfWeek, today, type DateValue } from '@internationalized/date'\nimport { PhCalendarBlank, PhCaretLeft, PhCaretRight } from '@phosphor-icons/vue'\nimport {\n CalendarCell,\n CalendarCellTrigger,\n CalendarGrid,\n CalendarGridBody,\n CalendarGridHead,\n CalendarGridRow,\n CalendarHeadCell,\n CalendarHeader,\n CalendarHeading,\n CalendarNext,\n CalendarPrev,\n CalendarRoot,\n PopoverContent,\n PopoverPortal,\n PopoverRoot,\n PopoverTrigger,\n} from 'reka-ui'\nimport { computed, nextTick, onMounted, ref } from 'vue'\nimport { getFormat, toDate } from '../../core/format'\nimport { useDataTableContext } from '../../core/plugin'\nimport type { ColumnDef } from '../../types/columns'\nimport { inputText, parseInput } from '../parse'\nimport { focusEnd, useParseEnv } from './useParseEnv'\n\nconst props = defineProps<{ modelValue: unknown; row: object; column: ColumnDef }>()\nconst emit = defineEmits<{ 'update:modelValue': [value: unknown] }>()\nconst { i18n, locale } = useDataTableContext()\nconst env = useParseEnv()\nconst fmt = getFormat(locale)\nconst dayFmt = new Intl.DateTimeFormat(locale, { weekday: 'short', month: 'short', day: 'numeric' })\nconst el = ref<HTMLInputElement | null>(null)\nconst open = ref(false)\nconst text = ref(inputText(props.column, props.modelValue))\nonMounted(() => focusEnd(el.value))\n\nconst tz = getLocalTimeZone()\nconst now = today(tz)\nconst weekStartsOn = getDayOfWeek(startOfWeek(now, locale), 'en-US') as 0 | 1 | 2 | 3 | 4 | 5 | 6\nconst safe = (s: unknown): DateValue | undefined => {\n try {\n return typeof s === 'string' && s ? parseDate(s.slice(0, 10)) : undefined\n } catch {\n return undefined\n }\n}\nconst single = computed(() => safe(props.modelValue))\nconst resolved = computed(() => {\n const v = props.modelValue\n if (typeof v !== 'string' || !single.value) return null\n const d = toDate(v.slice(0, 10))\n return { day: dayFmt.format(d), relative: fmt.relative(d) }\n})\n\nconst onInput = () => {\n text.value = el.value!.value\n emit('update:modelValue', parseInput(props.column, text.value, env()))\n}\nconst onPick = (d: DateValue | undefined) => {\n if (!d) return\n const iso = d.toString()\n text.value = iso\n emit('update:modelValue', iso)\n open.value = false\n}\nconst refocus = (e: Event) => {\n e.preventDefault()\n void nextTick(() => focusEnd(el.value))\n}\nconst onKeydown = (e: KeyboardEvent) => {\n if (e.altKey && e.key === 'ArrowDown') {\n e.preventDefault()\n open.value = true\n }\n}\n</script>\n\n<template>\n <span class=\"dt-cell-editor is-date\">\n <input\n ref=\"el\"\n class=\"dt-cell-input\"\n type=\"text\"\n :value=\"text\"\n :aria-label=\"column.header\"\n autocomplete=\"off\"\n @input=\"onInput\"\n @keydown=\"onKeydown\"\n />\n <PopoverRoot v-model:open=\"open\">\n <PopoverTrigger as-child>\n <button type=\"button\" class=\"dt-cell-editor-btn\" tabindex=\"-1\" :aria-label=\"i18n.t('type.date')\">\n <PhCalendarBlank :size=\"14\" aria-hidden=\"true\" />\n </button>\n </PopoverTrigger>\n <PopoverPortal>\n <PopoverContent\n class=\"dt-pop dt-cell-date dt-sheet-layer\"\n align=\"start\"\n :side-offset=\"4\"\n @close-auto-focus=\"refocus\"\n >\n <div v-if=\"resolved\" class=\"dt-cell-date-head\">\n <strong>{{ resolved.day }}</strong>\n <span>{{ resolved.relative }}</span>\n </div>\n <CalendarRoot\n v-slot=\"{ weekDays, grid }\"\n class=\"dt-calendar\"\n :model-value=\"single\"\n :locale=\"locale\"\n :week-starts-on=\"weekStartsOn\"\n :placeholder=\"single ?? now\"\n @update:model-value=\"(d) => onPick(d as DateValue | undefined)\"\n >\n <CalendarHeader class=\"dt-cal-head\">\n <CalendarPrev class=\"dt-icon-btn-sm\"><PhCaretLeft :size=\"16\" aria-hidden=\"true\" /></CalendarPrev>\n <CalendarHeading class=\"dt-cal-title\" />\n <CalendarNext class=\"dt-icon-btn-sm\"><PhCaretRight :size=\"16\" aria-hidden=\"true\" /></CalendarNext>\n </CalendarHeader>\n <CalendarGrid v-for=\"month in grid\" :key=\"month.value.toString()\" class=\"dt-cal-grid\">\n <CalendarGridHead>\n <CalendarGridRow>\n <CalendarHeadCell v-for=\"day in weekDays\" :key=\"day\" class=\"dt-cal-dow\">{{ day }}</CalendarHeadCell>\n </CalendarGridRow>\n </CalendarGridHead>\n <CalendarGridBody>\n <CalendarGridRow v-for=\"(week, i) in month.rows\" :key=\"i\">\n <CalendarCell v-for=\"d in week\" :key=\"d.toString()\" :date=\"d\" class=\"dt-cal-cell\">\n <CalendarCellTrigger :day=\"d\" :month=\"month.value\" class=\"dt-cal-day\" />\n </CalendarCell>\n </CalendarGridRow>\n </CalendarGridBody>\n </CalendarGrid>\n </CalendarRoot>\n </PopoverContent>\n </PopoverPortal>\n </PopoverRoot>\n </span>\n</template>\n","<script setup lang=\"ts\">\n// Tarih hücre editörü (07 §5, T11-07): yazılabilir (\"24.10\", \"+7d\", \"today\") + takvim popover'ı (reka Popover + Calendar).\n// Popover üstünde çözümlenen tarih (\"Wed, Oct 28 · in 7 days\"); kapanınca odak input'a döner (ikinci Esc düzenlemeyi\n// iptal eder). Popover portalda: `dt-sheet-layer` dışarı tık sayılmaz. Alt↓ takvimi açar.\nimport { getDayOfWeek, getLocalTimeZone, parseDate, startOfWeek, today, type DateValue } from '@internationalized/date'\nimport { PhCalendarBlank, PhCaretLeft, PhCaretRight } from '@phosphor-icons/vue'\nimport {\n CalendarCell,\n CalendarCellTrigger,\n CalendarGrid,\n CalendarGridBody,\n CalendarGridHead,\n CalendarGridRow,\n CalendarHeadCell,\n CalendarHeader,\n CalendarHeading,\n CalendarNext,\n CalendarPrev,\n CalendarRoot,\n PopoverContent,\n PopoverPortal,\n PopoverRoot,\n PopoverTrigger,\n} from 'reka-ui'\nimport { computed, nextTick, onMounted, ref } from 'vue'\nimport { getFormat, toDate } from '../../core/format'\nimport { useDataTableContext } from '../../core/plugin'\nimport type { ColumnDef } from '../../types/columns'\nimport { inputText, parseInput } from '../parse'\nimport { focusEnd, useParseEnv } from './useParseEnv'\n\nconst props = defineProps<{ modelValue: unknown; row: object; column: ColumnDef }>()\nconst emit = defineEmits<{ 'update:modelValue': [value: unknown] }>()\nconst { i18n, locale } = useDataTableContext()\nconst env = useParseEnv()\nconst fmt = getFormat(locale)\nconst dayFmt = new Intl.DateTimeFormat(locale, { weekday: 'short', month: 'short', day: 'numeric' })\nconst el = ref<HTMLInputElement | null>(null)\nconst open = ref(false)\nconst text = ref(inputText(props.column, props.modelValue))\nonMounted(() => focusEnd(el.value))\n\nconst tz = getLocalTimeZone()\nconst now = today(tz)\nconst weekStartsOn = getDayOfWeek(startOfWeek(now, locale), 'en-US') as 0 | 1 | 2 | 3 | 4 | 5 | 6\nconst safe = (s: unknown): DateValue | undefined => {\n try {\n return typeof s === 'string' && s ? parseDate(s.slice(0, 10)) : undefined\n } catch {\n return undefined\n }\n}\nconst single = computed(() => safe(props.modelValue))\nconst resolved = computed(() => {\n const v = props.modelValue\n if (typeof v !== 'string' || !single.value) return null\n const d = toDate(v.slice(0, 10))\n return { day: dayFmt.format(d), relative: fmt.relative(d) }\n})\n\nconst onInput = () => {\n text.value = el.value!.value\n emit('update:modelValue', parseInput(props.column, text.value, env()))\n}\nconst onPick = (d: DateValue | undefined) => {\n if (!d) return\n const iso = d.toString()\n text.value = iso\n emit('update:modelValue', iso)\n open.value = false\n}\nconst refocus = (e: Event) => {\n e.preventDefault()\n void nextTick(() => focusEnd(el.value))\n}\nconst onKeydown = (e: KeyboardEvent) => {\n if (e.altKey && e.key === 'ArrowDown') {\n e.preventDefault()\n open.value = true\n }\n}\n</script>\n\n<template>\n <span class=\"dt-cell-editor is-date\">\n <input\n ref=\"el\"\n class=\"dt-cell-input\"\n type=\"text\"\n :value=\"text\"\n :aria-label=\"column.header\"\n autocomplete=\"off\"\n @input=\"onInput\"\n @keydown=\"onKeydown\"\n />\n <PopoverRoot v-model:open=\"open\">\n <PopoverTrigger as-child>\n <button type=\"button\" class=\"dt-cell-editor-btn\" tabindex=\"-1\" :aria-label=\"i18n.t('type.date')\">\n <PhCalendarBlank :size=\"14\" aria-hidden=\"true\" />\n </button>\n </PopoverTrigger>\n <PopoverPortal>\n <PopoverContent\n class=\"dt-pop dt-cell-date dt-sheet-layer\"\n align=\"start\"\n :side-offset=\"4\"\n @close-auto-focus=\"refocus\"\n >\n <div v-if=\"resolved\" class=\"dt-cell-date-head\">\n <strong>{{ resolved.day }}</strong>\n <span>{{ resolved.relative }}</span>\n </div>\n <CalendarRoot\n v-slot=\"{ weekDays, grid }\"\n class=\"dt-calendar\"\n :model-value=\"single\"\n :locale=\"locale\"\n :week-starts-on=\"weekStartsOn\"\n :placeholder=\"single ?? now\"\n @update:model-value=\"(d) => onPick(d as DateValue | undefined)\"\n >\n <CalendarHeader class=\"dt-cal-head\">\n <CalendarPrev class=\"dt-icon-btn-sm\"><PhCaretLeft :size=\"16\" aria-hidden=\"true\" /></CalendarPrev>\n <CalendarHeading class=\"dt-cal-title\" />\n <CalendarNext class=\"dt-icon-btn-sm\"><PhCaretRight :size=\"16\" aria-hidden=\"true\" /></CalendarNext>\n </CalendarHeader>\n <CalendarGrid v-for=\"month in grid\" :key=\"month.value.toString()\" class=\"dt-cal-grid\">\n <CalendarGridHead>\n <CalendarGridRow>\n <CalendarHeadCell v-for=\"day in weekDays\" :key=\"day\" class=\"dt-cal-dow\">{{ day }}</CalendarHeadCell>\n </CalendarGridRow>\n </CalendarGridHead>\n <CalendarGridBody>\n <CalendarGridRow v-for=\"(week, i) in month.rows\" :key=\"i\">\n <CalendarCell v-for=\"d in week\" :key=\"d.toString()\" :date=\"d\" class=\"dt-cal-cell\">\n <CalendarCellTrigger :day=\"d\" :month=\"month.value\" class=\"dt-cal-day\" />\n </CalendarCell>\n </CalendarGridRow>\n </CalendarGridBody>\n </CalendarGrid>\n </CalendarRoot>\n </PopoverContent>\n </PopoverPortal>\n </PopoverRoot>\n </span>\n</template>\n","// Yerleşik editörlerin DataSheet'ten aldığı iç bağlam (public sözleşme değil; özel editörler yalnızca props alır).\nimport { inject, type InjectionKey } from 'vue'\n\nexport interface SheetEditorContext {\n /** Yazarak açılan `multiselect` editöründe aramaya giden ilk metin (seçimler korunur). */\n seed: () => string | undefined\n}\n\nexport const SHEET_EDITOR_KEY: InjectionKey<SheetEditorContext> = Symbol('dt-sheet-editor')\n\nexport const useSheetEditor = (): SheetEditorContext => inject(SHEET_EDITOR_KEY, { seed: () => undefined })\n","<script setup lang=\"ts\">\n// Çoklu seçim editörü (07 §5, 06 §7 T11-07): multiselect. Hücre içinde arama kutusu, altta seçenek listesi (reka Combobox,\n// `multiple`). Yazmak süzer; eşleşen seçenek yoksa liste açılmaz (boş listbox olmaz, axe). Enter vurgulu seçeneği aç/kapar;\n// seçim listeyi açık tutar, seçili seçenek tik alır, tekrar seçmek kaldırır. Listede olmayan metin yok sayılır: listede olmayan\n// değer yalnızca yapıştırmayla girer ve \"isn't an option\" hatası alır (select ile aynı). Esc kaydedip çıkar (SheetGrid).\n// Liste portalda: `dt-sheet-layer`.\nimport { PhCheck } from '@phosphor-icons/vue'\nimport {\n ComboboxAnchor,\n ComboboxContent,\n ComboboxInput,\n ComboboxItem,\n ComboboxItemIndicator,\n ComboboxPortal,\n ComboboxRoot,\n ComboboxViewport,\n} from 'reka-ui'\nimport { computed, nextTick, onMounted, ref, watch } from 'vue'\nimport { badge } from '../../core/cells/renderCell'\nimport type { ColumnDef, OptionDef } from '../../types/columns'\nimport { useDataTableContext } from '../../core/plugin'\nimport { useSheetEditor } from './context'\nimport { focusEnd } from './useParseEnv'\n\ntype Value = string | number\nconst props = defineProps<{ modelValue: unknown; row: object; column: ColumnDef }>()\nconst emit = defineEmits<{ 'update:modelValue': [value: unknown] }>()\nconst { locale } = useDataTableContext()\nconst lower = (t: string) => t.toLocaleLowerCase(locale)\nconst sheet = useSheetEditor()\n\nconst def = computed(() => props.column as Extract<ColumnDef, { type: 'multiselect' }>)\nconst values = computed<Value[]>(() => (Array.isArray(props.modelValue) ? (props.modelValue as Value[]) : []))\n/** Sütunun seçenekleri: satıra göre kapalı olanlar yok, seçili olanlar kalır. */\nconst suggestions = computed<OptionDef[]>(() => {\n const d = def.value\n return d.options.filter((o) => values.value.includes(o.value) || !d.optionEnabled || d.optionEnabled(o, props.row))\n})\n\nconst search = ref(sheet.seed() ?? '')\n/** Süzme burada (reka'nınki kapalı): eşleşme yoksa liste hiç açılmaz. */\nconst shown = computed(() => {\n const q = lower(search.value.trim())\n return q ? suggestions.value.filter((o) => lower(o.label).includes(q)) : suggestions.value\n})\nconst wantOpen = ref(true)\nconst open = computed({ get: () => wantOpen.value && shown.value.length > 0, set: (v) => (wantOpen.value = v) })\n// reka listenin id'sini input'a geç yazıyor (aria-controls=\"\"): açılınca DOM'daki gerçek id okunur (OptionCell ile aynı).\nconst listId = ref<string | undefined>()\nwatch(\n open,\n (o) => {\n if (o)\n void nextTick(() => {\n listId.value = document.querySelector<HTMLElement>('.dt-cell-list[role=\"listbox\"]')?.id || undefined\n })\n },\n { immediate: true },\n)\n/** reka aç/kapa yapılmış yeni diziyi verir; arama temizlenir, liste açık kalır. */\nconst onPick = (v: unknown) => {\n if (!Array.isArray(v)) return\n emit('update:modelValue', v.length ? v : null)\n search.value = ''\n void nextTick(reveal)\n}\nconst onKeydown = (e: KeyboardEvent) => {\n if (e.altKey && e.key === 'ArrowDown') {\n e.preventDefault()\n open.value = true\n }\n}\nconst input = ref<{ $el: HTMLInputElement } | null>(null)\nconst reveal = () => focusEnd(input.value?.$el ?? null)\nonMounted(() => void nextTick(reveal))\n\n// Sabit bileşen: her render'da yeni bileşen üretmek öğeyi mousedown–mouseup arasında değiştirir, click kaybolur.\nconst Item = (p: { o: OptionDef }) => badge(p.o.tone, p.o.label)\n</script>\n\n<template>\n <ComboboxRoot\n v-model:open=\"open\"\n class=\"dt-cell-editor is-multi\"\n multiple\n :model-value=\"values\"\n :reset-search-term-on-blur=\"false\"\n :reset-search-term-on-select=\"false\"\n ignore-filter\n @update:model-value=\"onPick\"\n >\n <ComboboxAnchor class=\"dt-cell-anchor\">\n <ComboboxInput\n ref=\"input\"\n v-model=\"search\"\n class=\"dt-cell-input\"\n :display-value=\"() => search\"\n autocomplete=\"off\"\n :aria-label=\"column.header\"\n :aria-controls=\"listId\"\n @keydown=\"onKeydown\"\n />\n </ComboboxAnchor>\n <ComboboxPortal>\n <ComboboxContent\n class=\"dt-pop dt-cell-list dt-sheet-layer\"\n position=\"popper\"\n align=\"start\"\n :side-offset=\"2\"\n :aria-label=\"column.header\"\n >\n <ComboboxViewport>\n <ComboboxItem\n v-for=\"o in shown\"\n :key=\"String(o.value)\"\n class=\"dt-pop-item dt-cell-option\"\n :value=\"o.value\"\n :text-value=\"o.label\"\n >\n <Item :o=\"o\" />\n <ComboboxItemIndicator class=\"dt-cell-option-check\">\n <PhCheck :size=\"14\" aria-hidden=\"true\" />\n </ComboboxItemIndicator>\n <kbd class=\"dt-kbd dt-cell-option-enter\" aria-hidden=\"true\">↵</kbd>\n </ComboboxItem>\n </ComboboxViewport>\n </ComboboxContent>\n </ComboboxPortal>\n </ComboboxRoot>\n</template>\n","<script setup lang=\"ts\">\n// Çoklu seçim editörü (07 §5, 06 §7 T11-07): multiselect. Hücre içinde arama kutusu, altta seçenek listesi (reka Combobox,\n// `multiple`). Yazmak süzer; eşleşen seçenek yoksa liste açılmaz (boş listbox olmaz, axe). Enter vurgulu seçeneği aç/kapar;\n// seçim listeyi açık tutar, seçili seçenek tik alır, tekrar seçmek kaldırır. Listede olmayan metin yok sayılır: listede olmayan\n// değer yalnızca yapıştırmayla girer ve \"isn't an option\" hatası alır (select ile aynı). Esc kaydedip çıkar (SheetGrid).\n// Liste portalda: `dt-sheet-layer`.\nimport { PhCheck } from '@phosphor-icons/vue'\nimport {\n ComboboxAnchor,\n ComboboxContent,\n ComboboxInput,\n ComboboxItem,\n ComboboxItemIndicator,\n ComboboxPortal,\n ComboboxRoot,\n ComboboxViewport,\n} from 'reka-ui'\nimport { computed, nextTick, onMounted, ref, watch } from 'vue'\nimport { badge } from '../../core/cells/renderCell'\nimport type { ColumnDef, OptionDef } from '../../types/columns'\nimport { useDataTableContext } from '../../core/plugin'\nimport { useSheetEditor } from './context'\nimport { focusEnd } from './useParseEnv'\n\ntype Value = string | number\nconst props = defineProps<{ modelValue: unknown; row: object; column: ColumnDef }>()\nconst emit = defineEmits<{ 'update:modelValue': [value: unknown] }>()\nconst { locale } = useDataTableContext()\nconst lower = (t: string) => t.toLocaleLowerCase(locale)\nconst sheet = useSheetEditor()\n\nconst def = computed(() => props.column as Extract<ColumnDef, { type: 'multiselect' }>)\nconst values = computed<Value[]>(() => (Array.isArray(props.modelValue) ? (props.modelValue as Value[]) : []))\n/** Sütunun seçenekleri: satıra göre kapalı olanlar yok, seçili olanlar kalır. */\nconst suggestions = computed<OptionDef[]>(() => {\n const d = def.value\n return d.options.filter((o) => values.value.includes(o.value) || !d.optionEnabled || d.optionEnabled(o, props.row))\n})\n\nconst search = ref(sheet.seed() ?? '')\n/** Süzme burada (reka'nınki kapalı): eşleşme yoksa liste hiç açılmaz. */\nconst shown = computed(() => {\n const q = lower(search.value.trim())\n return q ? suggestions.value.filter((o) => lower(o.label).includes(q)) : suggestions.value\n})\nconst wantOpen = ref(true)\nconst open = computed({ get: () => wantOpen.value && shown.value.length > 0, set: (v) => (wantOpen.value = v) })\n// reka listenin id'sini input'a geç yazıyor (aria-controls=\"\"): açılınca DOM'daki gerçek id okunur (OptionCell ile aynı).\nconst listId = ref<string | undefined>()\nwatch(\n open,\n (o) => {\n if (o)\n void nextTick(() => {\n listId.value = document.querySelector<HTMLElement>('.dt-cell-list[role=\"listbox\"]')?.id || undefined\n })\n },\n { immediate: true },\n)\n/** reka aç/kapa yapılmış yeni diziyi verir; arama temizlenir, liste açık kalır. */\nconst onPick = (v: unknown) => {\n if (!Array.isArray(v)) return\n emit('update:modelValue', v.length ? v : null)\n search.value = ''\n void nextTick(reveal)\n}\nconst onKeydown = (e: KeyboardEvent) => {\n if (e.altKey && e.key === 'ArrowDown') {\n e.preventDefault()\n open.value = true\n }\n}\nconst input = ref<{ $el: HTMLInputElement } | null>(null)\nconst reveal = () => focusEnd(input.value?.$el ?? null)\nonMounted(() => void nextTick(reveal))\n\n// Sabit bileşen: her render'da yeni bileşen üretmek öğeyi mousedown–mouseup arasında değiştirir, click kaybolur.\nconst Item = (p: { o: OptionDef }) => badge(p.o.tone, p.o.label)\n</script>\n\n<template>\n <ComboboxRoot\n v-model:open=\"open\"\n class=\"dt-cell-editor is-multi\"\n multiple\n :model-value=\"values\"\n :reset-search-term-on-blur=\"false\"\n :reset-search-term-on-select=\"false\"\n ignore-filter\n @update:model-value=\"onPick\"\n >\n <ComboboxAnchor class=\"dt-cell-anchor\">\n <ComboboxInput\n ref=\"input\"\n v-model=\"search\"\n class=\"dt-cell-input\"\n :display-value=\"() => search\"\n autocomplete=\"off\"\n :aria-label=\"column.header\"\n :aria-controls=\"listId\"\n @keydown=\"onKeydown\"\n />\n </ComboboxAnchor>\n <ComboboxPortal>\n <ComboboxContent\n class=\"dt-pop dt-cell-list dt-sheet-layer\"\n position=\"popper\"\n align=\"start\"\n :side-offset=\"2\"\n :aria-label=\"column.header\"\n >\n <ComboboxViewport>\n <ComboboxItem\n v-for=\"o in shown\"\n :key=\"String(o.value)\"\n class=\"dt-pop-item dt-cell-option\"\n :value=\"o.value\"\n :text-value=\"o.label\"\n >\n <Item :o=\"o\" />\n <ComboboxItemIndicator class=\"dt-cell-option-check\">\n <PhCheck :size=\"14\" aria-hidden=\"true\" />\n </ComboboxItemIndicator>\n <kbd class=\"dt-kbd dt-cell-option-enter\" aria-hidden=\"true\">↵</kbd>\n </ComboboxItem>\n </ComboboxViewport>\n </ComboboxContent>\n </ComboboxPortal>\n </ComboboxRoot>\n</template>\n","// Doldurma (07 §8): kaynak en az iki sayı ve sabit artışlıysa seri devam eder (1, 2, 3 / 10, 20), aksi halde kaynak\n// döngüyle kopyalanır. Yukarı doldurmada seri geriye gider, kopya sondan başlar.\n\n/** `count` hedef değer; `up` yukarı yön. */\nexport function fillValues(source: unknown[], count: number, up = false): unknown[] {\n if (!source.length || count <= 0) return []\n const nums = source.every((v) => typeof v === 'number') ? (source as number[]) : null\n if (nums && nums.length >= 2) {\n const step = nums[1]! - nums[0]!\n if (nums.every((v, i) => i === 0 || Math.abs(v - nums[i - 1]! - step) < 1e-9)) {\n const base = up ? nums[0]! : nums[nums.length - 1]!\n const dir = up ? -1 : 1\n return Array.from({ length: count }, (_, i) => round(base + dir * step * (i + 1)))\n }\n }\n const n = source.length\n return Array.from({ length: count }, (_, i) => (up ? source[(n - 1 - (i % n) + n) % n] : source[i % n]))\n}\n\n/** Kayan nokta artığı (0.1 + 0.2) görünmesin: 10 anlamlı basamak. */\nconst round = (n: number): number => Number(n.toPrecision(10))\n","// Excel'den içe aktarma — saf fonksiyonlar (07 §13, 01): başlık satırı tespiti ve sütun eşleme dosya biçiminden\n// bağımsızdır (.xlsx ve .csv aynı yol); `@medyat/vue-data-table/sheet`'ten dışa verilir ve ayrı test edilir.\nimport { isoDay } from '../../core/filters/model'\nimport type { ColumnDef } from '../../types/columns'\n\n/** Hücre metni: tarih yerel gün olarak ISO, sayı olduğu gibi, boş → ''. */\nexport function cellText(v: unknown): string {\n if (v === null || v === undefined) return ''\n if (v instanceof Date) return Number.isNaN(v.getTime()) ? '' : isoDay(v)\n return String(v).trim()\n}\n\n/** Başlık normalizasyonu: küçük harf, baştaki/sondaki ve ardışık boşluklar, Türkçe karakterler (ı→i, ş→s …). */\nconst TR: Record<string, string> = { ı: 'i', i̇: 'i', ş: 's', ğ: 'g', ç: 'c', ö: 'o', ü: 'u', â: 'a', î: 'i', û: 'u' }\nexport const normalizeHeader = (s: string): string =>\n s\n .toLocaleLowerCase('tr')\n .replace(/ı|i̇|ş|ğ|ç|ö|ü|â|î|û/g, (ch) => TR[ch] ?? ch)\n .replace(/[^a-z0-9]+/g, ' ')\n .trim()\n\nconst isNumberLike = (s: string) => /^[-+]?[\\d.,\\s]*\\d[\\d.,\\s]*%?$/.test(s)\n\n/**\n * Başlık satırı: ilk 20 satır içinde, boş olmayan hücre sayısı en yüksek ve hücrelerinin çoğu metin olan ilk satır;\n * eşitlikte ilk boş olmayan satır. Hiç aday yoksa 0.\n */\nexport function detectHeaderRow(rows: unknown[][]): number {\n let best = -1\n let bestScore = -1\n for (let i = 0; i < Math.min(rows.length, 20); i++) {\n const cells = (rows[i] ?? []).map(cellText).filter(Boolean)\n if (!cells.length) continue\n const textual = cells.filter((c) => !isNumberLike(c)).length\n if (textual * 2 < cells.length) continue\n if (cells.length > bestScore) {\n bestScore = cells.length\n best = i\n }\n }\n if (best >= 0) return best\n const first = rows.findIndex((r) => (r ?? []).some((c) => cellText(c) !== ''))\n return first < 0 ? 0 : first\n}\n\n/**\n * Otomatik eşleme: başlık normalize edilerek sütunun `header`, `id` ya da `importAliases` değerlerinden biriyle aynıysa\n * ve yalnızca tek bir sütuna uyuyorsa. Eşleşmeyen ya da birden fazla sütuna uyan başlık haritada yoktur.\n */\nexport function matchColumns(\n headers: string[],\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n columns: Array<Pick<ColumnDef<any>, 'id' | 'header' | 'importAliases'>>,\n): Record<number, string> {\n const out: Record<number, string> = {}\n const names = columns.map((c) => new Set([c.header, String(c.id), ...(c.importAliases ?? [])].map(normalizeHeader)))\n headers.forEach((h, i) => {\n const n = normalizeHeader(h)\n if (!n) return\n const hits = columns.filter((_, j) => names[j]!.has(n))\n if (hits.length === 1) out[i] = String(hits[0]!.id)\n })\n return out\n}\n","<script setup lang=\"ts\" generic=\"Row extends object\">\n// Import from Excel (07 §13, handoff 06 §11, T12-09/10/11): dosya yalnızca grid'i doldurur; Save'e kadar kaydedilmez.\n// Dosya (bırak/seç) → `parseFile` → sayfa · başlık satırı (otomatik, değiştirilebilir) · eşleşme anahtarı (eşlenmeden\n// Apply pasif) · sütun eşleme (otomatik tek/kesin, elle değiştirilebilir, boş kalan alınmaz, read-only pasif) · ilk değer\n// önizlemesi (1.650,00 → 1,650.00) · özet (listede/sunucuda olanlar günceller, yeni anahtarlar satır olur). Dosyadaki\n// boş hücre mevcut değeri silmez (Q3). `maxRows` aşılırsa Apply pasif.\nimport {\n PhArrowLeft,\n PhArrowRight,\n PhInfo,\n PhLock,\n PhTable,\n PhUploadSimple,\n PhWarningCircle,\n PhX,\n} from '@phosphor-icons/vue'\nimport {\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogOverlay,\n DialogPortal,\n DialogRoot,\n DialogTitle,\n} from 'reka-ui'\nimport { computed, ref, shallowRef, watch } from 'vue'\nimport { formatCell, type FormatEnv } from '../core/cells/format'\nimport { TYPE_SPECS } from '../core/cells/specs'\nimport { useDataTableContext } from '../core/plugin'\nimport type { ColumnDef } from '../types/columns'\nimport type { Plural } from '../types/core'\nimport type { ParsedWorkbook } from '../types/sheet'\nimport { cellText, detectHeaderRow, matchColumns } from './import/model'\nimport { inferDecimal, parseInput, type ParseEnv } from './parse'\n\nexport interface ImportRow<Row> {\n key: string\n values: Record<string, unknown>\n /** undefined: listede var; Row: sunucuda var (Update); null: yeni. */\n server?: Row | null\n}\nexport interface ImportPayload<Row> {\n rows: Array<ImportRow<Row>>\n addNew: boolean\n}\n\nconst props = defineProps<{\n parseFile: (file: File) => Promise<ParsedWorkbook>\n columns: Array<ColumnDef<Row>>\n keyColumn: string\n entity: Plural\n maxRows: number\n /** Şu anki satır sayısı (sınır için). */\n rowCount: number\n inList: (key: string) => boolean\n lookupKeys?: (keys: string[], ctx: { signal: AbortSignal }) => Promise<Record<string, Row | null>>\n parseEnv: (locale?: string) => ParseEnv\n fmtEnv: FormatEnv\n}>()\nconst emit = defineEmits<{ apply: [payload: ImportPayload<Row>] }>()\nconst open = defineModel<boolean>('open', { default: false })\nconst { i18n, locale } = useDataTableContext()\nconst SKIP = '__skip__'\n\nconst keyDef = computed(() => props.columns.find((c) => c.id === props.keyColumn))\nconst keyHeader = computed(() => keyDef.value?.header ?? props.keyColumn)\n/** Eşlenebilir alanlar: anahtar dışındaki sütunlar; düzenlenemeyenler listede pasif. */\nconst fields = computed(() =>\n props.columns\n .filter((c) => c.id !== props.keyColumn)\n .map((c) => ({ id: c.id as string, def: c, editable: !!c.editable })),\n)\n\nconst file = shallowRef<File | null>(null)\nconst workbook = shallowRef<ParsedWorkbook | null>(null)\nconst loading = ref(false)\nconst failed = ref(false)\n/** `parseFile`'ın fırlattığı sebep (uygulamanın metni); `import.failed` başlığının altında gösterilir. */\nconst failReason = ref('')\nconst sheetIndex = ref(0)\nconst headerRow = ref(0)\nconst mapping = ref<Record<number, string>>({})\nconst keyCol = ref<number | null>(null)\nconst addNew = ref(true)\nconst showNew = ref(false)\nconst dragging = ref(false)\nconst input = ref<HTMLInputElement | null>(null)\n\nconst rows = computed(() => workbook.value?.sheets[sheetIndex.value]?.rows ?? [])\nconst headers = computed(() => (rows.value[headerRow.value] ?? []).map(cellText))\nconst dataRows = computed(() =>\n rows.value.slice(headerRow.value + 1).filter((r) => (r ?? []).some((c) => cellText(c) !== '')),\n)\nconst headerOptions = computed(() => Math.min(rows.value.length, 20))\n\nconst rebuild = () => {\n const auto = matchColumns(headers.value, props.columns)\n const m: Record<number, string> = {}\n let key: number | null = null\n for (const [i, id] of Object.entries(auto)) {\n if (id === props.keyColumn) key = key ?? Number(i)\n else if (fields.value.find((f) => f.id === id)?.editable) m[Number(i)] = id\n }\n mapping.value = m\n keyCol.value = key\n showNew.value = false\n}\nconst load = async (f: File) => {\n file.value = f\n failed.value = false\n loading.value = true\n try {\n const wb = await props.parseFile(f)\n workbook.value = wb\n sheetIndex.value = 0\n headerRow.value = detectHeaderRow(wb.sheets[0]?.rows ?? [])\n rebuild()\n } catch (e) {\n workbook.value = null\n failed.value = true\n failReason.value = e instanceof Error ? e.message : ''\n } finally {\n loading.value = false\n }\n}\nwatch(sheetIndex, () => {\n headerRow.value = detectHeaderRow(rows.value)\n rebuild()\n})\nconst onHeaderRow = (n: number) => {\n headerRow.value = n\n rebuild()\n}\nconst onPick = (e: Event) => {\n const f = (e.target as HTMLInputElement).files?.[0]\n if (f) void load(f)\n ;(e.target as HTMLInputElement).value = ''\n}\nconst onDrop = (e: DragEvent) => {\n dragging.value = false\n const f = e.dataTransfer?.files?.[0]\n if (f) void load(f)\n}\nconst reset = () => {\n file.value = null\n workbook.value = null\n failed.value = false\n mapping.value = {}\n keyCol.value = null\n lookup.value = null\n}\nwatch(open, (o) => {\n if (!o) reset()\n})\n\n// Anahtarlar: listede olanlar güncellenir; olmayanlar `lookupKeys` ile sunucuda aranır (varsa Update, yoksa New).\nconst keyTexts = computed(() =>\n keyCol.value === null ? [] : dataRows.value.map((r) => cellText(r?.[keyCol.value!])).filter(Boolean),\n)\nconst lookup = shallowRef<Map<string, Row | null> | null>(null)\nlet ctl: AbortController | null = null\nwatch(keyTexts, async (keys) => {\n lookup.value = null\n ctl?.abort()\n const unknown = [...new Set(keys.filter((k) => !props.inList(k)))]\n if (!unknown.length || !props.lookupKeys) {\n lookup.value = new Map(unknown.map((k) => [k, null]))\n return\n }\n ctl = new AbortController()\n const map = new Map<string, Row | null>()\n try {\n for (let i = 0; i < unknown.length; i += 500) {\n const chunk = unknown.slice(i, i + 500)\n const res = await props.lookupKeys(chunk, { signal: ctl.signal })\n for (const k of chunk) map.set(k, res[k] ?? null)\n }\n lookup.value = map\n } catch {\n if (!ctl.signal.aborted) lookup.value = new Map(unknown.map((k) => [k, null]))\n }\n})\nconst summary = computed(() => {\n if (!keyTexts.value.length) return null\n const seen = new Set<string>()\n let inList = 0\n let server = 0\n const news: string[] = []\n for (const k of keyTexts.value) {\n if (seen.has(k)) continue\n seen.add(k)\n if (props.inList(k)) inList++\n else if (lookup.value?.get(k)) server++\n else news.push(k)\n }\n return { updates: inList + server, news, pending: lookup.value === null && !!props.lookupKeys }\n})\nconst overLimit = computed(() => {\n const s = summary.value\n return !!s && addNew.value && props.rowCount + s.news.length > props.maxRows\n})\nconst canApply = computed(\n () => !!workbook.value && keyCol.value !== null && !!summary.value && !summary.value.pending && !overLimit.value,\n)\n\n// Önizleme: ilk veri satırının ham değeri ve çözümlenmiş biçimi (sütun bazında ondalık çıkarımı, 07 §7).\nconst localeFor = (col: number, def: ColumnDef<Row>): string => {\n if (!TYPE_SPECS[def.type].numeric) return locale\n const dec = inferDecimal(dataRows.value.slice(0, 50).map((r) => cellText(r?.[col])))\n return dec === ',' ? 'de' : dec === '.' ? 'en' : locale\n}\nconst convert = (col: number, def: ColumnDef<Row>, raw: unknown): unknown => {\n if (typeof raw === 'number' || typeof raw === 'boolean') return raw\n if (raw instanceof Date) return cellText(raw)\n const text = cellText(raw)\n return text === '' ? null : parseInput(def, text, props.parseEnv(localeFor(col, def)))\n}\nconst preview = (col: number): { raw: string; shown: string | null } => {\n const row = dataRows.value[0]\n const raw = cellText(row?.[col])\n const id = mapping.value[col]\n const def = id ? props.columns.find((c) => c.id === id) : undefined\n if (!def || !raw) return { raw, shown: null }\n const value = convert(col, def, row?.[col])\n const shown = formatCell(def, {} as Row, value, props.fmtEnv)\n return { raw, shown: shown === raw ? null : shown }\n}\n\nconst apply = () => {\n if (!canApply.value || keyCol.value === null) return\n const out: Array<ImportRow<Row>> = []\n for (const r of dataRows.value) {\n const key = cellText(r?.[keyCol.value])\n if (!key) continue\n const values: Record<string, unknown> = {}\n for (const [col, id] of Object.entries(mapping.value)) {\n if (!id || id === SKIP) continue\n const def = props.columns.find((c) => c.id === id)\n const raw = r?.[Number(col)]\n if (!def || cellText(raw) === '') continue // boş hücre mevcut değeri silmez (Q3)\n values[id] = convert(Number(col), def, raw)\n }\n out.push({ key, values, server: props.inList(key) ? undefined : (lookup.value?.get(key) ?? null) })\n }\n emit('apply', { rows: out, addNew: addNew.value })\n open.value = false\n}\nconst sheetInfo = computed(() => {\n const s = workbook.value?.sheets[sheetIndex.value]\n return s ? i18n.t('import.sheetInfo', { sheet: s.name, count: dataRows.value.length }) : ''\n})\n</script>\n\n<template>\n <DialogRoot v-model:open=\"open\">\n <DialogPortal>\n <DialogOverlay class=\"dt-scrim\" />\n <DialogContent class=\"dt-dialog dt-import\">\n <div class=\"dt-import-head\">\n <div>\n <DialogTitle class=\"dt-dialog-title\">{{ i18n.t('import.title') }}</DialogTitle>\n <DialogDescription class=\"dt-dialog-body\">\n {{ i18n.t('import.body', { key: keyHeader, entity }) }}\n </DialogDescription>\n </div>\n <DialogClose class=\"dt-btn dt-btn-icon dt-btn-ghost\" :aria-label=\"i18n.t('common.close')\">\n <PhX :size=\"16\" aria-hidden=\"true\" />\n </DialogClose>\n </div>\n <div class=\"dt-import-body\">\n <input ref=\"input\" type=\"file\" class=\"dt-sr-only\" accept=\".xlsx,.xls,.csv\" tabindex=\"-1\" @change=\"onPick\" />\n <button\n v-if=\"!workbook\"\n type=\"button\"\n class=\"dt-import-drop\"\n :class=\"{ 'is-over': dragging, 'is-failed': failed }\"\n :aria-busy=\"loading ? 'true' : undefined\"\n @click=\"input?.click()\"\n @dragover.prevent=\"dragging = true\"\n @dragleave=\"dragging = false\"\n @drop.prevent=\"onDrop\"\n >\n <span class=\"dt-import-drop-icon\"><PhUploadSimple :size=\"20\" aria-hidden=\"true\" /></span>\n <span>{{ i18n.t('import.drop') }}</span>\n </button>\n <template v-else>\n <div class=\"dt-import-file\">\n <span class=\"dt-import-file-icon\"><PhTable :size=\"18\" aria-hidden=\"true\" /></span>\n <span class=\"dt-import-file-text\">\n <strong>{{ file?.name }}</strong>\n <label v-if=\"workbook.sheets.length > 1\" class=\"dt-select dt-import-sheet\">\n <select v-model=\"sheetIndex\" :aria-label=\"i18n.t('import.sheetInfo', { sheet: '', count: 0 })\">\n <option v-for=\"(s, i) in workbook.sheets\" :key=\"i\" :value=\"i\">\n {{ i18n.t('import.sheetInfo', { sheet: s.name, count: s.rows.length }) }}\n </option>\n </select>\n </label>\n <span v-else class=\"dt-import-sheet-info\">{{ sheetInfo }}</span>\n </span>\n <button type=\"button\" class=\"dt-btn dt-btn-sm\" @click=\"input?.click()\">\n {{ i18n.t('import.replace') }}\n </button>\n </div>\n <div class=\"dt-import-match\">\n <span class=\"dt-import-match-label\">{{ i18n.t('import.matchBy') }}</span>\n <span class=\"dt-import-key\">\n <PhLock :size=\"12\" aria-hidden=\"true\" />\n <span class=\"dt-mono\">{{ keyHeader }}</span>\n </span>\n <PhArrowLeft :size=\"14\" aria-hidden=\"true\" />\n <label class=\"dt-select dt-import-keysel\" :class=\"{ 'is-missing': keyCol === null }\">\n <select\n :value=\"keyCol ?? ''\"\n :aria-label=\"i18n.t('import.excelColumn')\"\n @change=\"\n keyCol =\n ($event.target as HTMLSelectElement).value === ''\n ? null\n : Number(($event.target as HTMLSelectElement).value)\n \"\n >\n <option value=\"\">{{ i18n.t('import.excelColumn') }}</option>\n <option v-for=\"(h, i) in headers\" :key=\"i\" :value=\"i\" :disabled=\"!h\">{{ h }}</option>\n </select>\n </label>\n <span class=\"dt-import-spacer\" />\n <label class=\"dt-select dt-import-headerrow\">\n <span class=\"dt-import-match-label\">{{ i18n.t('import.headerRow') }}</span>\n <select :value=\"headerRow\" @change=\"onHeaderRow(Number(($event.target as HTMLSelectElement).value))\">\n <option v-for=\"n in headerOptions\" :key=\"n\" :value=\"n - 1\">\n {{ i18n.t('import.headerRowN', { n }) }}\n </option>\n </select>\n </label>\n </div>\n <p v-if=\"keyCol === null\" class=\"dt-import-warn\">\n <PhWarningCircle :size=\"14\" aria-hidden=\"true\" />\n {{ i18n.t('import.keyRequired', { key: keyHeader }) }}\n </p>\n <table class=\"dt-import-table\">\n <colgroup>\n <col class=\"dt-import-col-excel\" />\n <col class=\"dt-import-col-arrow\" />\n <col class=\"dt-import-col-field\" />\n <col />\n </colgroup>\n <thead>\n <tr>\n <th>{{ i18n.t('import.excelColumn') }}</th>\n <th />\n <th>{{ i18n.t('import.field') }}</th>\n <th>{{ i18n.t('import.firstValue') }}</th>\n </tr>\n </thead>\n <tbody>\n <tr\n v-for=\"(h, i) in headers\"\n :key=\"i\"\n :class=\"{ 'is-skipped': i !== keyCol && (mapping[i] ?? '') === SKIP }\"\n >\n <td class=\"dt-import-col\" :title=\"h\">{{ h }}</td>\n <td><PhArrowRight :size=\"14\" aria-hidden=\"true\" /></td>\n <td>\n <template v-if=\"i === keyCol\">\n <span class=\"dt-mono\">{{ keyHeader }}</span>\n <span class=\"dt-import-muted\">{{ i18n.t('import.matchKey') }}</span>\n </template>\n <label v-else class=\"dt-select dt-import-field\">\n <select\n :value=\"mapping[i] ?? ''\"\n :aria-label=\"i18n.t('import.field')\"\n @change=\"mapping = { ...mapping, [i]: ($event.target as HTMLSelectElement).value }\"\n >\n <option value=\"\" disabled>{{ i18n.t('import.chooseField') }}</option>\n <option :value=\"SKIP\">{{ i18n.t('import.skip') }}</option>\n <option v-for=\"f in fields\" :key=\"f.id\" :value=\"f.id\" :disabled=\"!f.editable\">\n {{ f.def.header }}{{ f.editable ? '' : ` · ${i18n.t('sheet.readOnly.badge')}` }}\n </option>\n </select>\n </label>\n </td>\n <td class=\"dt-import-preview\">\n <template v-if=\"i === keyCol\">\n <span class=\"dt-mono\">{{ preview(i).raw }}</span>\n </template>\n <template v-else-if=\"preview(i).shown\">\n <span class=\"dt-import-muted\">{{ preview(i).raw }}</span>\n <PhArrowRight :size=\"12\" aria-hidden=\"true\" />\n <strong>{{ preview(i).shown }}</strong>\n </template>\n <span v-else :class=\"{ 'dt-import-muted': !mapping[i] || mapping[i] === SKIP }\">\n {{ preview(i).raw }}\n </span>\n </td>\n </tr>\n </tbody>\n </table>\n <div v-if=\"summary && keyCol !== null\" class=\"dt-import-summary\">\n <div class=\"dt-import-summary-line\">\n <PhInfo :size=\"16\" aria-hidden=\"true\" />\n <span>\n {{\n i18n.t('import.summary', {\n updates: summary.updates,\n news: summary.news.length,\n entity,\n key: keyHeader,\n })\n }}\n </span>\n <button\n v-if=\"summary.news.length\"\n type=\"button\"\n class=\"dt-link dt-import-link\"\n @click=\"showNew = !showNew\"\n >\n {{ i18n.t('import.seeNew', { key: keyHeader }) }}\n </button>\n </div>\n <div v-if=\"showNew\" class=\"dt-import-newlist dt-mono\">{{ summary.news.join(', ') }}</div>\n <label v-if=\"summary.news.length\" class=\"dt-check-row\">\n <input v-model=\"addNew\" type=\"checkbox\" class=\"dt-checkbox\" />\n {{ i18n.t('import.addNew', { count: summary.news.length, key: keyHeader }) }}\n </label>\n <p v-if=\"overLimit\" class=\"dt-import-warn\">\n <PhWarningCircle :size=\"14\" aria-hidden=\"true\" />\n {{ i18n.t('sheet.limitFile', { count: rowCount + summary.news.length, max: maxRows }) }}\n </p>\n </div>\n </template>\n <p v-if=\"failed && !workbook\" class=\"dt-import-error\" role=\"alert\">\n {{ i18n.t('import.failed') }}\n <template v-if=\"failReason\">· {{ failReason }}</template>\n </p>\n </div>\n <div class=\"dt-import-foot\">\n <DialogClose class=\"dt-btn\">{{ i18n.t('common.cancel') }}</DialogClose>\n <button type=\"button\" class=\"dt-btn dt-btn-primary\" :disabled=\"!canApply\" @click=\"apply\">\n {{ i18n.t('import.apply') }}\n </button>\n </div>\n </DialogContent>\n </DialogPortal>\n </DialogRoot>\n</template>\n","<script setup lang=\"ts\" generic=\"Row extends object\">\n// Import from Excel (07 §13, handoff 06 §11, T12-09/10/11): dosya yalnızca grid'i doldurur; Save'e kadar kaydedilmez.\n// Dosya (bırak/seç) → `parseFile` → sayfa · başlık satırı (otomatik, değiştirilebilir) · eşleşme anahtarı (eşlenmeden\n// Apply pasif) · sütun eşleme (otomatik tek/kesin, elle değiştirilebilir, boş kalan alınmaz, read-only pasif) · ilk değer\n// önizlemesi (1.650,00 → 1,650.00) · özet (listede/sunucuda olanlar günceller, yeni anahtarlar satır olur). Dosyadaki\n// boş hücre mevcut değeri silmez (Q3). `maxRows` aşılırsa Apply pasif.\nimport {\n PhArrowLeft,\n PhArrowRight,\n PhInfo,\n PhLock,\n PhTable,\n PhUploadSimple,\n PhWarningCircle,\n PhX,\n} from '@phosphor-icons/vue'\nimport {\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogOverlay,\n DialogPortal,\n DialogRoot,\n DialogTitle,\n} from 'reka-ui'\nimport { computed, ref, shallowRef, watch } from 'vue'\nimport { formatCell, type FormatEnv } from '../core/cells/format'\nimport { TYPE_SPECS } from '../core/cells/specs'\nimport { useDataTableContext } from '../core/plugin'\nimport type { ColumnDef } from '../types/columns'\nimport type { Plural } from '../types/core'\nimport type { ParsedWorkbook } from '../types/sheet'\nimport { cellText, detectHeaderRow, matchColumns } from './import/model'\nimport { inferDecimal, parseInput, type ParseEnv } from './parse'\n\nexport interface ImportRow<Row> {\n key: string\n values: Record<string, unknown>\n /** undefined: listede var; Row: sunucuda var (Update); null: yeni. */\n server?: Row | null\n}\nexport interface ImportPayload<Row> {\n rows: Array<ImportRow<Row>>\n addNew: boolean\n}\n\nconst props = defineProps<{\n parseFile: (file: File) => Promise<ParsedWorkbook>\n columns: Array<ColumnDef<Row>>\n keyColumn: string\n entity: Plural\n maxRows: number\n /** Şu anki satır sayısı (sınır için). */\n rowCount: number\n inList: (key: string) => boolean\n lookupKeys?: (keys: string[], ctx: { signal: AbortSignal }) => Promise<Record<string, Row | null>>\n parseEnv: (locale?: string) => ParseEnv\n fmtEnv: FormatEnv\n}>()\nconst emit = defineEmits<{ apply: [payload: ImportPayload<Row>] }>()\nconst open = defineModel<boolean>('open', { default: false })\nconst { i18n, locale } = useDataTableContext()\nconst SKIP = '__skip__'\n\nconst keyDef = computed(() => props.columns.find((c) => c.id === props.keyColumn))\nconst keyHeader = computed(() => keyDef.value?.header ?? props.keyColumn)\n/** Eşlenebilir alanlar: anahtar dışındaki sütunlar; düzenlenemeyenler listede pasif. */\nconst fields = computed(() =>\n props.columns\n .filter((c) => c.id !== props.keyColumn)\n .map((c) => ({ id: c.id as string, def: c, editable: !!c.editable })),\n)\n\nconst file = shallowRef<File | null>(null)\nconst workbook = shallowRef<ParsedWorkbook | null>(null)\nconst loading = ref(false)\nconst failed = ref(false)\n/** `parseFile`'ın fırlattığı sebep (uygulamanın metni); `import.failed` başlığının altında gösterilir. */\nconst failReason = ref('')\nconst sheetIndex = ref(0)\nconst headerRow = ref(0)\nconst mapping = ref<Record<number, string>>({})\nconst keyCol = ref<number | null>(null)\nconst addNew = ref(true)\nconst showNew = ref(false)\nconst dragging = ref(false)\nconst input = ref<HTMLInputElement | null>(null)\n\nconst rows = computed(() => workbook.value?.sheets[sheetIndex.value]?.rows ?? [])\nconst headers = computed(() => (rows.value[headerRow.value] ?? []).map(cellText))\nconst dataRows = computed(() =>\n rows.value.slice(headerRow.value + 1).filter((r) => (r ?? []).some((c) => cellText(c) !== '')),\n)\nconst headerOptions = computed(() => Math.min(rows.value.length, 20))\n\nconst rebuild = () => {\n const auto = matchColumns(headers.value, props.columns)\n const m: Record<number, string> = {}\n let key: number | null = null\n for (const [i, id] of Object.entries(auto)) {\n if (id === props.keyColumn) key = key ?? Number(i)\n else if (fields.value.find((f) => f.id === id)?.editable) m[Number(i)] = id\n }\n mapping.value = m\n keyCol.value = key\n showNew.value = false\n}\nconst load = async (f: File) => {\n file.value = f\n failed.value = false\n loading.value = true\n try {\n const wb = await props.parseFile(f)\n workbook.value = wb\n sheetIndex.value = 0\n headerRow.value = detectHeaderRow(wb.sheets[0]?.rows ?? [])\n rebuild()\n } catch (e) {\n workbook.value = null\n failed.value = true\n failReason.value = e instanceof Error ? e.message : ''\n } finally {\n loading.value = false\n }\n}\nwatch(sheetIndex, () => {\n headerRow.value = detectHeaderRow(rows.value)\n rebuild()\n})\nconst onHeaderRow = (n: number) => {\n headerRow.value = n\n rebuild()\n}\nconst onPick = (e: Event) => {\n const f = (e.target as HTMLInputElement).files?.[0]\n if (f) void load(f)\n ;(e.target as HTMLInputElement).value = ''\n}\nconst onDrop = (e: DragEvent) => {\n dragging.value = false\n const f = e.dataTransfer?.files?.[0]\n if (f) void load(f)\n}\nconst reset = () => {\n file.value = null\n workbook.value = null\n failed.value = false\n mapping.value = {}\n keyCol.value = null\n lookup.value = null\n}\nwatch(open, (o) => {\n if (!o) reset()\n})\n\n// Anahtarlar: listede olanlar güncellenir; olmayanlar `lookupKeys` ile sunucuda aranır (varsa Update, yoksa New).\nconst keyTexts = computed(() =>\n keyCol.value === null ? [] : dataRows.value.map((r) => cellText(r?.[keyCol.value!])).filter(Boolean),\n)\nconst lookup = shallowRef<Map<string, Row | null> | null>(null)\nlet ctl: AbortController | null = null\nwatch(keyTexts, async (keys) => {\n lookup.value = null\n ctl?.abort()\n const unknown = [...new Set(keys.filter((k) => !props.inList(k)))]\n if (!unknown.length || !props.lookupKeys) {\n lookup.value = new Map(unknown.map((k) => [k, null]))\n return\n }\n ctl = new AbortController()\n const map = new Map<string, Row | null>()\n try {\n for (let i = 0; i < unknown.length; i += 500) {\n const chunk = unknown.slice(i, i + 500)\n const res = await props.lookupKeys(chunk, { signal: ctl.signal })\n for (const k of chunk) map.set(k, res[k] ?? null)\n }\n lookup.value = map\n } catch {\n if (!ctl.signal.aborted) lookup.value = new Map(unknown.map((k) => [k, null]))\n }\n})\nconst summary = computed(() => {\n if (!keyTexts.value.length) return null\n const seen = new Set<string>()\n let inList = 0\n let server = 0\n const news: string[] = []\n for (const k of keyTexts.value) {\n if (seen.has(k)) continue\n seen.add(k)\n if (props.inList(k)) inList++\n else if (lookup.value?.get(k)) server++\n else news.push(k)\n }\n return { updates: inList + server, news, pending: lookup.value === null && !!props.lookupKeys }\n})\nconst overLimit = computed(() => {\n const s = summary.value\n return !!s && addNew.value && props.rowCount + s.news.length > props.maxRows\n})\nconst canApply = computed(\n () => !!workbook.value && keyCol.value !== null && !!summary.value && !summary.value.pending && !overLimit.value,\n)\n\n// Önizleme: ilk veri satırının ham değeri ve çözümlenmiş biçimi (sütun bazında ondalık çıkarımı, 07 §7).\nconst localeFor = (col: number, def: ColumnDef<Row>): string => {\n if (!TYPE_SPECS[def.type].numeric) return locale\n const dec = inferDecimal(dataRows.value.slice(0, 50).map((r) => cellText(r?.[col])))\n return dec === ',' ? 'de' : dec === '.' ? 'en' : locale\n}\nconst convert = (col: number, def: ColumnDef<Row>, raw: unknown): unknown => {\n if (typeof raw === 'number' || typeof raw === 'boolean') return raw\n if (raw instanceof Date) return cellText(raw)\n const text = cellText(raw)\n return text === '' ? null : parseInput(def, text, props.parseEnv(localeFor(col, def)))\n}\nconst preview = (col: number): { raw: string; shown: string | null } => {\n const row = dataRows.value[0]\n const raw = cellText(row?.[col])\n const id = mapping.value[col]\n const def = id ? props.columns.find((c) => c.id === id) : undefined\n if (!def || !raw) return { raw, shown: null }\n const value = convert(col, def, row?.[col])\n const shown = formatCell(def, {} as Row, value, props.fmtEnv)\n return { raw, shown: shown === raw ? null : shown }\n}\n\nconst apply = () => {\n if (!canApply.value || keyCol.value === null) return\n const out: Array<ImportRow<Row>> = []\n for (const r of dataRows.value) {\n const key = cellText(r?.[keyCol.value])\n if (!key) continue\n const values: Record<string, unknown> = {}\n for (const [col, id] of Object.entries(mapping.value)) {\n if (!id || id === SKIP) continue\n const def = props.columns.find((c) => c.id === id)\n const raw = r?.[Number(col)]\n if (!def || cellText(raw) === '') continue // boş hücre mevcut değeri silmez (Q3)\n values[id] = convert(Number(col), def, raw)\n }\n out.push({ key, values, server: props.inList(key) ? undefined : (lookup.value?.get(key) ?? null) })\n }\n emit('apply', { rows: out, addNew: addNew.value })\n open.value = false\n}\nconst sheetInfo = computed(() => {\n const s = workbook.value?.sheets[sheetIndex.value]\n return s ? i18n.t('import.sheetInfo', { sheet: s.name, count: dataRows.value.length }) : ''\n})\n</script>\n\n<template>\n <DialogRoot v-model:open=\"open\">\n <DialogPortal>\n <DialogOverlay class=\"dt-scrim\" />\n <DialogContent class=\"dt-dialog dt-import\">\n <div class=\"dt-import-head\">\n <div>\n <DialogTitle class=\"dt-dialog-title\">{{ i18n.t('import.title') }}</DialogTitle>\n <DialogDescription class=\"dt-dialog-body\">\n {{ i18n.t('import.body', { key: keyHeader, entity }) }}\n </DialogDescription>\n </div>\n <DialogClose class=\"dt-btn dt-btn-icon dt-btn-ghost\" :aria-label=\"i18n.t('common.close')\">\n <PhX :size=\"16\" aria-hidden=\"true\" />\n </DialogClose>\n </div>\n <div class=\"dt-import-body\">\n <input ref=\"input\" type=\"file\" class=\"dt-sr-only\" accept=\".xlsx,.xls,.csv\" tabindex=\"-1\" @change=\"onPick\" />\n <button\n v-if=\"!workbook\"\n type=\"button\"\n class=\"dt-import-drop\"\n :class=\"{ 'is-over': dragging, 'is-failed': failed }\"\n :aria-busy=\"loading ? 'true' : undefined\"\n @click=\"input?.click()\"\n @dragover.prevent=\"dragging = true\"\n @dragleave=\"dragging = false\"\n @drop.prevent=\"onDrop\"\n >\n <span class=\"dt-import-drop-icon\"><PhUploadSimple :size=\"20\" aria-hidden=\"true\" /></span>\n <span>{{ i18n.t('import.drop') }}</span>\n </button>\n <template v-else>\n <div class=\"dt-import-file\">\n <span class=\"dt-import-file-icon\"><PhTable :size=\"18\" aria-hidden=\"true\" /></span>\n <span class=\"dt-import-file-text\">\n <strong>{{ file?.name }}</strong>\n <label v-if=\"workbook.sheets.length > 1\" class=\"dt-select dt-import-sheet\">\n <select v-model=\"sheetIndex\" :aria-label=\"i18n.t('import.sheetInfo', { sheet: '', count: 0 })\">\n <option v-for=\"(s, i) in workbook.sheets\" :key=\"i\" :value=\"i\">\n {{ i18n.t('import.sheetInfo', { sheet: s.name, count: s.rows.length }) }}\n </option>\n </select>\n </label>\n <span v-else class=\"dt-import-sheet-info\">{{ sheetInfo }}</span>\n </span>\n <button type=\"button\" class=\"dt-btn dt-btn-sm\" @click=\"input?.click()\">\n {{ i18n.t('import.replace') }}\n </button>\n </div>\n <div class=\"dt-import-match\">\n <span class=\"dt-import-match-label\">{{ i18n.t('import.matchBy') }}</span>\n <span class=\"dt-import-key\">\n <PhLock :size=\"12\" aria-hidden=\"true\" />\n <span class=\"dt-mono\">{{ keyHeader }}</span>\n </span>\n <PhArrowLeft :size=\"14\" aria-hidden=\"true\" />\n <label class=\"dt-select dt-import-keysel\" :class=\"{ 'is-missing': keyCol === null }\">\n <select\n :value=\"keyCol ?? ''\"\n :aria-label=\"i18n.t('import.excelColumn')\"\n @change=\"\n keyCol =\n ($event.target as HTMLSelectElement).value === ''\n ? null\n : Number(($event.target as HTMLSelectElement).value)\n \"\n >\n <option value=\"\">{{ i18n.t('import.excelColumn') }}</option>\n <option v-for=\"(h, i) in headers\" :key=\"i\" :value=\"i\" :disabled=\"!h\">{{ h }}</option>\n </select>\n </label>\n <span class=\"dt-import-spacer\" />\n <label class=\"dt-select dt-import-headerrow\">\n <span class=\"dt-import-match-label\">{{ i18n.t('import.headerRow') }}</span>\n <select :value=\"headerRow\" @change=\"onHeaderRow(Number(($event.target as HTMLSelectElement).value))\">\n <option v-for=\"n in headerOptions\" :key=\"n\" :value=\"n - 1\">\n {{ i18n.t('import.headerRowN', { n }) }}\n </option>\n </select>\n </label>\n </div>\n <p v-if=\"keyCol === null\" class=\"dt-import-warn\">\n <PhWarningCircle :size=\"14\" aria-hidden=\"true\" />\n {{ i18n.t('import.keyRequired', { key: keyHeader }) }}\n </p>\n <table class=\"dt-import-table\">\n <colgroup>\n <col class=\"dt-import-col-excel\" />\n <col class=\"dt-import-col-arrow\" />\n <col class=\"dt-import-col-field\" />\n <col />\n </colgroup>\n <thead>\n <tr>\n <th>{{ i18n.t('import.excelColumn') }}</th>\n <th />\n <th>{{ i18n.t('import.field') }}</th>\n <th>{{ i18n.t('import.firstValue') }}</th>\n </tr>\n </thead>\n <tbody>\n <tr\n v-for=\"(h, i) in headers\"\n :key=\"i\"\n :class=\"{ 'is-skipped': i !== keyCol && (mapping[i] ?? '') === SKIP }\"\n >\n <td class=\"dt-import-col\" :title=\"h\">{{ h }}</td>\n <td><PhArrowRight :size=\"14\" aria-hidden=\"true\" /></td>\n <td>\n <template v-if=\"i === keyCol\">\n <span class=\"dt-mono\">{{ keyHeader }}</span>\n <span class=\"dt-import-muted\">{{ i18n.t('import.matchKey') }}</span>\n </template>\n <label v-else class=\"dt-select dt-import-field\">\n <select\n :value=\"mapping[i] ?? ''\"\n :aria-label=\"i18n.t('import.field')\"\n @change=\"mapping = { ...mapping, [i]: ($event.target as HTMLSelectElement).value }\"\n >\n <option value=\"\" disabled>{{ i18n.t('import.chooseField') }}</option>\n <option :value=\"SKIP\">{{ i18n.t('import.skip') }}</option>\n <option v-for=\"f in fields\" :key=\"f.id\" :value=\"f.id\" :disabled=\"!f.editable\">\n {{ f.def.header }}{{ f.editable ? '' : ` · ${i18n.t('sheet.readOnly.badge')}` }}\n </option>\n </select>\n </label>\n </td>\n <td class=\"dt-import-preview\">\n <template v-if=\"i === keyCol\">\n <span class=\"dt-mono\">{{ preview(i).raw }}</span>\n </template>\n <template v-else-if=\"preview(i).shown\">\n <span class=\"dt-import-muted\">{{ preview(i).raw }}</span>\n <PhArrowRight :size=\"12\" aria-hidden=\"true\" />\n <strong>{{ preview(i).shown }}</strong>\n </template>\n <span v-else :class=\"{ 'dt-import-muted': !mapping[i] || mapping[i] === SKIP }\">\n {{ preview(i).raw }}\n </span>\n </td>\n </tr>\n </tbody>\n </table>\n <div v-if=\"summary && keyCol !== null\" class=\"dt-import-summary\">\n <div class=\"dt-import-summary-line\">\n <PhInfo :size=\"16\" aria-hidden=\"true\" />\n <span>\n {{\n i18n.t('import.summary', {\n updates: summary.updates,\n news: summary.news.length,\n entity,\n key: keyHeader,\n })\n }}\n </span>\n <button\n v-if=\"summary.news.length\"\n type=\"button\"\n class=\"dt-link dt-import-link\"\n @click=\"showNew = !showNew\"\n >\n {{ i18n.t('import.seeNew', { key: keyHeader }) }}\n </button>\n </div>\n <div v-if=\"showNew\" class=\"dt-import-newlist dt-mono\">{{ summary.news.join(', ') }}</div>\n <label v-if=\"summary.news.length\" class=\"dt-check-row\">\n <input v-model=\"addNew\" type=\"checkbox\" class=\"dt-checkbox\" />\n {{ i18n.t('import.addNew', { count: summary.news.length, key: keyHeader }) }}\n </label>\n <p v-if=\"overLimit\" class=\"dt-import-warn\">\n <PhWarningCircle :size=\"14\" aria-hidden=\"true\" />\n {{ i18n.t('sheet.limitFile', { count: rowCount + summary.news.length, max: maxRows }) }}\n </p>\n </div>\n </template>\n <p v-if=\"failed && !workbook\" class=\"dt-import-error\" role=\"alert\">\n {{ i18n.t('import.failed') }}\n <template v-if=\"failReason\">· {{ failReason }}</template>\n </p>\n </div>\n <div class=\"dt-import-foot\">\n <DialogClose class=\"dt-btn\">{{ i18n.t('common.cancel') }}</DialogClose>\n <button type=\"button\" class=\"dt-btn dt-btn-primary\" :disabled=\"!canApply\" @click=\"apply\">\n {{ i18n.t('import.apply') }}\n </button>\n </div>\n </DialogContent>\n </DialogPortal>\n </DialogRoot>\n</template>\n","<script setup lang=\"ts\">\n// \"Save with errors\" dialog'u (07 §14, handoff 06 §10, T12-01): hatalı satırlar gönderilmez; Fix first (ilk odak)\n// Errors görünümüne geçip ilk hataya gider, \"Save N rows\" kalanını teslim eder. `alertdialog`, 480 px.\nimport { PhWarningCircle } from '@phosphor-icons/vue'\nimport {\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogOverlay,\n AlertDialogPortal,\n AlertDialogRoot,\n AlertDialogTitle,\n} from 'reka-ui'\nimport { useDataTableContext } from '../core/plugin'\n\nexport interface ErrorRowItem {\n rowNo: number\n key: string\n message: string\n}\ndefineProps<{\n /** Hatalı satırlar (gutter sırasıyla). */\n errors: ErrorRowItem[]\n /** Gönderilecek satır sayısı. */\n okRows: number\n}>()\nconst emit = defineEmits<{ fix: []; save: [] }>()\nconst open = defineModel<boolean>('open', { default: false })\nconst { i18n } = useDataTableContext()\nconst save = () => {\n emit('save')\n open.value = false\n}\n</script>\n\n<template>\n <AlertDialogRoot v-model:open=\"open\">\n <AlertDialogPortal>\n <AlertDialogOverlay class=\"dt-scrim\" />\n <AlertDialogContent class=\"dt-dialog dt-dialog-errors\">\n <AlertDialogTitle class=\"dt-dialog-title\">\n {{ i18n.t('sheet.errDialog.title', { count: errors.length }) }}\n </AlertDialogTitle>\n <AlertDialogDescription class=\"dt-dialog-body\">\n {{ i18n.t('sheet.errDialog.body', { count: okRows }) }}\n </AlertDialogDescription>\n <ul class=\"dt-error-list\">\n <li v-for=\"e in errors.slice(0, 8)\" :key=\"e.rowNo\" class=\"dt-error-row\">\n <PhWarningCircle :size=\"14\" aria-hidden=\"true\" />\n <span class=\"dt-error-no\">{{ e.rowNo }}</span>\n <span class=\"dt-mono\">{{ e.key }}</span>\n <span class=\"dt-error-msg\">{{ e.message }}</span>\n </li>\n </ul>\n <div class=\"dt-dialog-actions\">\n <AlertDialogCancel class=\"dt-btn\" @click=\"emit('fix')\">{{ i18n.t('sheet.errDialog.fix') }}</AlertDialogCancel>\n <button type=\"button\" class=\"dt-btn dt-btn-primary\" :disabled=\"!okRows\" @click=\"save\">\n {{ i18n.t('sheet.errDialog.save', { count: okRows }) }}\n </button>\n </div>\n </AlertDialogContent>\n </AlertDialogPortal>\n </AlertDialogRoot>\n</template>\n","<script setup lang=\"ts\">\n// \"Save with errors\" dialog'u (07 §14, handoff 06 §10, T12-01): hatalı satırlar gönderilmez; Fix first (ilk odak)\n// Errors görünümüne geçip ilk hataya gider, \"Save N rows\" kalanını teslim eder. `alertdialog`, 480 px.\nimport { PhWarningCircle } from '@phosphor-icons/vue'\nimport {\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogOverlay,\n AlertDialogPortal,\n AlertDialogRoot,\n AlertDialogTitle,\n} from 'reka-ui'\nimport { useDataTableContext } from '../core/plugin'\n\nexport interface ErrorRowItem {\n rowNo: number\n key: string\n message: string\n}\ndefineProps<{\n /** Hatalı satırlar (gutter sırasıyla). */\n errors: ErrorRowItem[]\n /** Gönderilecek satır sayısı. */\n okRows: number\n}>()\nconst emit = defineEmits<{ fix: []; save: [] }>()\nconst open = defineModel<boolean>('open', { default: false })\nconst { i18n } = useDataTableContext()\nconst save = () => {\n emit('save')\n open.value = false\n}\n</script>\n\n<template>\n <AlertDialogRoot v-model:open=\"open\">\n <AlertDialogPortal>\n <AlertDialogOverlay class=\"dt-scrim\" />\n <AlertDialogContent class=\"dt-dialog dt-dialog-errors\">\n <AlertDialogTitle class=\"dt-dialog-title\">\n {{ i18n.t('sheet.errDialog.title', { count: errors.length }) }}\n </AlertDialogTitle>\n <AlertDialogDescription class=\"dt-dialog-body\">\n {{ i18n.t('sheet.errDialog.body', { count: okRows }) }}\n </AlertDialogDescription>\n <ul class=\"dt-error-list\">\n <li v-for=\"e in errors.slice(0, 8)\" :key=\"e.rowNo\" class=\"dt-error-row\">\n <PhWarningCircle :size=\"14\" aria-hidden=\"true\" />\n <span class=\"dt-error-no\">{{ e.rowNo }}</span>\n <span class=\"dt-mono\">{{ e.key }}</span>\n <span class=\"dt-error-msg\">{{ e.message }}</span>\n </li>\n </ul>\n <div class=\"dt-dialog-actions\">\n <AlertDialogCancel class=\"dt-btn\" @click=\"emit('fix')\">{{ i18n.t('sheet.errDialog.fix') }}</AlertDialogCancel>\n <button type=\"button\" class=\"dt-btn dt-btn-primary\" :disabled=\"!okRows\" @click=\"save\">\n {{ i18n.t('sheet.errDialog.save', { count: okRows }) }}\n </button>\n </div>\n </AlertDialogContent>\n </AlertDialogPortal>\n </AlertDialogRoot>\n</template>\n","<script setup lang=\"ts\">\n// Hücre menüsü (07 §9, T11-03, 236 px): sağ tıklanan noktada (reka ContextMenu; kök ızgara tetikleyici). Cut · Copy ·\n// Paste · Fill down · Clear · ─ · Insert row above / below · Remove from list (⌘−, nötr, D12) · ─ · Open {entity}\n// (yalnızca sunucuda var olan satırlar, yeni sekmede). Kısayollar mono.\nimport { ContextMenuContent, ContextMenuItem, ContextMenuPortal, ContextMenuSeparator } from 'reka-ui'\nimport { FILL_KBD, REMOVE_KBD, mac } from '../core/interaction/kbd'\nimport { useDataTableContext } from '../core/plugin'\nimport type { Plural } from '../types/core'\nimport type { SheetApi } from './useSheetEditing'\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyRow = any\ndefineProps<{\n sheet: SheetApi<AnyRow>\n entity: Plural\n href?: string\n /** Kaydederken ve salt okunurken yazan öğeler pasif. */\n readOnly: boolean\n}>()\nconst { i18n } = useDataTableContext()\nconst K = { cut: mac ? '⌘X' : 'Ctrl+X', copy: mac ? '⌘C' : 'Ctrl+C', paste: mac ? '⌘V' : 'Ctrl+V', clear: 'Del' }\n</script>\n\n<template>\n <ContextMenuPortal>\n <ContextMenuContent class=\"dt-menu dt-sheet-menu\">\n <ContextMenuItem class=\"dt-menu-item\" :disabled=\"readOnly\" @select=\"sheet.copyToClipboard(true)\">\n {{ i18n.t('sheet.menu.cut') }}\n <kbd class=\"dt-kbd\">{{ K.cut }}</kbd>\n </ContextMenuItem>\n <ContextMenuItem class=\"dt-menu-item\" @select=\"sheet.copyToClipboard(false)\">\n {{ i18n.t('sheet.menu.copy') }}\n <kbd class=\"dt-kbd\">{{ K.copy }}</kbd>\n </ContextMenuItem>\n <ContextMenuItem class=\"dt-menu-item\" :disabled=\"readOnly\" @select=\"sheet.pasteFromClipboard()\">\n {{ i18n.t('sheet.menu.paste') }}\n <kbd class=\"dt-kbd\">{{ K.paste }}</kbd>\n </ContextMenuItem>\n <ContextMenuItem class=\"dt-menu-item\" :disabled=\"readOnly\" @select=\"sheet.fillDown()\">\n {{ i18n.t('sheet.menu.fillDown') }}\n <kbd class=\"dt-kbd\">{{ FILL_KBD }}</kbd>\n </ContextMenuItem>\n <ContextMenuItem class=\"dt-menu-item\" :disabled=\"readOnly\" @select=\"sheet.clearCells()\">\n {{ i18n.t('sheet.menu.clear') }}\n <kbd class=\"dt-kbd\">{{ K.clear }}</kbd>\n </ContextMenuItem>\n <ContextMenuSeparator class=\"dt-menu-sep\" />\n <ContextMenuItem class=\"dt-menu-item\" :disabled=\"readOnly\" @select=\"sheet.insertRow('above')\">\n {{ i18n.t('sheet.menu.insertAbove') }}\n </ContextMenuItem>\n <ContextMenuItem class=\"dt-menu-item\" :disabled=\"readOnly\" @select=\"sheet.insertRow('below')\">\n {{ i18n.t('sheet.menu.insertBelow') }}\n </ContextMenuItem>\n <ContextMenuItem class=\"dt-menu-item\" :disabled=\"readOnly\" @select=\"sheet.removeSelectedRows()\">\n {{ i18n.t('sheet.menu.remove') }}\n <kbd class=\"dt-kbd\">{{ REMOVE_KBD }}</kbd>\n </ContextMenuItem>\n <template v-if=\"href\">\n <ContextMenuSeparator class=\"dt-menu-sep\" />\n <ContextMenuItem as-child class=\"dt-menu-item\">\n <a :href=\"href\" target=\"_blank\" rel=\"noopener\">{{ i18n.t('sheet.menu.open', { entity }) }}</a>\n </ContextMenuItem>\n </template>\n </ContextMenuContent>\n </ContextMenuPortal>\n</template>\n","<script setup lang=\"ts\">\n// Hücre menüsü (07 §9, T11-03, 236 px): sağ tıklanan noktada (reka ContextMenu; kök ızgara tetikleyici). Cut · Copy ·\n// Paste · Fill down · Clear · ─ · Insert row above / below · Remove from list (⌘−, nötr, D12) · ─ · Open {entity}\n// (yalnızca sunucuda var olan satırlar, yeni sekmede). Kısayollar mono.\nimport { ContextMenuContent, ContextMenuItem, ContextMenuPortal, ContextMenuSeparator } from 'reka-ui'\nimport { FILL_KBD, REMOVE_KBD, mac } from '../core/interaction/kbd'\nimport { useDataTableContext } from '../core/plugin'\nimport type { Plural } from '../types/core'\nimport type { SheetApi } from './useSheetEditing'\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyRow = any\ndefineProps<{\n sheet: SheetApi<AnyRow>\n entity: Plural\n href?: string\n /** Kaydederken ve salt okunurken yazan öğeler pasif. */\n readOnly: boolean\n}>()\nconst { i18n } = useDataTableContext()\nconst K = { cut: mac ? '⌘X' : 'Ctrl+X', copy: mac ? '⌘C' : 'Ctrl+C', paste: mac ? '⌘V' : 'Ctrl+V', clear: 'Del' }\n</script>\n\n<template>\n <ContextMenuPortal>\n <ContextMenuContent class=\"dt-menu dt-sheet-menu\">\n <ContextMenuItem class=\"dt-menu-item\" :disabled=\"readOnly\" @select=\"sheet.copyToClipboard(true)\">\n {{ i18n.t('sheet.menu.cut') }}\n <kbd class=\"dt-kbd\">{{ K.cut }}</kbd>\n </ContextMenuItem>\n <ContextMenuItem class=\"dt-menu-item\" @select=\"sheet.copyToClipboard(false)\">\n {{ i18n.t('sheet.menu.copy') }}\n <kbd class=\"dt-kbd\">{{ K.copy }}</kbd>\n </ContextMenuItem>\n <ContextMenuItem class=\"dt-menu-item\" :disabled=\"readOnly\" @select=\"sheet.pasteFromClipboard()\">\n {{ i18n.t('sheet.menu.paste') }}\n <kbd class=\"dt-kbd\">{{ K.paste }}</kbd>\n </ContextMenuItem>\n <ContextMenuItem class=\"dt-menu-item\" :disabled=\"readOnly\" @select=\"sheet.fillDown()\">\n {{ i18n.t('sheet.menu.fillDown') }}\n <kbd class=\"dt-kbd\">{{ FILL_KBD }}</kbd>\n </ContextMenuItem>\n <ContextMenuItem class=\"dt-menu-item\" :disabled=\"readOnly\" @select=\"sheet.clearCells()\">\n {{ i18n.t('sheet.menu.clear') }}\n <kbd class=\"dt-kbd\">{{ K.clear }}</kbd>\n </ContextMenuItem>\n <ContextMenuSeparator class=\"dt-menu-sep\" />\n <ContextMenuItem class=\"dt-menu-item\" :disabled=\"readOnly\" @select=\"sheet.insertRow('above')\">\n {{ i18n.t('sheet.menu.insertAbove') }}\n </ContextMenuItem>\n <ContextMenuItem class=\"dt-menu-item\" :disabled=\"readOnly\" @select=\"sheet.insertRow('below')\">\n {{ i18n.t('sheet.menu.insertBelow') }}\n </ContextMenuItem>\n <ContextMenuItem class=\"dt-menu-item\" :disabled=\"readOnly\" @select=\"sheet.removeSelectedRows()\">\n {{ i18n.t('sheet.menu.remove') }}\n <kbd class=\"dt-kbd\">{{ REMOVE_KBD }}</kbd>\n </ContextMenuItem>\n <template v-if=\"href\">\n <ContextMenuSeparator class=\"dt-menu-sep\" />\n <ContextMenuItem as-child class=\"dt-menu-item\">\n <a :href=\"href\" target=\"_blank\" rel=\"noopener\">{{ i18n.t('sheet.menu.open', { entity }) }}</a>\n </ContextMenuItem>\n </template>\n </ContextMenuContent>\n </ContextMenuPortal>\n</template>\n","// Sheet satırı + hücreler (07 §3–4, handoff 06 §5): render fonksiyonu (sanal listede yüzlerce örnek). Gutter (56 px,\n// satır no + işaret), hücre durumları (editable / read-only / active / in selection / editing / changed / error / warning /\n// required / new / fill target / match), editör hücrenin yerinde. Satırın taslak ve hata Map'leri prop'tur: yalnızca\n// değişen satır yeniden çizilir.\nimport { PhCircleNotch, PhLock, PhPlus, PhWarningCircle } from '@phosphor-icons/vue'\nimport { defineComponent, h, type Component, type PropType, type VNodeChild } from 'vue'\nimport { formatCell, isEmptyValue } from '../core/cells/format'\nimport { cellFillStyle, renderCellContent, type RenderEnv } from '../core/cells/renderCell'\nimport { alignOf, isNumericType } from '../core/cells/specs'\nimport type { LayoutColumn } from '../core/columns/useColumnLayout'\nimport { withFill } from '../core/grid/Row'\nimport type { ColumnDef } from '../types/columns'\nimport { inputText } from './parse'\nimport type { Issue, KeyState } from './useSheetStore'\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- satır tipi DataSheet'te; accessor parametreleri karşıt değişken\ntype AnyRow = any\n\n/** Bu satırdaki seçili sütun dizini aralığı ve dış kenarlar (aralık > 1 hücre olduğunda). */\nexport interface RowSelection {\n from: number\n to: number\n top: boolean\n bottom: boolean\n}\n/** Doldurma hedefi: sütun dizini aralığı; `last` son hedef satır (alt kenar). */\nexport interface RowFill {\n from: number\n to: number\n last: boolean\n}\nexport interface CellEditing {\n columnId: string\n value: unknown\n /** false: formül çubuğundan düzenleniyor; hücre editör açmaz, taslağı gösterir. */\n inCell: boolean\n}\n\n/** Sheet'te hücre içinde link yok (07 §9: \"Open product\" hücre menüsünde); `id`/`ajax` tipinin `href`'i çizimde düşer. */\nconst plainDefs = new WeakMap<ColumnDef<AnyRow>, ColumnDef<AnyRow>>()\nconst plain = (def: ColumnDef<AnyRow>): ColumnDef<AnyRow> => {\n if (!def.href) return def\n let p = plainDefs.get(def)\n if (!p) plainDefs.set(def, (p = { ...def, href: undefined }))\n return p\n}\n\nexport default defineComponent({\n name: 'DtSheetRow',\n props: {\n row: { type: Object as PropType<object>, required: true },\n index: { type: Number, required: true },\n /** Kararlı satır numarası (yükleme sırası, 07 §3). */\n rowNo: { type: Number, required: true },\n columns: { type: Array as PropType<Array<LayoutColumn<AnyRow>>>, required: true },\n env: { type: Object as PropType<RenderEnv>, required: true },\n keyColumn: { type: String, required: true },\n read: { type: Function as PropType<(row: AnyRow, def: ColumnDef<AnyRow>) => unknown>, required: true },\n original: { type: Function as PropType<(row: AnyRow, def: ColumnDef<AnyRow>) => unknown>, required: true },\n canEdit: { type: Function as PropType<(row: AnyRow, def: ColumnDef<AnyRow>) => boolean>, required: true },\n /** Satırın taslak hali: editör (`optionEnabled`) `editable` ve doğrulayıcılarla aynı güncel satırı görür. */\n current: { type: Function as PropType<(row: AnyRow) => AnyRow>, required: true },\n editorFor: { type: Function as PropType<(def: ColumnDef<AnyRow>) => Component | null>, required: true },\n draft: { type: Map as PropType<Map<string, unknown>>, default: undefined },\n issues: { type: Map as PropType<Map<string, Issue>>, default: undefined },\n /** Yeni satır (07 §9): gutter'da `+`, anahtar hücresinde New / Update / kontrol spinner'ı. */\n isNew: { type: Boolean, default: false },\n keyState: { type: String as PropType<KeyState | undefined>, default: undefined },\n /** Sunucu satır hatası (07 §14): anahtar hücresinde ve gutter ipucunda. */\n rowError: { type: String as PropType<string | undefined>, default: undefined },\n /** Aktif hücrenin sütun id'si (roving tabindex 0). */\n active: { type: String as PropType<string | null>, default: null },\n selection: { type: Object as PropType<RowSelection | null>, default: null },\n /** Fill handle'ın çizildiği hücre (tek hücrede aktif, aralıkta sağ alt köşe). */\n handleAt: { type: String as PropType<string | null>, default: null },\n fill: { type: Object as PropType<RowFill | null>, default: null },\n /** Find in grid eşleşen sütunlar. */\n found: { type: Set as PropType<Set<string>>, default: undefined },\n editing: { type: Object as PropType<CellEditing | null>, default: null },\n /** Hata balonu ilk satırda hücrenin altında (üstte header'ın altında kalırdı). */\n tipBelow: { type: Boolean, default: false },\n /** Telefonda gutter yok (07 §17). */\n gutter: { type: Boolean, default: true },\n /** Hata balonu id'leri için örnek öneki (`aria-describedby`, 08 §5). */\n uid: { type: String, default: 'dt' },\n style: { type: Object as PropType<Record<string, string>>, default: undefined },\n },\n emits: ['edit-value', 'use-suggestion'],\n setup(props, { emit }) {\n const t = (key: string, params?: Record<string, string | number>) => props.env.i18n.t(key, params)\n\n const renderCell = (col: LayoutColumn<AnyRow>, i: number): VNodeChild => {\n const def = col.def\n const id = col.id\n const value = props.read(props.row, def)\n const editable = props.canEdit(props.row, def)\n const issue = props.issues?.get(id)\n const changed = props.draft?.has(id) ?? false\n const isActive = props.active === id\n const sel = props.selection\n const inSel = !!sel && i >= sel.from && i <= sel.to\n const fill = props.fill\n const inFill = !!fill && i >= fill.from && i <= fill.to\n const ed = props.editing?.columnId === id ? props.editing : null\n const isKey = id === props.keyColumn\n\n let content: VNodeChild\n if (ed?.inCell) {\n const Editor = props.editorFor(def)!\n content = h(Editor, {\n modelValue: ed.value,\n row: props.current(props.row),\n column: def,\n 'onUpdate:modelValue': (v: unknown) => emit('edit-value', v),\n })\n } else if (ed) content = h('span', { class: 'dt-cell-content' }, inputText(def, ed.value))\n else if (issue?.level === 'error' && isEmptyValue(value) && issue.message === t('sheet.required'))\n content = h('span', { class: 'dt-cell-content dt-cell-required' }, issue.message)\n else\n content = h('span', { class: 'dt-cell-content' }, [renderCellContent(plain(def), props.row, value, props.env)])\n\n const children: VNodeChild[] = [content]\n if (isKey && props.isNew && !ed)\n children.push(\n props.keyState === 'checking'\n ? h(PhCircleNotch, {\n size: 12,\n class: 'dt-tag-spin dt-spin',\n role: 'img',\n 'aria-label': t('common.loading'),\n })\n : h(\n 'span',\n { class: ['dt-tag-new', { 'is-update': props.keyState === 'update' }] },\n t(props.keyState === 'update' ? 'sheet.tag.update' : 'sheet.tag.new'),\n ),\n )\n if (isKey && props.rowError && !ed)\n children.push(h('span', { class: 'dt-cell-tip is-error', role: 'tooltip' }, props.rowError))\n if (!editable && !isKey)\n children.push(\n h(PhLock, { size: 12, class: 'dt-cell-lock', role: 'img', 'aria-label': t('sheet.readOnly.badge') }),\n )\n const tipId = issue ? `${props.uid}-${props.rowNo}-${i}` : undefined\n if (issue)\n children.push(\n h('span', { id: tipId, class: ['dt-cell-tip', `is-${issue.level}`], role: 'tooltip' }, [\n issue.message,\n issue.suggest\n ? h(\n 'button',\n {\n type: 'button',\n class: 'dt-cell-tip-btn',\n tabindex: -1,\n onClick: () => emit('use-suggestion', def, issue.suggest!.value),\n },\n t('sheet.useOption', { option: issue.suggest.label }),\n )\n : null,\n ]),\n )\n if (props.handleAt === id && !ed) children.push(h('span', { class: 'dt-fill-handle', 'aria-hidden': 'true' }))\n\n return h(\n 'div',\n {\n class: [\n 'dt-cell',\n `is-${alignOf(def)}`,\n {\n 'is-numeric': isNumericType(def.type),\n 'is-key': isKey,\n 'is-new': isKey && props.isNew,\n 'is-readonly': !editable,\n 'is-active': isActive,\n 'is-selected': inSel,\n 'is-edge-l': inSel && i === sel!.from,\n 'is-edge-r': inSel && i === sel!.to,\n 'is-edge-t': inSel && sel!.top,\n 'is-edge-b': inSel && sel!.bottom,\n 'is-fill': inFill,\n 'is-fill-end': inFill && fill!.last,\n 'is-match': props.found?.has(id) ?? false,\n 'is-editing': !!ed,\n 'is-changed': changed,\n 'is-error': issue?.level === 'error' || (isKey && !!props.rowError),\n 'is-warning': issue?.level === 'warning',\n 'is-tip-below': props.tipBelow,\n 'is-pinned-start': col.pinned === 'start',\n 'is-pinned-end': col.pinned === 'end',\n 'is-pin-edge': col.pinEdge,\n },\n ],\n style: {\n ...(col.pinned === 'start'\n ? { left: `var(${col.offsetVar})` }\n : col.pinned === 'end'\n ? { right: `var(${col.offsetVar})` }\n : null),\n ...cellFillStyle(def, value),\n },\n role: 'gridcell',\n tabindex: isActive ? 0 : -1,\n 'aria-readonly': editable ? undefined : 'true',\n 'aria-selected': inSel ? 'true' : undefined,\n 'aria-describedby': tipId,\n 'aria-invalid': issue?.level === 'error' ? 'true' : undefined,\n 'data-col': id,\n // Öncelik Error > Warning > Changed (07 §4): hata/uyarı balonu varken \"Was …\" ipucu yok; yeni satırda orijinal yok.\n 'data-dt-tip':\n changed && !issue && !ed && !props.isNew\n ? t('sheet.was', { value: formatCell(def, props.row, props.original(props.row, def), props.env) })\n : undefined,\n },\n children,\n )\n }\n\n const gutter = () => {\n let hasError = !!props.rowError\n for (const i of props.issues?.values() ?? []) if (i.level === 'error') hasError = true\n const changed = !!props.draft?.size\n return h(\n 'div',\n {\n class: ['dt-cell', 'dt-gutter', 'is-pinned-start'],\n style: { left: '0px' },\n role: 'rowheader',\n 'data-dt-tip': props.rowError,\n },\n [\n hasError\n ? h(PhWarningCircle, {\n size: 13,\n class: 'dt-mark is-error',\n role: 'img',\n 'aria-label': t('sheet.hasErrors'),\n })\n : props.isNew\n ? h(PhPlus, { size: 13, class: 'dt-mark is-new', role: 'img', 'aria-label': t('sheet.tag.new') })\n : changed\n ? h('span', { class: 'dt-mark is-changed', role: 'img', 'aria-label': t('sheet.changed') })\n : null,\n h('span', { class: 'dt-gutter-no' }, String(props.rowNo)),\n ],\n )\n }\n\n return () => {\n const index = new Map(props.columns.map((c, i) => [c.id, i]))\n return h(\n 'div',\n {\n class: ['dt-row', { 'is-active-row': props.active !== null }],\n role: 'row',\n 'aria-rowindex': props.index + 2,\n 'data-index': props.index,\n style: props.style,\n },\n [props.gutter ? gutter() : null, ...withFill(props.columns, (col) => renderCell(col, index.get(col.id)!))],\n )\n }\n },\n})\n","<script setup lang=\"ts\">\n// Sheet ızgarası (07 §2–10, 08 §2 sheet, handoff 06 §5): tek kayan alan, sticky header (yerel sıralama oku), gutter\n// (56 px) + sola sabit sütunlar, sanal satırlar (aktif satır DOM'da kalır); hücre odaklı klavye (roving tabindex = aktif\n// hücre), fare ile hücre / aralık seçimi (TanStack handler'ları, gutter = satır, kenarda otomatik kaydırma), fill handle\n// sürükleme, pano olayları, hücre menüsü (sağ tık / ⇧F10), düzenleme başlatma ve onaylama kuralları. Veri, seçim ve\n// düzenleme durumu `sheet` nesnesinden (DataSheet kurar); bu dosya yalnızca DOM, odak ve kaydırmayı yönetir.\nimport { PhArrowUp, PhLock } from '@phosphor-icons/vue'\nimport { useVirtualizer } from '@tanstack/vue-virtual'\nimport { ContextMenuRoot, ContextMenuTrigger } from 'reka-ui'\nimport { computed, nextTick, onBeforeUnmount, onMounted, ref, shallowRef, useId, watch, watchEffect } from 'vue'\nimport { RemoteLabels } from '../core/cells/remoteLabels'\nimport type { RenderEnv } from '../core/cells/renderCell'\nimport { alignOf, isNumericType } from '../core/cells/specs'\nimport type { ColumnLayoutApi, LayoutColumn } from '../core/columns/useColumnLayout'\nimport { getFormat } from '../core/format'\nimport SkeletonRow from '../core/grid/SkeletonRow'\nimport { INTERACTIVE_SELECTOR, isInteractive, isTextInput } from '../core/interaction/isInteractive'\nimport { useDataTableContext } from '../core/plugin'\nimport type { ColumnDef } from '../types/columns'\nimport type { Density, Plural } from '../types/core'\nimport SheetMenu from './SheetMenu.vue'\nimport SheetRow, { type CellEditing, type RowFill, type RowSelection } from './SheetRow'\nimport type { SheetApi } from './useSheetEditing'\nimport type { Direction } from './useSheetTable'\n\n// İç bileşen: satır tipi DataSheet'te tiplidir.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyRow = any\nconst GUTTER_FULL = 56\n/** Sürüklerken bu kadar yakınken kenar kaydırır (px / kare). */\nconst EDGE = 24\nconst SCROLL_STEP = 12\n\nconst props = withDefaults(\n defineProps<{\n sheet: SheetApi<AnyRow>\n layout: ColumnLayoutApi<AnyRow>\n rows: AnyRow[]\n density?: Density\n /** role=grid aria-label. */\n label: string\n /** aria-busy. */\n loading?: boolean\n /** Açılış: 24 iskelet satır (07 §15). */\n skeleton?: boolean\n verticalLines?: boolean\n keyColumn: string\n /** Find in grid eşleşmeleri: satır anahtarı → sütunlar. */\n found?: Map<string, Set<string>> | null\n /** Kaydederken (07 §14): aria-readonly; kaydırma, Find ve seçim serbest. */\n readOnly?: boolean\n /** Yerel sıralama (07 §10): sütun → yön ve öncelik. */\n sort?: ReadonlyMap<string, { dir: 'asc' | 'desc'; index: number | null }>\n entity: Plural\n /** Telefon (D14, 07 §17): gutter ve işaret yok, seçim aralığı ve fill handle yok; dokunma hücreyi odaklar. */\n phone?: boolean\n }>(),\n {\n density: 'compact',\n loading: false,\n skeleton: false,\n verticalLines: true,\n found: null,\n readOnly: false,\n phone: false,\n },\n)\ndefineSlots<{ state?: () => unknown }>()\n\nconst ctx = useDataTableContext()\nconst uid = useId()\nconst root = ref<HTMLElement | null>(null)\nconst scrollEl = ref<HTMLElement | null>(null)\nconst layout = props.layout\nconst sheet = props.sheet\nconst table = sheet.table\nconst store = sheet.store\nconst keyOf = store.keyOf\n\nconst coarse = typeof matchMedia === 'function' && matchMedia('(pointer: coarse)').matches\nconst density = computed<Density>(() => (coarse && props.density === 'compact' ? 'standard' : props.density))\n\nconst GUTTER_W = computed(() => (props.phone ? 0 : GUTTER_FULL))\n// Gutter track'i başa eklenir; sola sabit sütunların ofseti o kadar kayar (GridRoot ile aynı yöntem).\nwatchEffect(\n () => {\n const el = root.value\n if (!el) return\n const g = GUTTER_W.value\n el.style.setProperty('--cols', `${g ? `${g}px ` : ''}${layout.colsVar.value}`)\n el.style.setProperty('--dt-min-w', `${layout.minWidth.value + g}px`)\n const startVars = new Set(layout.start.value.map((c) => c.offsetVar))\n for (const [name, value] of Object.entries(layout.offsetVars.value))\n el.style.setProperty(name, startVars.has(name) ? `${parseFloat(value) + g}px` : value)\n },\n { flush: 'sync' },\n)\n\nconst rowHeight = ref(32)\n// Sticky header akış içinde: sanal öğeler header kadar aşağıda başlar (TanStack `scrollMargin`), header görünür alanın üstünü\n// (`scrollPaddingStart`), yatay kaydırma çubuğu altını (`scrollPaddingEnd`) örter. Yoksa ↓ ile inen satır tam bir header\n// yüksekliği kadar kabın altında kalır (08 §2).\nconst headH = ref(32)\nconst barH = ref(0)\nconst readBarH = () => {\n const el = scrollEl.value\n barH.value = el ? Math.max(0, el.offsetHeight - el.clientHeight) : 0\n}\nconst readRowHeight = () => {\n const v = root.value ? parseFloat(getComputedStyle(root.value).getPropertyValue('--dt-row-h')) : NaN\n rowHeight.value = Number.isFinite(v) ? v : 32\n headH.value = root.value?.querySelector<HTMLElement>('.dt-head')?.offsetHeight ?? headH.value\n readBarH()\n}\nonMounted(readRowHeight)\nwatch(density, () => requestAnimationFrame(readRowHeight))\n\nconst labels = new RemoteLabels()\nconst env = computed<RenderEnv>(() => ({\n fmt: getFormat(ctx.locale),\n i18n: ctx.i18n,\n today: new Date(),\n labels,\n density: density.value,\n coarse,\n}))\nconst columns = computed(() => layout.columns.value)\nconst defById = computed(() => new Map(columns.value.map((c) => [c.id, c.def])))\nconst indexByKey = computed(() => {\n const m = new Map<string, number>()\n props.rows.forEach((r, i) => m.set(keyOf(r), i))\n return m\n})\nconst active = table.active\nconst activeIndex = computed(() => (active.value ? (indexByKey.value.get(active.value.rowId) ?? -1) : -1))\n// Aralık görünümü yalnızca birden çok hücrede (tek hücre = aktif çerçeve, 07 §4).\nconst multi = computed(() => {\n const b = table.bounds.value\n return !!b && (b.maxRowIndex > b.minRowIndex || b.maxColumnIndex > b.minColumnIndex)\n})\nconst selectionFor = (i: number): RowSelection | null => {\n const b = table.bounds.value\n if (!b || !multi.value || i < b.minRowIndex || i > b.maxRowIndex) return null\n return { from: b.minColumnIndex, to: b.maxColumnIndex, top: i === b.minRowIndex, bottom: i === b.maxRowIndex }\n}\n/** Fill handle: tek hücrede aktif hücre, aralıkta sağ alt köşe. */\nconst handleFor = (i: number): string | null => {\n const b = table.bounds.value\n if (!b || fillDrag.value || props.phone) return null\n if (!multi.value) return i === activeIndex.value ? (active.value?.columnId ?? null) : null\n return i === b.maxRowIndex ? (columns.value[b.maxColumnIndex]?.id ?? null) : null\n}\nconst editingFor = (i: number): CellEditing | null => {\n const e = sheet.edit.editing.value\n const row = props.rows[i]\n return e && row && keyOf(e.row) === keyOf(row)\n ? { columnId: e.def.id as string, value: e.value, inCell: e.inCell }\n : null\n}\nconst foundFor = (i: number) => {\n const row = props.rows[i]\n return row ? props.found?.get(keyOf(row)) : undefined\n}\n\nconst count = computed(() => (props.skeleton ? 24 : props.rows.length))\nconst virtualizer = useVirtualizer(\n computed(() => ({\n count: count.value,\n getScrollElement: () => scrollEl.value,\n estimateSize: () => rowHeight.value + 1,\n scrollMargin: headH.value,\n scrollPaddingStart: headH.value,\n scrollPaddingEnd: barH.value,\n overscan: 10,\n getItemKey: (i: number) => (props.skeleton ? `sk-${i}` : keyOf(props.rows[i]!)),\n // Aktif satır her zaman DOM'da (08 §2): kaydırma odağı kaybettirmez.\n rangeExtractor: (range: { startIndex: number; endIndex: number; overscan: number; count: number }) => {\n const start = Math.max(0, range.startIndex - range.overscan)\n const end = Math.min(range.count - 1, range.endIndex + range.overscan)\n const out: number[] = []\n const a = props.skeleton ? -1 : activeIndex.value\n if (a >= 0 && a < start) out.push(a)\n for (let i = start; i <= end; i++) out.push(i)\n if (a > end && a < range.count) out.push(a)\n return out\n },\n })),\n)\nconst virtualRows = computed(() => virtualizer.value.getVirtualItems())\nconst totalSize = computed(() => virtualizer.value.getTotalSize())\nwatch(rowHeight, () => virtualizer.value.measure())\n\nconst scrolledStart = shallowRef(false)\nconst onScroll = () => {\n readBarH()\n scrolledStart.value = (scrollEl.value?.scrollLeft ?? 0) > 0\n}\n\n/** Hücre elemanı (id'de nokta olabilir: dataset karşılaştırması). */\nconst cellEl = (i: number, columnId: string): HTMLElement | null => {\n const row = root.value?.querySelector<HTMLElement>(`.dt-row[data-index=\"${i}\"]`)\n if (!row) return null\n for (const c of row.querySelectorAll<HTMLElement>('.dt-cell[data-col]')) if (c.dataset.col === columnId) return c\n return null\n}\nconst pinnedWidth = (): number => {\n let w = 0\n for (const c of root.value?.querySelectorAll<HTMLElement>('.dt-head .is-pinned-start') ?? []) w += c.offsetWidth\n return w\n}\n/** Yatayda görünüre getir: sola sabit sütunların altında kalmasın. */\nconst revealX = (el: HTMLElement) => {\n const sc = scrollEl.value\n if (!sc || el.classList.contains('is-pinned-start')) return\n const r = el.getBoundingClientRect()\n const s = sc.getBoundingClientRect()\n const left = s.left + pinnedWidth()\n if (r.left < left) sc.scrollLeft -= left - r.left\n else if (r.right > s.right) sc.scrollLeft += r.right - s.right\n}\n/** ⇧+ok: seçimin hareket eden ucu görünür alana gelir; odak aktif hücrede (anchor) kalır, o satır zaten DOM'da tutulur. */\nconst revealEnd = () => {\n const end = table.rangeEnd.value\n const i = end ? indexByKey.value.get(end.rowId) : undefined\n if (!end || i === undefined) return\n virtualizer.value.scrollToIndex(i, { align: 'auto' })\n requestAnimationFrame(() => {\n const el = cellEl(i, end.columnId)\n if (el) revealX(el)\n })\n}\n/** Aktif hücreyi DOM'a getirip odaklar: önce üst bileşenin `rows` prop'u gelsin (görünüm değişimi, yeni/geri gelen satır\n * dizini kaydırır), sonra sanal listede sonraki karede DOM'a girsin. */\nconst focusActive = () => void nextTick(() => focusNow(0))\nconst focusNow = (round: number) => {\n const a = active.value\n // Hücre editörü açıksa odak ondadır (Add row → anahtar hücresi düzenlemede); çalınmaz.\n if (!a || sheet.edit.editing.value?.inCell) return\n const i = indexByKey.value.get(a.rowId)\n if (i === undefined) {\n if (round < 3) requestAnimationFrame(() => focusNow(round + 1))\n return\n }\n virtualizer.value.scrollToIndex(i, { align: 'auto' })\n const tryFocus = (attempt: number) => {\n const el = cellEl(i, a.columnId)\n if (el) {\n el.focus({ preventScroll: true })\n revealX(el)\n } else if (attempt < 3) requestAnimationFrame(() => tryFocus(attempt + 1))\n }\n tryFocus(0)\n}\n\nconst focusCell = (i: number, columnId: string) => {\n const row = props.rows[Math.max(0, Math.min(props.rows.length - 1, i))]\n if (!row) return\n table.focus(keyOf(row), columnId)\n focusActive()\n}\n/** Tab / ⇧Tab: satır sonunda sonraki satırın başına (08 §4). */\nconst step = (dir: 'left' | 'right') => {\n const a = active.value\n if (!a) return\n const cols = columns.value\n const ci = cols.findIndex((c) => c.id === a.columnId)\n const ri = activeIndex.value\n if (dir === 'right') {\n if (ci < cols.length - 1) table.move('right')\n else if (ri < props.rows.length - 1) table.focus(keyOf(props.rows[ri + 1]), cols[0]!.id)\n } else if (ci > 0) table.move('left')\n else if (ri > 0) table.focus(keyOf(props.rows[ri - 1]), cols[cols.length - 1]!.id)\n focusActive()\n}\n/** ⌘ + ok: kenara atla. */\nconst jump = (dir: Direction) => {\n const a = active.value!\n const cols = columns.value\n if (dir === 'left') table.focus(a.rowId, cols[0]!.id)\n else if (dir === 'right') table.focus(a.rowId, cols[cols.length - 1]!.id)\n else {\n const row = props.rows[dir === 'up' ? 0 : props.rows.length - 1]\n if (row) table.focus(keyOf(row), a.columnId)\n }\n}\nconst pageSize = () => Math.max(1, Math.floor((scrollEl.value?.clientHeight ?? 0) / (rowHeight.value + 1)) - 1)\nconst DIR: Record<string, Direction> = { ArrowUp: 'up', ArrowDown: 'down', ArrowLeft: 'left', ArrowRight: 'right' }\nconst mac = typeof navigator !== 'undefined' && /Mac|iPhone|iPad/.test(navigator.platform)\n\nconst onKeydown = (e: KeyboardEvent) => {\n const target = e.target as HTMLElement\n const ed = sheet.edit.editing.value\n if (ed?.inCell) {\n // Tab her zaman onaylar (listede olmayan metin olduğu gibi kalır → hata, 07 §5). Enter/Esc: açık combobox\n // (aria-expanded), kendi işini yapmış widget (defaultPrevented) ve düğmeler önce.\n if (e.key === 'Tab') {\n e.preventDefault()\n sheet.edit.commit()\n step(e.shiftKey ? 'left' : 'right')\n return\n }\n // Yerleşik multiselect: seçimler listede tik ile yapılır, Esc liste açıkken de kaydedip çıkar (07 §5).\n if (e.key === 'Escape' && ed.def.type === 'multiselect' && !ed.def.editor) {\n e.preventDefault()\n sheet.edit.commit()\n focusActive()\n return\n }\n if (e.defaultPrevented || target.getAttribute('aria-expanded') === 'true' || target.tagName === 'BUTTON') return\n if (e.key === 'Enter' && !(e.shiftKey && target.tagName === 'TEXTAREA')) {\n e.preventDefault()\n sheet.edit.commit()\n table.move('down')\n focusActive()\n } else if (e.key === 'Escape') {\n e.preventDefault()\n sheet.edit.cancel()\n focusActive()\n }\n return\n }\n const cell = target.closest<HTMLElement>('.dt-cell[data-col]')\n if (!cell) return\n if (target !== cell) {\n // Hücre içi widget: ızgara tuşları kapalı, Esc hücreye döner (08 §2).\n if (e.key === 'Escape') {\n e.preventDefault()\n cell.focus()\n }\n return\n }\n const a = active.value\n const row = props.rows[activeIndex.value]\n const def = a ? defById.value.get(a.columnId) : undefined\n if (!a || !row || !def) return\n const editable = sheet.canEdit(row, def)\n const mod = e.metaKey || e.ctrlKey\n const dir = DIR[e.key]\n if (dir) {\n e.preventDefault()\n if (e.shiftKey) {\n table.extend(dir)\n void nextTick(revealEnd)\n return\n }\n if (mod) jump(dir)\n else table.move(dir)\n focusActive()\n return\n }\n switch (e.key) {\n case 'Tab':\n e.preventDefault()\n step(e.shiftKey ? 'left' : 'right')\n return\n case 'Enter': {\n e.preventDefault()\n const widget = editable ? null : cell.querySelector<HTMLElement>(INTERACTIVE_SELECTOR)\n if (widget) widget.focus()\n else {\n table.move('down')\n focusActive()\n }\n return\n }\n case 'F2':\n e.preventDefault()\n sheet.edit.start(row, def, { inCell: true })\n return\n case 'Escape':\n e.preventDefault()\n table.focus(a.rowId, a.columnId)\n return\n case ' ':\n e.preventDefault()\n if (def.type === 'boolean' && editable) sheet.toggle(row, def)\n return\n case 'Delete':\n case 'Backspace':\n e.preventDefault()\n sheet.clearCells()\n return\n case 'Home':\n e.preventDefault()\n focusCell(mod ? 0 : activeIndex.value, columns.value[0]!.id)\n return\n case 'End':\n e.preventDefault()\n focusCell(mod ? props.rows.length - 1 : activeIndex.value, columns.value[columns.value.length - 1]!.id)\n return\n case 'PageDown':\n e.preventDefault()\n focusCell(activeIndex.value + pageSize(), a.columnId)\n return\n case 'PageUp':\n e.preventDefault()\n focusCell(activeIndex.value - pageSize(), a.columnId)\n return\n case 'F8':\n e.preventDefault()\n sheet.goToError(e.shiftKey ? -1 : 1)\n return\n case 'ContextMenu':\n case 'F10':\n if (e.key === 'F10' && !e.shiftKey) return\n e.preventDefault()\n openMenuAt(cell)\n return\n }\n if (mod) {\n // ⌘C / ⌘X / ⌘V tarayıcının copy/cut/paste olaylarıyla gelir (aşağıda); burada yalnızca kısayol tuşları.\n const k = e.key.toLowerCase()\n if (k === 'a' && !e.shiftKey) {\n e.preventDefault()\n table.selectAll()\n } else if (k === 's') {\n e.preventDefault()\n sheet.save()\n } else if (k === 'd' && !e.shiftKey) {\n e.preventDefault()\n sheet.fillDown()\n } else if (k === 'z' && !e.shiftKey) {\n e.preventDefault()\n sheet.undo()\n } else if ((k === 'z' && e.shiftKey) || (k === 'y' && !mac)) {\n e.preventDefault()\n sheet.redo()\n } else if (e.key === '-' || e.key === 'Subtract') {\n e.preventDefault()\n sheet.removeSelectedRows()\n }\n return\n }\n // Yazmaya başlamak: düzenleme açılır, içerik yazılanla değiştirilir (07 §5).\n if (e.key.length === 1 && !e.altKey && editable) {\n e.preventDefault()\n sheet.edit.start(row, def, { inCell: true, replace: e.key })\n }\n}\n\n/** Pano (07 §7): odak hücredeyken (editör ya da widget input'u değilken). */\nconst clipboard = (e: ClipboardEvent, action: 'copy' | 'cut' | 'paste') => {\n if (sheet.edit.editing.value?.inCell || isTextInput(e.target as Element)) return\n if (!(e.target as HTMLElement).closest('.dt-cell[data-col]')) return\n if (sheet[action](e.clipboardData)) e.preventDefault()\n}\n\ninterface Hit {\n index: number\n row: AnyRow\n columnId: string\n cell: HTMLElement\n target: HTMLElement\n}\nconst hitAt = (target: HTMLElement | null): Hit | null => {\n const cell = target?.closest<HTMLElement>('.dt-cell[data-col]')\n const rowEl = target?.closest<HTMLElement>('.dt-row[data-index]')\n if (!cell || !rowEl || props.skeleton) return null\n const index = Number(rowEl.dataset.index)\n const row = props.rows[index]\n return row ? { index, row, columnId: cell.dataset.col!, cell, target: target! } : null\n}\nconst hit = (e: Event): Hit | null => hitAt(e.target as HTMLElement)\n\n// Sürükleme (seçim ya da doldurma): kenara yaklaşınca otomatik kayar, kayan içerikte imlecin altındaki hücre izlenir.\nconst dragging = shallowRef<'select' | 'fill' | null>(null)\nconst fillDrag = shallowRef<{ fromRow: number; toRow: number; cols: [number, number]; target: number } | null>(null)\nconst fillLabel = shallowRef<{ left: number; top: number; text: string } | null>(null)\nlet pointer = { x: 0, y: 0 }\nlet scrollRaf = 0\nconst extendTo = (h: Hit | null) => {\n if (!h) return\n if (dragging.value === 'fill') {\n const f = fillDrag.value!\n const target = h.index > f.toRow ? h.index : h.index < f.fromRow ? h.index : f.toRow\n if (target !== f.target) {\n fillDrag.value = { ...f, target }\n updateFillLabel()\n }\n } else table.extendHandler(keyOf(h.row), h.columnId)?.(new MouseEvent('mouseover'))\n}\nconst autoScroll = () => {\n scrollRaf = 0\n const sc = scrollEl.value\n if (!dragging.value || !sc) return\n const r = sc.getBoundingClientRect()\n let dy = 0\n if (pointer.y < r.top + EDGE) dy = -SCROLL_STEP\n else if (pointer.y > r.bottom - EDGE) dy = SCROLL_STEP\n let dx = 0\n if (dragging.value === 'select') {\n if (pointer.x < r.left + pinnedWidth() + EDGE) dx = -SCROLL_STEP\n else if (pointer.x > r.right - EDGE) dx = SCROLL_STEP\n }\n if (dy || dx) {\n sc.scrollTop += dy\n sc.scrollLeft += dx\n extendTo(hitAt(document.elementFromPoint(pointer.x, pointer.y) as HTMLElement | null))\n scrollRaf = requestAnimationFrame(autoScroll)\n }\n}\nconst onMousemove = (e: MouseEvent) => {\n if (!dragging.value) return\n pointer = { x: e.clientX, y: e.clientY }\n if (dragging.value === 'fill') extendTo(hit(e))\n if (!scrollRaf) scrollRaf = requestAnimationFrame(autoScroll)\n}\nconst updateFillLabel = () => {\n const f = fillDrag.value\n if (!f || f.target === f.toRow) {\n fillLabel.value = null\n return\n }\n const last = f.target > f.toRow ? f.target : f.target\n const el = cellEl(last, columns.value[f.cols[1]]!.id)\n const rootRect = root.value?.getBoundingClientRect()\n if (!el || !rootRect) {\n fillLabel.value = null\n return\n }\n const r = el.getBoundingClientRect()\n fillLabel.value = {\n left: r.right - rootRect.left + 10,\n top: r.bottom - rootRect.top - 13,\n text: sheet.fillLabel(f.fromRow, f.toRow, f.cols, f.target),\n }\n}\nconst onDocMouseup = () => {\n if (dragging.value === 'fill' && fillDrag.value) {\n const f = fillDrag.value\n if (f.target !== f.toRow) sheet.fill(f.fromRow, f.toRow, f.cols, f.target)\n fillDrag.value = null\n fillLabel.value = null\n focusActive()\n }\n dragging.value = null\n cancelAnimationFrame(scrollRaf)\n scrollRaf = 0\n}\nonMounted(() => document.addEventListener('mouseup', onDocMouseup))\nonBeforeUnmount(() => {\n document.removeEventListener('mouseup', onDocMouseup)\n cancelAnimationFrame(scrollRaf)\n})\n\nlet rowAnchor = -1\nconst onMousedown = (e: MouseEvent) => {\n if (e.button !== 0) return\n const target = e.target as HTMLElement\n // Fill handle (07 §8): 4 px dışarı taştığı için alt satırın hücresi hedef olabilir; dikdörtgenle tespit.\n const handle = root.value?.querySelector<HTMLElement>('.dt-fill-handle')\n const hr = handle?.getBoundingClientRect()\n if (\n hr &&\n e.clientX >= hr.left - 2 &&\n e.clientX <= hr.right + 2 &&\n e.clientY >= hr.top - 2 &&\n e.clientY <= hr.bottom + 2\n ) {\n const b = table.bounds.value\n if (!b) return\n e.preventDefault()\n sheet.edit.commit()\n fillDrag.value = {\n fromRow: b.minRowIndex,\n toRow: b.maxRowIndex,\n cols: [b.minColumnIndex, b.maxColumnIndex],\n target: b.maxRowIndex,\n }\n dragging.value = 'fill'\n pointer = { x: e.clientX, y: e.clientY }\n return\n }\n const rowEl = target.closest<HTMLElement>('.dt-row[data-index]')\n if (target.closest('.dt-gutter') && rowEl && !props.skeleton) {\n // Gutter: satırın tamamı, ⇧ ile satır aralığı (07 §6).\n e.preventDefault()\n const i = Number(rowEl.dataset.index)\n const cols = columns.value\n const from = e.shiftKey && rowAnchor >= 0 ? rowAnchor : i\n rowAnchor = from\n sheet.edit.commit()\n table.selectRange({\n anchorRowId: keyOf(props.rows[from]),\n anchorColumnId: cols[0]!.id,\n focusRowId: keyOf(props.rows[i]),\n focusColumnId: cols[cols.length - 1]!.id,\n })\n focusActive()\n return\n }\n const h = hit(e)\n if (!h) return\n rowAnchor = -1\n const ed = sheet.edit.editing.value\n if (ed?.inCell && h.cell.classList.contains('is-editing')) return\n // Başka hücreye mousedown onaylar (07 §5); hücredeki düğme hücreyi aktif yapar ama düzenlemez.\n sheet.edit.commit()\n if (props.phone) {\n // Telefon: dokunma yalnızca hücreyi odaklar (kaydırma serbest, aralık yok).\n table.focus(keyOf(h.row), h.columnId)\n return\n }\n if (!isInteractive(h.target, h.cell)) e.preventDefault()\n table.startHandler(keyOf(h.row), h.columnId)?.(e)\n dragging.value = 'select'\n pointer = { x: e.clientX, y: e.clientY }\n h.cell.focus({ preventScroll: true })\n}\nconst onMouseover = (e: MouseEvent) => {\n if (dragging.value === 'fill') return\n const h = hit(e)\n if (h) table.extendHandler(keyOf(h.row), h.columnId)?.(e)\n}\nconst onDblclick = (e: MouseEvent) => {\n const h = hit(e)\n if (!h || isInteractive(h.target, h.cell)) return\n const def = defById.value.get(h.columnId)\n if (!def) return\n // boolean: düzenleme modu yok (07 §5); çift tık Space gibi Yes ↔ No çevirir.\n if (def.type === 'boolean' && !def.editor) {\n if (sheet.canEdit(h.row, def)) sheet.toggle(h.row, def)\n return\n }\n sheet.edit.start(h.row, def, { inCell: true })\n}\nconst fillFor = (i: number): RowFill | null => {\n const f = fillDrag.value\n if (!f || f.target === f.toRow) return null\n const down = f.target > f.toRow\n const inRange = down ? i > f.toRow && i <= f.target : i < f.fromRow && i >= f.target\n if (!inRange) return null\n return { from: f.cols[0], to: f.cols[1], last: down ? i === f.target : i === f.fromRow - 1 }\n}\n\n/** Sağ tık (07 §9): hedef hücre seçimin dışındaysa aktif olur; hücre dışı (header, boş alan) için menü açılmaz. */\nconst onContextmenuCapture = (e: MouseEvent) => {\n const h = hit(e)\n if (!h || props.skeleton) {\n e.stopPropagation()\n return\n }\n const b = table.bounds.value\n const ci = columns.value.findIndex((c) => c.id === h.columnId)\n const inside =\n !!b && h.index >= b.minRowIndex && h.index <= b.maxRowIndex && ci >= b.minColumnIndex && ci <= b.maxColumnIndex\n if (!inside) {\n sheet.edit.commit()\n table.focus(keyOf(h.row), h.columnId)\n h.cell.focus({ preventScroll: true })\n }\n}\n/** ⇧F10 / Menü tuşu: menü hücrenin köşesinde (reka tetikleyicisi contextmenu olayından konum alır). */\nconst openMenuAt = (cell: HTMLElement) => {\n const r = cell.getBoundingClientRect()\n cell.dispatchEvent(\n new MouseEvent('contextmenu', { bubbles: true, cancelable: true, clientX: r.left + 8, clientY: r.bottom - 4 }),\n )\n}\nconst menuHref = computed(() => {\n const row = props.rows[activeIndex.value]\n return row ? sheet.openHref(row) : undefined\n})\nconst sortOf = (id: string) => props.sort?.get(id)\n\nconst unitOf = (def: ColumnDef<AnyRow>) => (typeof def.unit === 'string' ? def.unit : undefined)\n// D33: anahtar sütunda anahtar metni, açıklama varsa altına ikinci satır; aksi halde ad + açıklama.\nconst headTip = (col: { id: string; def: ColumnDef<AnyRow> }) => {\n const key = col.id === props.keyColumn ? ctx.i18n.t('sheet.keyTooltip', { key: col.def.header }) : undefined\n return col.def.description ? `${key ?? col.def.header}\\n${col.def.description}` : key\n}\nconst resize = (col: LayoutColumn<AnyRow>, e: MouseEvent | TouchEvent) => {\n const cell = (e.currentTarget as HTMLElement).parentElement!\n layout.setWidth(col.id, cell.getBoundingClientRect().width)\n col.header.getResizeHandler()(e)\n}\nconst requiredLabel = ctx.i18n.t('sheet.required').toLocaleLowerCase(ctx.locale)\n\ndefineExpose({ focusActive, scrollToIndex: (i: number) => virtualizer.value.scrollToIndex(i) })\n</script>\n\n<template>\n <ContextMenuRoot>\n <ContextMenuTrigger as-child>\n <div\n ref=\"root\"\n class=\"dt-grid dt-sheet-grid\"\n :class=\"{\n 'is-scrolled-start': scrolledStart,\n 'is-skeleton': skeleton,\n 'has-vlines': verticalLines,\n 'is-filling': dragging === 'fill',\n 'is-phone': phone,\n }\"\n role=\"grid\"\n :aria-label=\"label\"\n :aria-rowcount=\"skeleton ? -1 : rows.length\"\n :aria-colcount=\"columns.length + (phone ? 0 : 1)\"\n :aria-busy=\"loading || readOnly ? 'true' : undefined\"\n :aria-readonly=\"readOnly ? 'true' : undefined\"\n :data-density=\"density\"\n @keydown=\"onKeydown\"\n @mousedown=\"onMousedown\"\n @mousemove=\"onMousemove\"\n @mouseover=\"onMouseover\"\n @dblclick=\"onDblclick\"\n @contextmenu.capture=\"onContextmenuCapture\"\n @copy=\"clipboard($event, 'copy')\"\n @cut=\"clipboard($event, 'cut')\"\n @paste=\"clipboard($event, 'paste')\"\n >\n <div ref=\"scrollEl\" class=\"dt-scroll\" @scroll.passive=\"onScroll\">\n <div class=\"dt-head\" role=\"row\" aria-rowindex=\"1\">\n <div v-if=\"!phone\" class=\"dt-head-cell dt-gutter is-pinned-start\" style=\"left: 0px\" role=\"columnheader\">\n {{ ctx.i18n.t('sheet.err.row') }}\n </div>\n <div\n v-for=\"col in columns\"\n :key=\"col.id\"\n class=\"dt-head-cell\"\n :class=\"[\n `is-${alignOf(col.def)}`,\n {\n 'is-numeric': isNumericType(col.def.type),\n 'is-key': col.id === keyColumn,\n 'is-pinned-start': col.pinned === 'start',\n 'is-pin-edge': col.pinEdge,\n 'is-resizing': layout.resizing.value?.id === col.id,\n },\n ]\"\n :style=\"col.pinned === 'start' ? { left: `var(${col.offsetVar})` } : undefined\"\n role=\"columnheader\"\n :aria-sort=\"\n sortOf(col.id)?.dir === 'asc' ? 'ascending' : sortOf(col.id)?.dir === 'desc' ? 'descending' : undefined\n \"\n :data-col=\"col.id\"\n >\n <PhLock v-if=\"col.id === keyColumn\" :size=\"12\" class=\"dt-head-lock\" aria-hidden=\"true\" />\n <button\n type=\"button\"\n class=\"dt-head-label\"\n tabindex=\"-1\"\n :data-dt-tip=\"headTip(col)\"\n :aria-describedby=\"col.def.description ? `${uid}-desc-${col.id}` : undefined\"\n @click=\"sheet.sort(col.id, $event.shiftKey)\"\n >\n <span class=\"dt-head-text\">{{ col.def.header }}</span>\n <span v-if=\"col.def.required\" class=\"dt-head-required\" :aria-label=\"requiredLabel\">*</span>\n <span v-if=\"unitOf(col.def)\" class=\"dt-head-unit\">{{ unitOf(col.def) }}</span>\n <span v-if=\"sortOf(col.id)\" class=\"dt-head-sort\" aria-hidden=\"true\">\n <PhArrowUp :size=\"12\" :class=\"{ 'is-desc': sortOf(col.id)!.dir === 'desc' }\" />\n <span v-if=\"sortOf(col.id)!.index\" class=\"dt-head-sort-index\">{{ sortOf(col.id)!.index }}</span>\n </span>\n </button>\n <span v-if=\"col.def.description\" :id=\"`${uid}-desc-${col.id}`\" class=\"dt-sr-only\">\n {{ col.def.description }}\n </span>\n <span class=\"dt-head-sep\" aria-hidden=\"true\" />\n <span\n class=\"dt-resize\"\n aria-hidden=\"true\"\n @mousedown=\"resize(col, $event)\"\n @touchstart.passive=\"resize(col, $event)\"\n >\n <span v-if=\"layout.resizing.value?.id === col.id\" class=\"dt-resize-badge\">\n {{ Math.round(layout.resizing.value!.size) }} px\n </span>\n </span>\n </div>\n <div class=\"dt-head-cell dt-cell-fill\" role=\"presentation\" aria-hidden=\"true\" />\n </div>\n <div class=\"dt-body\" role=\"presentation\" :style=\"{ height: `${totalSize}px` }\">\n <div\n v-for=\"item in virtualRows\"\n :key=\"String(item.key)\"\n class=\"dt-item\"\n :data-index=\"item.index\"\n :style=\"{ transform: `translateY(${item.start - headH}px)` }\"\n >\n <SkeletonRow v-if=\"skeleton\" :index=\"item.index\" :columns=\"columns\" :gutter=\"!phone\" />\n <SheetRow\n v-else\n :row=\"rows[item.index]!\"\n :index=\"item.index\"\n :row-no=\"store.rowNoOf(keyOf(rows[item.index]))\"\n :gutter=\"!phone\"\n :uid=\"uid\"\n :columns=\"columns\"\n :env=\"env\"\n :key-column=\"keyColumn\"\n :read=\"store.read\"\n :original=\"store.original\"\n :can-edit=\"sheet.canEdit\"\n :current=\"store.current\"\n :editor-for=\"sheet.editorFor\"\n :draft=\"store.rowDraft(keyOf(rows[item.index]))\"\n :issues=\"store.rowIssues(keyOf(rows[item.index]))\"\n :is-new=\"store.isNew(keyOf(rows[item.index]))\"\n :key-state=\"store.keyState(keyOf(rows[item.index]))\"\n :row-error=\"store.rowError(keyOf(rows[item.index]))\"\n :active=\"activeIndex === item.index ? active!.columnId : null\"\n :selection=\"selectionFor(item.index)\"\n :handle-at=\"handleFor(item.index)\"\n :fill=\"fillFor(item.index)\"\n :found=\"foundFor(item.index)\"\n :editing=\"editingFor(item.index)\"\n :tip-below=\"item.index === 0\"\n @edit-value=\"(v) => sheet.edit.setValue(v)\"\n @use-suggestion=\"(def, v) => sheet.useSuggestion(rows[item.index], def, v)\"\n />\n </div>\n </div>\n </div>\n <div\n v-if=\"fillLabel\"\n class=\"dt-fill-label\"\n role=\"status\"\n :style=\"{ left: `${fillLabel.left}px`, top: `${fillLabel.top}px` }\"\n >\n {{ fillLabel.text }}\n </div>\n <div v-if=\"$slots.state && !skeleton && rows.length === 0\" class=\"dt-body-state\"><slot name=\"state\" /></div>\n <SheetMenu :sheet=\"sheet\" :entity=\"entity\" :href=\"menuHref\" :read-only=\"readOnly || loading\" />\n </div>\n </ContextMenuTrigger>\n </ContextMenuRoot>\n</template>\n","<script setup lang=\"ts\">\n// Sheet ızgarası (07 §2–10, 08 §2 sheet, handoff 06 §5): tek kayan alan, sticky header (yerel sıralama oku), gutter\n// (56 px) + sola sabit sütunlar, sanal satırlar (aktif satır DOM'da kalır); hücre odaklı klavye (roving tabindex = aktif\n// hücre), fare ile hücre / aralık seçimi (TanStack handler'ları, gutter = satır, kenarda otomatik kaydırma), fill handle\n// sürükleme, pano olayları, hücre menüsü (sağ tık / ⇧F10), düzenleme başlatma ve onaylama kuralları. Veri, seçim ve\n// düzenleme durumu `sheet` nesnesinden (DataSheet kurar); bu dosya yalnızca DOM, odak ve kaydırmayı yönetir.\nimport { PhArrowUp, PhLock } from '@phosphor-icons/vue'\nimport { useVirtualizer } from '@tanstack/vue-virtual'\nimport { ContextMenuRoot, ContextMenuTrigger } from 'reka-ui'\nimport { computed, nextTick, onBeforeUnmount, onMounted, ref, shallowRef, useId, watch, watchEffect } from 'vue'\nimport { RemoteLabels } from '../core/cells/remoteLabels'\nimport type { RenderEnv } from '../core/cells/renderCell'\nimport { alignOf, isNumericType } from '../core/cells/specs'\nimport type { ColumnLayoutApi, LayoutColumn } from '../core/columns/useColumnLayout'\nimport { getFormat } from '../core/format'\nimport SkeletonRow from '../core/grid/SkeletonRow'\nimport { INTERACTIVE_SELECTOR, isInteractive, isTextInput } from '../core/interaction/isInteractive'\nimport { useDataTableContext } from '../core/plugin'\nimport type { ColumnDef } from '../types/columns'\nimport type { Density, Plural } from '../types/core'\nimport SheetMenu from './SheetMenu.vue'\nimport SheetRow, { type CellEditing, type RowFill, type RowSelection } from './SheetRow'\nimport type { SheetApi } from './useSheetEditing'\nimport type { Direction } from './useSheetTable'\n\n// İç bileşen: satır tipi DataSheet'te tiplidir.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyRow = any\nconst GUTTER_FULL = 56\n/** Sürüklerken bu kadar yakınken kenar kaydırır (px / kare). */\nconst EDGE = 24\nconst SCROLL_STEP = 12\n\nconst props = withDefaults(\n defineProps<{\n sheet: SheetApi<AnyRow>\n layout: ColumnLayoutApi<AnyRow>\n rows: AnyRow[]\n density?: Density\n /** role=grid aria-label. */\n label: string\n /** aria-busy. */\n loading?: boolean\n /** Açılış: 24 iskelet satır (07 §15). */\n skeleton?: boolean\n verticalLines?: boolean\n keyColumn: string\n /** Find in grid eşleşmeleri: satır anahtarı → sütunlar. */\n found?: Map<string, Set<string>> | null\n /** Kaydederken (07 §14): aria-readonly; kaydırma, Find ve seçim serbest. */\n readOnly?: boolean\n /** Yerel sıralama (07 §10): sütun → yön ve öncelik. */\n sort?: ReadonlyMap<string, { dir: 'asc' | 'desc'; index: number | null }>\n entity: Plural\n /** Telefon (D14, 07 §17): gutter ve işaret yok, seçim aralığı ve fill handle yok; dokunma hücreyi odaklar. */\n phone?: boolean\n }>(),\n {\n density: 'compact',\n loading: false,\n skeleton: false,\n verticalLines: true,\n found: null,\n readOnly: false,\n phone: false,\n },\n)\ndefineSlots<{ state?: () => unknown }>()\n\nconst ctx = useDataTableContext()\nconst uid = useId()\nconst root = ref<HTMLElement | null>(null)\nconst scrollEl = ref<HTMLElement | null>(null)\nconst layout = props.layout\nconst sheet = props.sheet\nconst table = sheet.table\nconst store = sheet.store\nconst keyOf = store.keyOf\n\nconst coarse = typeof matchMedia === 'function' && matchMedia('(pointer: coarse)').matches\nconst density = computed<Density>(() => (coarse && props.density === 'compact' ? 'standard' : props.density))\n\nconst GUTTER_W = computed(() => (props.phone ? 0 : GUTTER_FULL))\n// Gutter track'i başa eklenir; sola sabit sütunların ofseti o kadar kayar (GridRoot ile aynı yöntem).\nwatchEffect(\n () => {\n const el = root.value\n if (!el) return\n const g = GUTTER_W.value\n el.style.setProperty('--cols', `${g ? `${g}px ` : ''}${layout.colsVar.value}`)\n el.style.setProperty('--dt-min-w', `${layout.minWidth.value + g}px`)\n const startVars = new Set(layout.start.value.map((c) => c.offsetVar))\n for (const [name, value] of Object.entries(layout.offsetVars.value))\n el.style.setProperty(name, startVars.has(name) ? `${parseFloat(value) + g}px` : value)\n },\n { flush: 'sync' },\n)\n\nconst rowHeight = ref(32)\n// Sticky header akış içinde: sanal öğeler header kadar aşağıda başlar (TanStack `scrollMargin`), header görünür alanın üstünü\n// (`scrollPaddingStart`), yatay kaydırma çubuğu altını (`scrollPaddingEnd`) örter. Yoksa ↓ ile inen satır tam bir header\n// yüksekliği kadar kabın altında kalır (08 §2).\nconst headH = ref(32)\nconst barH = ref(0)\nconst readBarH = () => {\n const el = scrollEl.value\n barH.value = el ? Math.max(0, el.offsetHeight - el.clientHeight) : 0\n}\nconst readRowHeight = () => {\n const v = root.value ? parseFloat(getComputedStyle(root.value).getPropertyValue('--dt-row-h')) : NaN\n rowHeight.value = Number.isFinite(v) ? v : 32\n headH.value = root.value?.querySelector<HTMLElement>('.dt-head')?.offsetHeight ?? headH.value\n readBarH()\n}\nonMounted(readRowHeight)\nwatch(density, () => requestAnimationFrame(readRowHeight))\n\nconst labels = new RemoteLabels()\nconst env = computed<RenderEnv>(() => ({\n fmt: getFormat(ctx.locale),\n i18n: ctx.i18n,\n today: new Date(),\n labels,\n density: density.value,\n coarse,\n}))\nconst columns = computed(() => layout.columns.value)\nconst defById = computed(() => new Map(columns.value.map((c) => [c.id, c.def])))\nconst indexByKey = computed(() => {\n const m = new Map<string, number>()\n props.rows.forEach((r, i) => m.set(keyOf(r), i))\n return m\n})\nconst active = table.active\nconst activeIndex = computed(() => (active.value ? (indexByKey.value.get(active.value.rowId) ?? -1) : -1))\n// Aralık görünümü yalnızca birden çok hücrede (tek hücre = aktif çerçeve, 07 §4).\nconst multi = computed(() => {\n const b = table.bounds.value\n return !!b && (b.maxRowIndex > b.minRowIndex || b.maxColumnIndex > b.minColumnIndex)\n})\nconst selectionFor = (i: number): RowSelection | null => {\n const b = table.bounds.value\n if (!b || !multi.value || i < b.minRowIndex || i > b.maxRowIndex) return null\n return { from: b.minColumnIndex, to: b.maxColumnIndex, top: i === b.minRowIndex, bottom: i === b.maxRowIndex }\n}\n/** Fill handle: tek hücrede aktif hücre, aralıkta sağ alt köşe. */\nconst handleFor = (i: number): string | null => {\n const b = table.bounds.value\n if (!b || fillDrag.value || props.phone) return null\n if (!multi.value) return i === activeIndex.value ? (active.value?.columnId ?? null) : null\n return i === b.maxRowIndex ? (columns.value[b.maxColumnIndex]?.id ?? null) : null\n}\nconst editingFor = (i: number): CellEditing | null => {\n const e = sheet.edit.editing.value\n const row = props.rows[i]\n return e && row && keyOf(e.row) === keyOf(row)\n ? { columnId: e.def.id as string, value: e.value, inCell: e.inCell }\n : null\n}\nconst foundFor = (i: number) => {\n const row = props.rows[i]\n return row ? props.found?.get(keyOf(row)) : undefined\n}\n\nconst count = computed(() => (props.skeleton ? 24 : props.rows.length))\nconst virtualizer = useVirtualizer(\n computed(() => ({\n count: count.value,\n getScrollElement: () => scrollEl.value,\n estimateSize: () => rowHeight.value + 1,\n scrollMargin: headH.value,\n scrollPaddingStart: headH.value,\n scrollPaddingEnd: barH.value,\n overscan: 10,\n getItemKey: (i: number) => (props.skeleton ? `sk-${i}` : keyOf(props.rows[i]!)),\n // Aktif satır her zaman DOM'da (08 §2): kaydırma odağı kaybettirmez.\n rangeExtractor: (range: { startIndex: number; endIndex: number; overscan: number; count: number }) => {\n const start = Math.max(0, range.startIndex - range.overscan)\n const end = Math.min(range.count - 1, range.endIndex + range.overscan)\n const out: number[] = []\n const a = props.skeleton ? -1 : activeIndex.value\n if (a >= 0 && a < start) out.push(a)\n for (let i = start; i <= end; i++) out.push(i)\n if (a > end && a < range.count) out.push(a)\n return out\n },\n })),\n)\nconst virtualRows = computed(() => virtualizer.value.getVirtualItems())\nconst totalSize = computed(() => virtualizer.value.getTotalSize())\nwatch(rowHeight, () => virtualizer.value.measure())\n\nconst scrolledStart = shallowRef(false)\nconst onScroll = () => {\n readBarH()\n scrolledStart.value = (scrollEl.value?.scrollLeft ?? 0) > 0\n}\n\n/** Hücre elemanı (id'de nokta olabilir: dataset karşılaştırması). */\nconst cellEl = (i: number, columnId: string): HTMLElement | null => {\n const row = root.value?.querySelector<HTMLElement>(`.dt-row[data-index=\"${i}\"]`)\n if (!row) return null\n for (const c of row.querySelectorAll<HTMLElement>('.dt-cell[data-col]')) if (c.dataset.col === columnId) return c\n return null\n}\nconst pinnedWidth = (): number => {\n let w = 0\n for (const c of root.value?.querySelectorAll<HTMLElement>('.dt-head .is-pinned-start') ?? []) w += c.offsetWidth\n return w\n}\n/** Yatayda görünüre getir: sola sabit sütunların altında kalmasın. */\nconst revealX = (el: HTMLElement) => {\n const sc = scrollEl.value\n if (!sc || el.classList.contains('is-pinned-start')) return\n const r = el.getBoundingClientRect()\n const s = sc.getBoundingClientRect()\n const left = s.left + pinnedWidth()\n if (r.left < left) sc.scrollLeft -= left - r.left\n else if (r.right > s.right) sc.scrollLeft += r.right - s.right\n}\n/** ⇧+ok: seçimin hareket eden ucu görünür alana gelir; odak aktif hücrede (anchor) kalır, o satır zaten DOM'da tutulur. */\nconst revealEnd = () => {\n const end = table.rangeEnd.value\n const i = end ? indexByKey.value.get(end.rowId) : undefined\n if (!end || i === undefined) return\n virtualizer.value.scrollToIndex(i, { align: 'auto' })\n requestAnimationFrame(() => {\n const el = cellEl(i, end.columnId)\n if (el) revealX(el)\n })\n}\n/** Aktif hücreyi DOM'a getirip odaklar: önce üst bileşenin `rows` prop'u gelsin (görünüm değişimi, yeni/geri gelen satır\n * dizini kaydırır), sonra sanal listede sonraki karede DOM'a girsin. */\nconst focusActive = () => void nextTick(() => focusNow(0))\nconst focusNow = (round: number) => {\n const a = active.value\n // Hücre editörü açıksa odak ondadır (Add row → anahtar hücresi düzenlemede); çalınmaz.\n if (!a || sheet.edit.editing.value?.inCell) return\n const i = indexByKey.value.get(a.rowId)\n if (i === undefined) {\n if (round < 3) requestAnimationFrame(() => focusNow(round + 1))\n return\n }\n virtualizer.value.scrollToIndex(i, { align: 'auto' })\n const tryFocus = (attempt: number) => {\n const el = cellEl(i, a.columnId)\n if (el) {\n el.focus({ preventScroll: true })\n revealX(el)\n } else if (attempt < 3) requestAnimationFrame(() => tryFocus(attempt + 1))\n }\n tryFocus(0)\n}\n\nconst focusCell = (i: number, columnId: string) => {\n const row = props.rows[Math.max(0, Math.min(props.rows.length - 1, i))]\n if (!row) return\n table.focus(keyOf(row), columnId)\n focusActive()\n}\n/** Tab / ⇧Tab: satır sonunda sonraki satırın başına (08 §4). */\nconst step = (dir: 'left' | 'right') => {\n const a = active.value\n if (!a) return\n const cols = columns.value\n const ci = cols.findIndex((c) => c.id === a.columnId)\n const ri = activeIndex.value\n if (dir === 'right') {\n if (ci < cols.length - 1) table.move('right')\n else if (ri < props.rows.length - 1) table.focus(keyOf(props.rows[ri + 1]), cols[0]!.id)\n } else if (ci > 0) table.move('left')\n else if (ri > 0) table.focus(keyOf(props.rows[ri - 1]), cols[cols.length - 1]!.id)\n focusActive()\n}\n/** ⌘ + ok: kenara atla. */\nconst jump = (dir: Direction) => {\n const a = active.value!\n const cols = columns.value\n if (dir === 'left') table.focus(a.rowId, cols[0]!.id)\n else if (dir === 'right') table.focus(a.rowId, cols[cols.length - 1]!.id)\n else {\n const row = props.rows[dir === 'up' ? 0 : props.rows.length - 1]\n if (row) table.focus(keyOf(row), a.columnId)\n }\n}\nconst pageSize = () => Math.max(1, Math.floor((scrollEl.value?.clientHeight ?? 0) / (rowHeight.value + 1)) - 1)\nconst DIR: Record<string, Direction> = { ArrowUp: 'up', ArrowDown: 'down', ArrowLeft: 'left', ArrowRight: 'right' }\nconst mac = typeof navigator !== 'undefined' && /Mac|iPhone|iPad/.test(navigator.platform)\n\nconst onKeydown = (e: KeyboardEvent) => {\n const target = e.target as HTMLElement\n const ed = sheet.edit.editing.value\n if (ed?.inCell) {\n // Tab her zaman onaylar (listede olmayan metin olduğu gibi kalır → hata, 07 §5). Enter/Esc: açık combobox\n // (aria-expanded), kendi işini yapmış widget (defaultPrevented) ve düğmeler önce.\n if (e.key === 'Tab') {\n e.preventDefault()\n sheet.edit.commit()\n step(e.shiftKey ? 'left' : 'right')\n return\n }\n // Yerleşik multiselect: seçimler listede tik ile yapılır, Esc liste açıkken de kaydedip çıkar (07 §5).\n if (e.key === 'Escape' && ed.def.type === 'multiselect' && !ed.def.editor) {\n e.preventDefault()\n sheet.edit.commit()\n focusActive()\n return\n }\n if (e.defaultPrevented || target.getAttribute('aria-expanded') === 'true' || target.tagName === 'BUTTON') return\n if (e.key === 'Enter' && !(e.shiftKey && target.tagName === 'TEXTAREA')) {\n e.preventDefault()\n sheet.edit.commit()\n table.move('down')\n focusActive()\n } else if (e.key === 'Escape') {\n e.preventDefault()\n sheet.edit.cancel()\n focusActive()\n }\n return\n }\n const cell = target.closest<HTMLElement>('.dt-cell[data-col]')\n if (!cell) return\n if (target !== cell) {\n // Hücre içi widget: ızgara tuşları kapalı, Esc hücreye döner (08 §2).\n if (e.key === 'Escape') {\n e.preventDefault()\n cell.focus()\n }\n return\n }\n const a = active.value\n const row = props.rows[activeIndex.value]\n const def = a ? defById.value.get(a.columnId) : undefined\n if (!a || !row || !def) return\n const editable = sheet.canEdit(row, def)\n const mod = e.metaKey || e.ctrlKey\n const dir = DIR[e.key]\n if (dir) {\n e.preventDefault()\n if (e.shiftKey) {\n table.extend(dir)\n void nextTick(revealEnd)\n return\n }\n if (mod) jump(dir)\n else table.move(dir)\n focusActive()\n return\n }\n switch (e.key) {\n case 'Tab':\n e.preventDefault()\n step(e.shiftKey ? 'left' : 'right')\n return\n case 'Enter': {\n e.preventDefault()\n const widget = editable ? null : cell.querySelector<HTMLElement>(INTERACTIVE_SELECTOR)\n if (widget) widget.focus()\n else {\n table.move('down')\n focusActive()\n }\n return\n }\n case 'F2':\n e.preventDefault()\n sheet.edit.start(row, def, { inCell: true })\n return\n case 'Escape':\n e.preventDefault()\n table.focus(a.rowId, a.columnId)\n return\n case ' ':\n e.preventDefault()\n if (def.type === 'boolean' && editable) sheet.toggle(row, def)\n return\n case 'Delete':\n case 'Backspace':\n e.preventDefault()\n sheet.clearCells()\n return\n case 'Home':\n e.preventDefault()\n focusCell(mod ? 0 : activeIndex.value, columns.value[0]!.id)\n return\n case 'End':\n e.preventDefault()\n focusCell(mod ? props.rows.length - 1 : activeIndex.value, columns.value[columns.value.length - 1]!.id)\n return\n case 'PageDown':\n e.preventDefault()\n focusCell(activeIndex.value + pageSize(), a.columnId)\n return\n case 'PageUp':\n e.preventDefault()\n focusCell(activeIndex.value - pageSize(), a.columnId)\n return\n case 'F8':\n e.preventDefault()\n sheet.goToError(e.shiftKey ? -1 : 1)\n return\n case 'ContextMenu':\n case 'F10':\n if (e.key === 'F10' && !e.shiftKey) return\n e.preventDefault()\n openMenuAt(cell)\n return\n }\n if (mod) {\n // ⌘C / ⌘X / ⌘V tarayıcının copy/cut/paste olaylarıyla gelir (aşağıda); burada yalnızca kısayol tuşları.\n const k = e.key.toLowerCase()\n if (k === 'a' && !e.shiftKey) {\n e.preventDefault()\n table.selectAll()\n } else if (k === 's') {\n e.preventDefault()\n sheet.save()\n } else if (k === 'd' && !e.shiftKey) {\n e.preventDefault()\n sheet.fillDown()\n } else if (k === 'z' && !e.shiftKey) {\n e.preventDefault()\n sheet.undo()\n } else if ((k === 'z' && e.shiftKey) || (k === 'y' && !mac)) {\n e.preventDefault()\n sheet.redo()\n } else if (e.key === '-' || e.key === 'Subtract') {\n e.preventDefault()\n sheet.removeSelectedRows()\n }\n return\n }\n // Yazmaya başlamak: düzenleme açılır, içerik yazılanla değiştirilir (07 §5).\n if (e.key.length === 1 && !e.altKey && editable) {\n e.preventDefault()\n sheet.edit.start(row, def, { inCell: true, replace: e.key })\n }\n}\n\n/** Pano (07 §7): odak hücredeyken (editör ya da widget input'u değilken). */\nconst clipboard = (e: ClipboardEvent, action: 'copy' | 'cut' | 'paste') => {\n if (sheet.edit.editing.value?.inCell || isTextInput(e.target as Element)) return\n if (!(e.target as HTMLElement).closest('.dt-cell[data-col]')) return\n if (sheet[action](e.clipboardData)) e.preventDefault()\n}\n\ninterface Hit {\n index: number\n row: AnyRow\n columnId: string\n cell: HTMLElement\n target: HTMLElement\n}\nconst hitAt = (target: HTMLElement | null): Hit | null => {\n const cell = target?.closest<HTMLElement>('.dt-cell[data-col]')\n const rowEl = target?.closest<HTMLElement>('.dt-row[data-index]')\n if (!cell || !rowEl || props.skeleton) return null\n const index = Number(rowEl.dataset.index)\n const row = props.rows[index]\n return row ? { index, row, columnId: cell.dataset.col!, cell, target: target! } : null\n}\nconst hit = (e: Event): Hit | null => hitAt(e.target as HTMLElement)\n\n// Sürükleme (seçim ya da doldurma): kenara yaklaşınca otomatik kayar, kayan içerikte imlecin altındaki hücre izlenir.\nconst dragging = shallowRef<'select' | 'fill' | null>(null)\nconst fillDrag = shallowRef<{ fromRow: number; toRow: number; cols: [number, number]; target: number } | null>(null)\nconst fillLabel = shallowRef<{ left: number; top: number; text: string } | null>(null)\nlet pointer = { x: 0, y: 0 }\nlet scrollRaf = 0\nconst extendTo = (h: Hit | null) => {\n if (!h) return\n if (dragging.value === 'fill') {\n const f = fillDrag.value!\n const target = h.index > f.toRow ? h.index : h.index < f.fromRow ? h.index : f.toRow\n if (target !== f.target) {\n fillDrag.value = { ...f, target }\n updateFillLabel()\n }\n } else table.extendHandler(keyOf(h.row), h.columnId)?.(new MouseEvent('mouseover'))\n}\nconst autoScroll = () => {\n scrollRaf = 0\n const sc = scrollEl.value\n if (!dragging.value || !sc) return\n const r = sc.getBoundingClientRect()\n let dy = 0\n if (pointer.y < r.top + EDGE) dy = -SCROLL_STEP\n else if (pointer.y > r.bottom - EDGE) dy = SCROLL_STEP\n let dx = 0\n if (dragging.value === 'select') {\n if (pointer.x < r.left + pinnedWidth() + EDGE) dx = -SCROLL_STEP\n else if (pointer.x > r.right - EDGE) dx = SCROLL_STEP\n }\n if (dy || dx) {\n sc.scrollTop += dy\n sc.scrollLeft += dx\n extendTo(hitAt(document.elementFromPoint(pointer.x, pointer.y) as HTMLElement | null))\n scrollRaf = requestAnimationFrame(autoScroll)\n }\n}\nconst onMousemove = (e: MouseEvent) => {\n if (!dragging.value) return\n pointer = { x: e.clientX, y: e.clientY }\n if (dragging.value === 'fill') extendTo(hit(e))\n if (!scrollRaf) scrollRaf = requestAnimationFrame(autoScroll)\n}\nconst updateFillLabel = () => {\n const f = fillDrag.value\n if (!f || f.target === f.toRow) {\n fillLabel.value = null\n return\n }\n const last = f.target > f.toRow ? f.target : f.target\n const el = cellEl(last, columns.value[f.cols[1]]!.id)\n const rootRect = root.value?.getBoundingClientRect()\n if (!el || !rootRect) {\n fillLabel.value = null\n return\n }\n const r = el.getBoundingClientRect()\n fillLabel.value = {\n left: r.right - rootRect.left + 10,\n top: r.bottom - rootRect.top - 13,\n text: sheet.fillLabel(f.fromRow, f.toRow, f.cols, f.target),\n }\n}\nconst onDocMouseup = () => {\n if (dragging.value === 'fill' && fillDrag.value) {\n const f = fillDrag.value\n if (f.target !== f.toRow) sheet.fill(f.fromRow, f.toRow, f.cols, f.target)\n fillDrag.value = null\n fillLabel.value = null\n focusActive()\n }\n dragging.value = null\n cancelAnimationFrame(scrollRaf)\n scrollRaf = 0\n}\nonMounted(() => document.addEventListener('mouseup', onDocMouseup))\nonBeforeUnmount(() => {\n document.removeEventListener('mouseup', onDocMouseup)\n cancelAnimationFrame(scrollRaf)\n})\n\nlet rowAnchor = -1\nconst onMousedown = (e: MouseEvent) => {\n if (e.button !== 0) return\n const target = e.target as HTMLElement\n // Fill handle (07 §8): 4 px dışarı taştığı için alt satırın hücresi hedef olabilir; dikdörtgenle tespit.\n const handle = root.value?.querySelector<HTMLElement>('.dt-fill-handle')\n const hr = handle?.getBoundingClientRect()\n if (\n hr &&\n e.clientX >= hr.left - 2 &&\n e.clientX <= hr.right + 2 &&\n e.clientY >= hr.top - 2 &&\n e.clientY <= hr.bottom + 2\n ) {\n const b = table.bounds.value\n if (!b) return\n e.preventDefault()\n sheet.edit.commit()\n fillDrag.value = {\n fromRow: b.minRowIndex,\n toRow: b.maxRowIndex,\n cols: [b.minColumnIndex, b.maxColumnIndex],\n target: b.maxRowIndex,\n }\n dragging.value = 'fill'\n pointer = { x: e.clientX, y: e.clientY }\n return\n }\n const rowEl = target.closest<HTMLElement>('.dt-row[data-index]')\n if (target.closest('.dt-gutter') && rowEl && !props.skeleton) {\n // Gutter: satırın tamamı, ⇧ ile satır aralığı (07 §6).\n e.preventDefault()\n const i = Number(rowEl.dataset.index)\n const cols = columns.value\n const from = e.shiftKey && rowAnchor >= 0 ? rowAnchor : i\n rowAnchor = from\n sheet.edit.commit()\n table.selectRange({\n anchorRowId: keyOf(props.rows[from]),\n anchorColumnId: cols[0]!.id,\n focusRowId: keyOf(props.rows[i]),\n focusColumnId: cols[cols.length - 1]!.id,\n })\n focusActive()\n return\n }\n const h = hit(e)\n if (!h) return\n rowAnchor = -1\n const ed = sheet.edit.editing.value\n if (ed?.inCell && h.cell.classList.contains('is-editing')) return\n // Başka hücreye mousedown onaylar (07 §5); hücredeki düğme hücreyi aktif yapar ama düzenlemez.\n sheet.edit.commit()\n if (props.phone) {\n // Telefon: dokunma yalnızca hücreyi odaklar (kaydırma serbest, aralık yok).\n table.focus(keyOf(h.row), h.columnId)\n return\n }\n if (!isInteractive(h.target, h.cell)) e.preventDefault()\n table.startHandler(keyOf(h.row), h.columnId)?.(e)\n dragging.value = 'select'\n pointer = { x: e.clientX, y: e.clientY }\n h.cell.focus({ preventScroll: true })\n}\nconst onMouseover = (e: MouseEvent) => {\n if (dragging.value === 'fill') return\n const h = hit(e)\n if (h) table.extendHandler(keyOf(h.row), h.columnId)?.(e)\n}\nconst onDblclick = (e: MouseEvent) => {\n const h = hit(e)\n if (!h || isInteractive(h.target, h.cell)) return\n const def = defById.value.get(h.columnId)\n if (!def) return\n // boolean: düzenleme modu yok (07 §5); çift tık Space gibi Yes ↔ No çevirir.\n if (def.type === 'boolean' && !def.editor) {\n if (sheet.canEdit(h.row, def)) sheet.toggle(h.row, def)\n return\n }\n sheet.edit.start(h.row, def, { inCell: true })\n}\nconst fillFor = (i: number): RowFill | null => {\n const f = fillDrag.value\n if (!f || f.target === f.toRow) return null\n const down = f.target > f.toRow\n const inRange = down ? i > f.toRow && i <= f.target : i < f.fromRow && i >= f.target\n if (!inRange) return null\n return { from: f.cols[0], to: f.cols[1], last: down ? i === f.target : i === f.fromRow - 1 }\n}\n\n/** Sağ tık (07 §9): hedef hücre seçimin dışındaysa aktif olur; hücre dışı (header, boş alan) için menü açılmaz. */\nconst onContextmenuCapture = (e: MouseEvent) => {\n const h = hit(e)\n if (!h || props.skeleton) {\n e.stopPropagation()\n return\n }\n const b = table.bounds.value\n const ci = columns.value.findIndex((c) => c.id === h.columnId)\n const inside =\n !!b && h.index >= b.minRowIndex && h.index <= b.maxRowIndex && ci >= b.minColumnIndex && ci <= b.maxColumnIndex\n if (!inside) {\n sheet.edit.commit()\n table.focus(keyOf(h.row), h.columnId)\n h.cell.focus({ preventScroll: true })\n }\n}\n/** ⇧F10 / Menü tuşu: menü hücrenin köşesinde (reka tetikleyicisi contextmenu olayından konum alır). */\nconst openMenuAt = (cell: HTMLElement) => {\n const r = cell.getBoundingClientRect()\n cell.dispatchEvent(\n new MouseEvent('contextmenu', { bubbles: true, cancelable: true, clientX: r.left + 8, clientY: r.bottom - 4 }),\n )\n}\nconst menuHref = computed(() => {\n const row = props.rows[activeIndex.value]\n return row ? sheet.openHref(row) : undefined\n})\nconst sortOf = (id: string) => props.sort?.get(id)\n\nconst unitOf = (def: ColumnDef<AnyRow>) => (typeof def.unit === 'string' ? def.unit : undefined)\n// D33: anahtar sütunda anahtar metni, açıklama varsa altına ikinci satır; aksi halde ad + açıklama.\nconst headTip = (col: { id: string; def: ColumnDef<AnyRow> }) => {\n const key = col.id === props.keyColumn ? ctx.i18n.t('sheet.keyTooltip', { key: col.def.header }) : undefined\n return col.def.description ? `${key ?? col.def.header}\\n${col.def.description}` : key\n}\nconst resize = (col: LayoutColumn<AnyRow>, e: MouseEvent | TouchEvent) => {\n const cell = (e.currentTarget as HTMLElement).parentElement!\n layout.setWidth(col.id, cell.getBoundingClientRect().width)\n col.header.getResizeHandler()(e)\n}\nconst requiredLabel = ctx.i18n.t('sheet.required').toLocaleLowerCase(ctx.locale)\n\ndefineExpose({ focusActive, scrollToIndex: (i: number) => virtualizer.value.scrollToIndex(i) })\n</script>\n\n<template>\n <ContextMenuRoot>\n <ContextMenuTrigger as-child>\n <div\n ref=\"root\"\n class=\"dt-grid dt-sheet-grid\"\n :class=\"{\n 'is-scrolled-start': scrolledStart,\n 'is-skeleton': skeleton,\n 'has-vlines': verticalLines,\n 'is-filling': dragging === 'fill',\n 'is-phone': phone,\n }\"\n role=\"grid\"\n :aria-label=\"label\"\n :aria-rowcount=\"skeleton ? -1 : rows.length\"\n :aria-colcount=\"columns.length + (phone ? 0 : 1)\"\n :aria-busy=\"loading || readOnly ? 'true' : undefined\"\n :aria-readonly=\"readOnly ? 'true' : undefined\"\n :data-density=\"density\"\n @keydown=\"onKeydown\"\n @mousedown=\"onMousedown\"\n @mousemove=\"onMousemove\"\n @mouseover=\"onMouseover\"\n @dblclick=\"onDblclick\"\n @contextmenu.capture=\"onContextmenuCapture\"\n @copy=\"clipboard($event, 'copy')\"\n @cut=\"clipboard($event, 'cut')\"\n @paste=\"clipboard($event, 'paste')\"\n >\n <div ref=\"scrollEl\" class=\"dt-scroll\" @scroll.passive=\"onScroll\">\n <div class=\"dt-head\" role=\"row\" aria-rowindex=\"1\">\n <div v-if=\"!phone\" class=\"dt-head-cell dt-gutter is-pinned-start\" style=\"left: 0px\" role=\"columnheader\">\n {{ ctx.i18n.t('sheet.err.row') }}\n </div>\n <div\n v-for=\"col in columns\"\n :key=\"col.id\"\n class=\"dt-head-cell\"\n :class=\"[\n `is-${alignOf(col.def)}`,\n {\n 'is-numeric': isNumericType(col.def.type),\n 'is-key': col.id === keyColumn,\n 'is-pinned-start': col.pinned === 'start',\n 'is-pin-edge': col.pinEdge,\n 'is-resizing': layout.resizing.value?.id === col.id,\n },\n ]\"\n :style=\"col.pinned === 'start' ? { left: `var(${col.offsetVar})` } : undefined\"\n role=\"columnheader\"\n :aria-sort=\"\n sortOf(col.id)?.dir === 'asc' ? 'ascending' : sortOf(col.id)?.dir === 'desc' ? 'descending' : undefined\n \"\n :data-col=\"col.id\"\n >\n <PhLock v-if=\"col.id === keyColumn\" :size=\"12\" class=\"dt-head-lock\" aria-hidden=\"true\" />\n <button\n type=\"button\"\n class=\"dt-head-label\"\n tabindex=\"-1\"\n :data-dt-tip=\"headTip(col)\"\n :aria-describedby=\"col.def.description ? `${uid}-desc-${col.id}` : undefined\"\n @click=\"sheet.sort(col.id, $event.shiftKey)\"\n >\n <span class=\"dt-head-text\">{{ col.def.header }}</span>\n <span v-if=\"col.def.required\" class=\"dt-head-required\" :aria-label=\"requiredLabel\">*</span>\n <span v-if=\"unitOf(col.def)\" class=\"dt-head-unit\">{{ unitOf(col.def) }}</span>\n <span v-if=\"sortOf(col.id)\" class=\"dt-head-sort\" aria-hidden=\"true\">\n <PhArrowUp :size=\"12\" :class=\"{ 'is-desc': sortOf(col.id)!.dir === 'desc' }\" />\n <span v-if=\"sortOf(col.id)!.index\" class=\"dt-head-sort-index\">{{ sortOf(col.id)!.index }}</span>\n </span>\n </button>\n <span v-if=\"col.def.description\" :id=\"`${uid}-desc-${col.id}`\" class=\"dt-sr-only\">\n {{ col.def.description }}\n </span>\n <span class=\"dt-head-sep\" aria-hidden=\"true\" />\n <span\n class=\"dt-resize\"\n aria-hidden=\"true\"\n @mousedown=\"resize(col, $event)\"\n @touchstart.passive=\"resize(col, $event)\"\n >\n <span v-if=\"layout.resizing.value?.id === col.id\" class=\"dt-resize-badge\">\n {{ Math.round(layout.resizing.value!.size) }} px\n </span>\n </span>\n </div>\n <div class=\"dt-head-cell dt-cell-fill\" role=\"presentation\" aria-hidden=\"true\" />\n </div>\n <div class=\"dt-body\" role=\"presentation\" :style=\"{ height: `${totalSize}px` }\">\n <div\n v-for=\"item in virtualRows\"\n :key=\"String(item.key)\"\n class=\"dt-item\"\n :data-index=\"item.index\"\n :style=\"{ transform: `translateY(${item.start - headH}px)` }\"\n >\n <SkeletonRow v-if=\"skeleton\" :index=\"item.index\" :columns=\"columns\" :gutter=\"!phone\" />\n <SheetRow\n v-else\n :row=\"rows[item.index]!\"\n :index=\"item.index\"\n :row-no=\"store.rowNoOf(keyOf(rows[item.index]))\"\n :gutter=\"!phone\"\n :uid=\"uid\"\n :columns=\"columns\"\n :env=\"env\"\n :key-column=\"keyColumn\"\n :read=\"store.read\"\n :original=\"store.original\"\n :can-edit=\"sheet.canEdit\"\n :current=\"store.current\"\n :editor-for=\"sheet.editorFor\"\n :draft=\"store.rowDraft(keyOf(rows[item.index]))\"\n :issues=\"store.rowIssues(keyOf(rows[item.index]))\"\n :is-new=\"store.isNew(keyOf(rows[item.index]))\"\n :key-state=\"store.keyState(keyOf(rows[item.index]))\"\n :row-error=\"store.rowError(keyOf(rows[item.index]))\"\n :active=\"activeIndex === item.index ? active!.columnId : null\"\n :selection=\"selectionFor(item.index)\"\n :handle-at=\"handleFor(item.index)\"\n :fill=\"fillFor(item.index)\"\n :found=\"foundFor(item.index)\"\n :editing=\"editingFor(item.index)\"\n :tip-below=\"item.index === 0\"\n @edit-value=\"(v) => sheet.edit.setValue(v)\"\n @use-suggestion=\"(def, v) => sheet.useSuggestion(rows[item.index], def, v)\"\n />\n </div>\n </div>\n </div>\n <div\n v-if=\"fillLabel\"\n class=\"dt-fill-label\"\n role=\"status\"\n :style=\"{ left: `${fillLabel.left}px`, top: `${fillLabel.top}px` }\"\n >\n {{ fillLabel.text }}\n </div>\n <div v-if=\"$slots.state && !skeleton && rows.length === 0\" class=\"dt-body-state\"><slot name=\"state\" /></div>\n <SheetMenu :sheet=\"sheet\" :entity=\"entity\" :href=\"menuHref\" :read-only=\"readOnly || loading\" />\n </div>\n </ContextMenuTrigger>\n </ContextMenuRoot>\n</template>\n","// Düzenleme oturumu (07 §5): tek düzenlenen hücre; taslak değer burada durur, editör yalnızca düzenlenirken çizilir\n// (sanal kaydırmada kaybolmaz). Onaylayanlar: Enter/Tab, başka hücreye mousedown, ızgara dışına tık; Esc iptal; blur ile\n// onay yoktur. `inCell: false` formül çubuğundan düzenlemedir (hücre editör açmaz). Onayda '' → null.\nimport { shallowRef, type Component } from 'vue'\nimport type { ColumnDef } from '../types/columns'\nimport type { SheetStore } from './useSheetStore'\nimport type { SheetTable } from './useSheetTable'\n\nexport interface EditState<Row extends object> {\n row: Row\n def: ColumnDef<Row>\n value: unknown\n inCell: boolean\n /** Formül çubuğundan yazılan ham metin (çözümlenmiş değerden geri üretilmez: \"2,\" yazarken virgül kaybolmasın). */\n text?: string\n /** `multiselect` editörü yazarak açıldıysa: yazılan harf aramaya gider, değer korunur. */\n seed?: string\n}\n\nexport interface SheetEditingOptions<Row extends object> {\n store: SheetStore<Row>\n canEdit: (row: Row, def: ColumnDef<Row>) => boolean\n parse: (def: ColumnDef<Row>, text: string) => unknown\n}\n\nexport function useSheetEditing<Row extends object>(o: SheetEditingOptions<Row>) {\n const editing = shallowRef<EditState<Row> | null>(null)\n\n /** `replace`: yazarak açılış — içerik yazılanla değiştirilir; yoksa F2 / çift tık — mevcut değer, imleç sonda. */\n const start = (row: Row, def: ColumnDef<Row>, opts: { inCell: boolean; replace?: string }): boolean => {\n if (!o.canEdit(row, def)) return false\n // boolean'ın düzenleme modu yok (07 §5): Space / çift tık çevirir; özel editör verilmişse o açılır.\n if (def.type === 'boolean' && !def.editor) return false\n // Çoklu değerde yazmak chip'leri silmez (06 §7 T11-07): harf arama kutusuna gider.\n if (opts.replace !== undefined && !def.editor && def.type === 'multiselect') {\n editing.value = { row, def, value: o.store.read(row, def), inCell: opts.inCell, seed: opts.replace }\n return true\n }\n const value = opts.replace !== undefined ? o.parse(def, opts.replace) : o.store.read(row, def)\n editing.value = { row, def, value, inCell: opts.inCell, text: opts.replace }\n return true\n }\n const setValue = (value: unknown, text?: string, inCell?: boolean) => {\n const e = editing.value\n if (e) editing.value = { ...e, value, text, inCell: inCell ?? e.inCell }\n }\n const commit = (): boolean => {\n const e = editing.value\n if (!e) return false\n editing.value = null\n o.store.set(e.row, e.def, e.value === '' ? null : e.value)\n return true\n }\n const cancel = () => {\n editing.value = null\n }\n return { editing, start, setValue, commit, cancel }\n}\n\nexport type SheetEditing<Row extends object> = ReturnType<typeof useSheetEditing<Row>>\n\n/** DataSheet'in SheetGrid'e verdiği nesne: durum + niyetler (grid DOM'u, DataSheet kuralları yönetir). */\nexport interface SheetApi<Row extends object> {\n store: SheetStore<Row>\n table: SheetTable<Row>\n edit: SheetEditing<Row>\n canEdit: (row: Row, def: ColumnDef<Row>) => boolean\n editorFor: (def: ColumnDef<Row>) => Component | null\n /** `boolean` hücresinde Space. */\n toggle: (row: Row, def: ColumnDef<Row>) => void\n /** Delete / Backspace: seçimdeki düzenlenebilir hücreleri temizler. */\n clearCells: () => void\n /** ⌘S. */\n save: () => void\n /** F8 / ⇧F8. */\n goToError: (dir: 1 | -1) => void\n /** Pano olayları (07 §7): seçim TSV + HTML; yapıştırma aktif hücreden. İşlendiyse true (olay engellenir). */\n copy: (data: DataTransfer | null) => boolean\n cut: (data: DataTransfer | null) => boolean\n paste: (data: DataTransfer | null) => boolean\n /** Fill handle (07 §8): kaynak satır aralığı + sütun dizini aralığı → hedef satıra kadar. */\n fill: (fromRow: number, toRow: number, cols: [number, number], target: number) => void\n fillLabel: (fromRow: number, toRow: number, cols: [number, number], target: number) => string\n /** ⌘D. */\n fillDown: () => void\n undo: () => void\n redo: () => void\n /** Balondaki \"Use Pumps\". */\n useSuggestion: (row: Row, def: ColumnDef<Row>, value: unknown) => void\n /** Hücre menüsü (07 §9): panoya yaz / panodan oku (`navigator.clipboard`), satır ekle, listeden çıkar (⌘−). */\n copyToClipboard: (cut: boolean) => void\n pasteFromClipboard: () => void\n insertRow: (where: 'above' | 'below') => void\n removeSelectedRows: () => void\n /** Header tıklaması: yerel sıralama (07 §10). */\n sort: (columnId: string, additive: boolean) => void\n /** Sunucuda var olan satırın linki (\"Open product\"); yeni satırda undefined. */\n openHref: (row: Row) => string | undefined\n}\n","// Taslak deposu (07 §18, D11–D13): uygulamanın `rows` dizisine dokunmaz. Katmanlar, okuma sırasıyla:\n// draft Map<rowKey, Map<columnId, value>> — hücre başına, `Map.has` ile (bilinçli null korunur)\n// base Map<rowKey, Row> — kayıt sonrası sunucu satırı ya da Update satırının sunucu kaydı (07 §9, §14)\n// rows uygulamanın dizisi + `added` (yeni satırlar `new:n`, sunucu değeri yok, anahtar sütunu zorunlu)\n// Tek okuyucu `read`; render, doğrulama, kopyalama bunu kullanır. Doğrulama satır başına, hücre onaylanınca (07 §5):\n// tip → required → validate → warn; aynı satırın diğer hücreleri de yenilenir (çapraz kural); anahtar tekilliği (07 §9)\n// aynı anahtarı taşıyan tüm satırlarda. Sunucu hataları (`applyResult`) ayrı tutulur; hücre düzenlenince o hücreninki\n// temizlenir. Komut yığını (07 §12): adım = `{ patches, added, removed }`, 100 adım; `apply` toplu yazar.\n// Satır Map'leri her değişimde yeni nesnedir: yalnızca o satır yeniden çizilir.\nimport { computed, shallowReactive, shallowRef, toRaw, toValue, watch, type MaybeRefOrGetter } from 'vue'\nimport { isEmptyValue, optionLabel } from '../core/cells/format'\nimport { TYPE_SPECS } from '../core/cells/specs'\nimport { readPath } from '../core/columns/readPath'\nimport { toDate } from '../core/format'\nimport type { I18n } from '../core/i18n'\nimport type { ColumnDef, OptionDef } from '../types/columns'\nimport type { SheetChangeRow, SheetChanges, SheetRowResult } from '../types/sheet'\n\nexport interface Issue {\n level: 'error' | 'warning'\n message: string\n /** \"“Pump” isn't an option\" için yakın seçenek (balonda \"Use Pumps\"). */\n suggest?: OptionDef\n /** Sunucudan (`applyResult`): hücre düzenlenince temizlenir. */\n server?: boolean\n}\nexport interface Patch {\n key: string\n col: string\n before: unknown\n after: unknown\n}\nexport interface Step {\n patches: Patch[]\n /** Bu adımda eklenen satırlar (undo kaldırır, redo geri koyar). */\n added?: Array<{ key: string; row: object }>\n /** Bu adımda listeden çıkarılan satırlar (undo geri getirir). */\n removed?: string[]\n}\nexport interface Change<Row extends object> {\n row: Row\n def: ColumnDef<Row>\n value: unknown\n}\n/** Yeni satırın anahtar durumu (07 §9): kontrol sürüyor · sunucuda yok (New) · sunucuda var (Update). */\nexport type KeyState = 'checking' | 'new' | 'update'\n\nexport interface SheetStoreOptions<Row extends object> {\n rows: MaybeRefOrGetter<Row[]>\n columns: MaybeRefOrGetter<Array<ColumnDef<Row>>>\n rowKey: MaybeRefOrGetter<string>\n keyColumn: MaybeRefOrGetter<string>\n i18n: I18n\n locale: string\n}\n\nconst HISTORY = 100\n\n/** Boş değerler (null / undefined / '' / []) birbirine eşit sayılır; diziler elemanlarıyla. */\nconst same = (a: unknown, b: unknown): boolean =>\n (isEmptyValue(a) && isEmptyValue(b)) ||\n Object.is(a, b) ||\n (Array.isArray(a) && Array.isArray(b) && a.length === b.length && a.every((x, i) => Object.is(x, b[i])))\n\nfunction setPath(obj: Record<string, unknown>, path: string, value: unknown) {\n const keys = path.split('.')\n let o = obj\n for (const k of keys.slice(0, -1)) {\n const next = o[k]\n o[k] = next && typeof next === 'object' ? { ...(next as object) } : {}\n o = o[k] as Record<string, unknown>\n }\n o[keys[keys.length - 1]!] = value\n}\n\nconst fold = (s: string, locale: string) => s.trim().toLocaleLowerCase(locale).replace(/ı|i̇/g, 'i')\n/** Yakın seçenek: aynı başlangıç, içerme ya da ≤ 2 harf farkı. */\nfunction closest(options: OptionDef[], value: string, locale: string): OptionDef | undefined {\n const v = fold(value, locale)\n if (!v) return undefined\n const dist = (a: string, b: string): number => {\n const d = Array.from({ length: b.length + 1 }, (_, i) => i)\n for (let i = 1; i <= a.length; i++) {\n let prev = d[0]!\n d[0] = i\n for (let j = 1; j <= b.length; j++) {\n const tmp = d[j]!\n d[j] = Math.min(d[j]! + 1, d[j - 1]! + 1, prev + (a[i - 1] === b[j - 1] ? 0 : 1))\n prev = tmp\n }\n }\n return d[b.length]!\n }\n return (\n options.find((o) => fold(o.label, locale).startsWith(v) || v.startsWith(fold(o.label, locale))) ??\n options.find((o) => dist(fold(o.label, locale), v) <= 2)\n )\n}\n\nexport function useSheetStore<Row extends object>(o: SheetStoreOptions<Row>) {\n const t = o.i18n.t\n const defs = computed(() => toValue(o.columns))\n const defById = computed(() => new Map(defs.value.map((d) => [d.id as string, d])))\n const keyCol = () => toValue(o.keyColumn)\n const draft = shallowReactive(new Map<string, Map<string, unknown>>())\n const issues = shallowReactive(new Map<string, Map<string, Issue>>())\n /** Sunucu alan hataları ve satır hatası (07 §14). */\n const serverErrors = shallowReactive(new Map<string, Map<string, string>>())\n const rowErrors = shallowReactive(new Map<string, string>())\n /** Sunucu değerleri; `from` kayıt anındaki yüklenmiş satır nesnesi (uygulama satırı yenileyince base düşer). */\n const base = shallowReactive(new Map<string, { row: Row; from: Row | undefined }>())\n const added = shallowRef<Array<{ key: string; row: Row; saved?: boolean }>>([])\n const removed = shallowReactive(new Set<string>())\n const keyStates = shallowReactive(new Map<string, KeyState>())\n /** Her yazmada artar: seçim özeti gibi toplu okuyucular hücre başına bağımlılık kurmadan buna bağlanır. */\n const version = shallowRef(0)\n const undoStack: Step[] = []\n const redoStack: Step[] = []\n const canUndo = shallowRef(false)\n const canRedo = shallowRef(false)\n let newCounter = 0\n\n const keyOf = (row: Row): string => String(readPath(row, toValue(o.rowKey)))\n /** Parti: yüklenen + eklenen satırlar, listeden çıkarılanlar dahil (gutter numarası bu sıradır, 07 §3). */\n const batch = computed<Row[]>(() =>\n added.value.length ? [...toValue(o.rows), ...added.value.map((a) => a.row)] : toValue(o.rows),\n )\n const batchIndex = computed(() => {\n const m = new Map<string, number>()\n batch.value.forEach((r, i) => m.set(keyOf(r), i))\n return m\n })\n /** Gösterilen parti: çıkarılanlar hariç. */\n const allRows = computed<Row[]>(() =>\n removed.size ? batch.value.filter((r) => !removed.has(keyOf(r))) : batch.value,\n )\n const byKey = computed(() => {\n const m = new Map<string, Row>()\n for (const r of batch.value) m.set(keyOf(r), r)\n return m\n })\n const addedByKey = computed(() => new Map(added.value.map((a) => [a.key, a])))\n /** Yeni satır: eklenmiş ve henüz kaydedilmemiş (kaydedilince yüklenmiş sayılır, numarası kalır). */\n const isNew = (key: string) => !!addedByKey.value.get(key) && !addedByKey.value.get(key)!.saved\n const rowNoOf = (key: string) => (batchIndex.value.get(key) ?? -1) + 1\n\n const original = (row: Row, def: ColumnDef<Row>): unknown => {\n const key = keyOf(row)\n const b = base.get(key)\n if (b) return def.accessor ? def.accessor(b.row) : readPath(b.row, def.id as string)\n if (isNew(key)) return undefined\n return def.accessor ? def.accessor(row) : readPath(row, def.id as string)\n }\n const readFrom = (map: Map<string, Map<string, unknown>>, row: Row, def: ColumnDef<Row>): unknown => {\n const d = map.get(keyOf(row))\n const id = def.id as string\n return d?.has(id) ? d.get(id) : original(row, def)\n }\n const read = (row: Row, def: ColumnDef<Row>): unknown => readFrom(draft, row, def)\n /** Bağımlılık kurmadan okur (toplu özetler `version` ile yenilenir). */\n const readUntracked = (row: Row, def: ColumnDef<Row>): unknown => readFrom(toRaw(draft), row, def)\n /** Satırın güncel hali (doğrulama bağlamı, create yükü): base + taslak kopya üstüne; `rows` değişmez. */\n const current = (row: Row): Row => {\n const key = keyOf(row)\n const b = base.get(key)\n const d = draft.get(key)\n if (!b && !d?.size) return row\n const obj = { ...row, ...(b?.row as object) } as Record<string, unknown>\n for (const [col, v] of d ?? []) setPath(obj, col, v)\n return obj as Row\n }\n\n /** Anahtar değeri → o değeri taşıyan satır anahtarları (tekillik, 07 §9); çıkarılanlar sayılmaz. */\n const keyIndex = computed(() => {\n void version.value\n const m = new Map<string, Set<string>>()\n const def = defById.value.get(keyCol())\n if (!def) return m\n for (const row of allRows.value) {\n const v = readUntracked(row, def)\n if (isEmptyValue(v)) continue\n const k = String(v)\n let set = m.get(k)\n if (!set) m.set(k, (set = new Set()))\n set.add(keyOf(row))\n }\n return m\n })\n\n const typeIssue = (def: ColumnDef<Row>, value: unknown): Issue | null => {\n if (isEmptyValue(value)) return null\n const error = (message: string, suggest?: OptionDef): Issue => ({ level: 'error', message, suggest })\n if ((TYPE_SPECS[def.type].numeric || def.type === 'star') && typeof value !== 'number')\n return error(\n typeof value === 'string' && value.trim().startsWith('=') ? t('sheet.noFormulas') : t('sheet.notANumber'),\n )\n if ((def.type === 'date' || def.type === 'datetime') && Number.isNaN(toDate(value as string).getTime()))\n return error(t('sheet.notADate'))\n if (def.type === 'boolean' && typeof value !== 'boolean')\n return error(t('sheet.notAnOption', { value: String(value) }))\n if (def.type === 'select' && !def.options.some((opt) => opt.value === value))\n return error(t('sheet.notAnOption', { value: String(value) }), closest(def.options, String(value), o.locale))\n if (def.type === 'multiselect') {\n const bad = (Array.isArray(value) ? value : [value]).find((v) => !def.options.some((opt) => opt.value === v))\n if (bad !== undefined) return error(t('sheet.notAnOption', { value: String(bad) }))\n }\n return null\n }\n /** `optionEnabled`: satıra göre kapalı seçenek yalnızca değişen hücrede hata (mevcut değer kural değişince değil). */\n const optionIssue = (def: ColumnDef<Row>, value: unknown, ctx: { row: Row; original: unknown }): Issue | null => {\n if ((def.type !== 'select' && def.type !== 'multiselect') || !def.optionEnabled) return null\n if (isEmptyValue(value) || same(value, ctx.original)) return null\n const { options, optionEnabled } = def\n const bad = (Array.isArray(value) ? value : [value]).find((v) => {\n const opt = options.find((o) => o.value === v)\n return opt && !optionEnabled(opt, ctx.row)\n })\n return bad === undefined\n ? null\n : { level: 'error', message: t('sheet.notAnOption', { value: optionLabel(options, bad) }) }\n }\n const duplicateIssue = (key: string, value: unknown): Issue | null => {\n if (isEmptyValue(value)) return null\n const others = keyIndex.value.get(String(value))\n if (!others || others.size < 2) return null\n const other = [...others].find((k) => k !== key)\n return other\n ? { level: 'error', message: t('sheet.duplicateKey', { key: String(value), row: rowNoOf(other) }) }\n : null\n }\n const validateRow = (row: Row) => {\n const key = keyOf(row)\n const isNewRow = isNew(key)\n const cur = current(row)\n const map = new Map<string, Issue>()\n for (const def of defs.value) {\n const value = read(row, def)\n const ctx = { row: cur, isNew: isNewRow, original: original(row, def) }\n const isKey = def.id === keyCol()\n const required = def.required || (isNewRow && isKey)\n const issue =\n typeIssue(def, value) ??\n optionIssue(def, value, ctx) ??\n (required && isEmptyValue(value) ? { level: 'error' as const, message: t('sheet.required') } : null) ??\n // Yüklenmiş satırların anahtarı salt okunur: çift anahtar yalnızca yeni satır varken mümkün (10k indeks boşa kurulmaz).\n (isKey && (isNewRow || added.value.length) ? duplicateIssue(key, value) : null) ??\n (() => {\n const err = def.validate?.(value, ctx)\n if (err) return { level: 'error' as const, message: err }\n const warn = def.warn?.(value, ctx)\n return warn ? { level: 'warning' as const, message: warn } : null\n })()\n if (issue) map.set(def.id as string, issue)\n }\n if (map.size) issues.set(key, map)\n else issues.delete(key)\n }\n /** Anahtar sütunu değişince aynı değeri taşıyan diğer satırlar da yeniden doğrulanır (çift anahtar belirir/kalkar). */\n const revalidateKeys = (values: unknown[]) => {\n for (const v of values) {\n if (isEmptyValue(v)) continue\n for (const k of keyIndex.value.get(String(v)) ?? []) {\n const row = byKey.value.get(k)\n if (row) validateRow(row)\n }\n }\n }\n\n /** Ham yazma: satır başına tek Map kopyası ve tek doğrulama. Yama listesi döner (undo için `before`). */\n const write = (changes: Array<Change<Row>>): Patch[] => {\n const patches: Patch[] = []\n const touched = new Map<string, { row: Row; map: Map<string, unknown> }>()\n const keyValues: unknown[] = []\n for (const c of changes) {\n const key = keyOf(c.row)\n const id = c.def.id as string\n const before = read(c.row, c.def)\n if (same(before, c.value)) continue\n let entry = touched.get(key)\n if (!entry) touched.set(key, (entry = { row: c.row, map: new Map(draft.get(key)) }))\n if (same(c.value, original(c.row, c.def))) entry.map.delete(id)\n else entry.map.set(id, c.value)\n patches.push({ key, col: id, before, after: c.value })\n if (id === keyCol()) keyValues.push(before, c.value)\n // Hücre düzenlenince o hücrenin sunucu hatası temizlenir; satır hatası da düşer (07 §14).\n const se = serverErrors.get(key)\n if (se?.has(id)) {\n const next = new Map(se)\n next.delete(id)\n if (next.size) serverErrors.set(key, next)\n else serverErrors.delete(key)\n }\n rowErrors.delete(key)\n }\n for (const [key, { map }] of touched) {\n if (map.size) draft.set(key, map)\n else draft.delete(key)\n }\n if (patches.length) version.value++\n for (const { row, map } of touched.values()) {\n if (map.size || isNew(keyOf(row))) validateRow(row)\n else issues.delete(keyOf(row))\n }\n if (keyValues.length) revalidateKeys(keyValues)\n return patches\n }\n const syncHistory = () => {\n canUndo.value = undoStack.length > 0\n canRedo.value = redoStack.length > 0\n }\n const record = (step: Step) => {\n undoStack.push(step)\n if (undoStack.length > HISTORY) undoStack.shift()\n redoStack.length = 0\n syncHistory()\n }\n\n /** Tek kullanıcı işlemi = tek undo adımı; boş değişiklik kaydedilmez. */\n const apply = (changes: Array<Change<Row>>, addedRows: Array<{ key: string; row: Row }> = []): Patch[] => {\n const patches = write(changes)\n if (patches.length || addedRows.length) record({ patches, added: addedRows.length ? addedRows : undefined })\n return patches\n }\n const set = (row: Row, def: ColumnDef<Row>, value: unknown) => apply([{ row, def, value }])\n\n /** Yeni satırlar (07 §9): anahtar `new:n`, numara mevcut satırların devamı; anahtar yazılınca doğrulanır. */\n const addRows = (count: number): Array<{ key: string; row: Row }> => {\n const rows = Array.from({ length: count }, () => {\n const key = `new:${++newCounter}`\n const row = {} as Record<string, unknown>\n setPath(row, toValue(o.rowKey), key)\n return { key, row: row as Row }\n })\n added.value = [...added.value, ...rows]\n version.value++\n for (const r of rows) {\n keyStates.set(r.key, 'new')\n validateRow(r.row)\n }\n return rows\n }\n const dropAdded = (keys: string[]) => {\n const drop = new Set(keys)\n added.value = added.value.filter((a) => !drop.has(a.key))\n for (const k of keys) {\n draft.delete(k)\n issues.delete(k)\n keyStates.delete(k)\n base.delete(k)\n }\n version.value++\n }\n /** Listeden çıkarma (D12): sunucuda silmez; değişiklikleri gönderilmez; tek undo adımı. */\n const removeRows = (keys: string[]) => {\n const keyDef = defById.value.get(keyCol())\n const values = keyDef ? keys.map((k) => byKey.value.get(k)).map((r) => (r ? read(r, keyDef) : null)) : []\n for (const k of keys) removed.add(k)\n version.value++\n record({ patches: [], removed: keys })\n revalidateKeys(values)\n }\n const restoreRows = (keys: string[]) => {\n for (const k of keys) removed.delete(k)\n version.value++\n const keyDef = defById.value.get(keyCol())\n if (keyDef) revalidateKeys(keys.map((k) => byKey.value.get(k)).map((r) => (r ? read(r, keyDef) : null)))\n }\n\n const replay = (step: Step, dir: 'undo' | 'redo') => {\n if (dir === 'undo' && step.added) dropAdded(step.added.map((a) => a.key))\n if (dir === 'redo' && step.added) {\n added.value = [...added.value, ...(step.added as Array<{ key: string; row: Row }>)]\n for (const a of step.added) keyStates.set(a.key, 'new')\n version.value++\n }\n if (step.removed) {\n if (dir === 'undo') restoreRows(step.removed)\n else {\n for (const k of step.removed) removed.add(k)\n version.value++\n }\n }\n const changes: Array<Change<Row>> = []\n for (const p of step.patches) {\n const row = byKey.value.get(p.key)\n const def = defById.value.get(p.col)\n if (row && def) changes.push({ row, def, value: dir === 'undo' ? p.before : p.after })\n }\n write(changes)\n if (dir === 'redo' && step.added) for (const a of step.added) validateRow(a.row as Row)\n }\n const undo = (): Step | null => {\n const step = undoStack.pop()\n if (!step) return null\n replay(step, 'undo')\n redoStack.push(step)\n syncHistory()\n return step\n }\n const redo = (): Step | null => {\n const step = redoStack.pop()\n if (!step) return null\n replay(step, 'redo')\n undoStack.push(step)\n syncHistory()\n return step\n }\n const clearHistory = () => {\n undoStack.length = 0\n redoStack.length = 0\n syncHistory()\n }\n\n const rowDraft = (key: string) => draft.get(key)\n /** İstemci + sunucu hataları (sunucu hatası olan birkaç satırda birleşik Map). */\n const rowIssues = (key: string): Map<string, Issue> | undefined => {\n const client = issues.get(key)\n const server = serverErrors.get(key)\n if (!server) return client\n const merged = new Map(client)\n for (const [col, message] of server)\n if (!merged.has(col)) merged.set(col, { level: 'error', message, server: true })\n return merged\n }\n const rowError = (key: string) => rowErrors.get(key)\n const hasError = (key: string): boolean => {\n if (serverErrors.has(key) || rowErrors.has(key)) return true\n const m = issues.get(key)\n if (!m) return false\n for (const i of m.values()) if (i.level === 'error') return true\n return false\n }\n const keyState = (key: string): KeyState | undefined => keyStates.get(key)\n const setKeyState = (key: string, state: KeyState) => {\n if (addedByKey.value.has(key)) keyStates.set(key, state)\n }\n /** Update satırı (07 §9, Q2): sunucu kaydı orijinal sayılır; boş hücreler onunla dolar, yalnızca değişenler gider. */\n const setBase = (key: string, row: Row) => {\n base.set(key, { row, from: isNew(key) ? undefined : byKey.value.get(key) })\n version.value++\n const r = byKey.value.get(key)\n if (r) {\n // Taslakta sunucuyla aynı olan değerler düşer.\n const d = draft.get(key)\n if (d) {\n const next = new Map(d)\n for (const [col, v] of d) {\n const def = defById.value.get(col)\n if (def && same(v, original(r, def))) next.delete(col)\n }\n if (next.size) draft.set(key, next)\n else draft.delete(key)\n }\n validateRow(r)\n }\n }\n\n const counts = computed(() => {\n let changedCells = 0\n const changedKeys = new Set<string>()\n for (const [k, m] of draft) {\n if (removed.has(k)) continue\n changedCells += m.size\n changedKeys.add(k)\n }\n let errorRows = 0\n let warningRows = 0\n const errorKeys = new Set<string>([...serverErrors.keys(), ...rowErrors.keys()])\n for (const [k, m] of issues) {\n if (removed.has(k)) continue\n let w = false\n for (const i of m.values())\n if (i.level === 'error') errorKeys.add(k)\n else w = true\n if (w) warningRows++\n }\n for (const k of errorKeys) if (!removed.has(k)) errorRows++\n let newRows = 0\n let changedOrNewRows = changedKeys.size\n for (const a of added.value) {\n if (a.saved || removed.has(a.key)) continue\n newRows++\n if (!changedKeys.has(a.key)) changedOrNewRows++\n }\n return { changedCells, changedRows: changedKeys.size, errorRows, warningRows, newRows, changedOrNewRows }\n })\n\n /** Discard: taslak, hatalar, yeni satırlar, çıkarılanlar ve yığın gider; base kalır (kaydedilmiş değerler). */\n const reset = () => {\n draft.clear()\n issues.clear()\n serverErrors.clear()\n rowErrors.clear()\n added.value = []\n removed.clear()\n keyStates.clear()\n clearHistory()\n version.value++\n }\n\n /** Kayıt başlarken: sunucuda var olan (Update) ve hiç değişmemiş yeni satırlar gönderilecek bir şey taşımaz; yüklenmiş sayılır. */\n const settleUntouched = () => {\n let changed = false\n const next = added.value.map((a) => {\n if (a.saved || removed.has(a.key) || keyStates.get(a.key) !== 'update' || draft.get(a.key)?.size) return a\n changed = true\n keyStates.delete(a.key)\n issues.delete(a.key)\n return { ...a, saved: true }\n })\n if (changed) {\n added.value = next\n version.value++\n }\n }\n\n /** `@save` yükü (D11, D12): değişmiş + yeni, hatasız, çıkarılmamış satırlar; güncellemede yalnızca değişen alanlar. */\n const getChanges = (): SheetChanges => {\n const keyDef = defById.value.get(keyCol())\n const rows: SheetChangeRow[] = []\n for (const [key, m] of draft) {\n const row = byKey.value.get(key)\n if (!row || removed.has(key) || hasError(key)) continue\n const create = isNew(key) && keyStates.get(key) !== 'update'\n const values = Object.fromEntries([...m].filter(([, v]) => !create || !isEmptyValue(v)))\n rows.push({\n clientId: key,\n key: String(keyDef ? read(row, keyDef) : readPath(row, keyCol())),\n op: create ? 'create' : 'update',\n values,\n })\n }\n rows.sort((a, b) => rowNoOf(a.clientId) - rowNoOf(b.clientId))\n return { rows }\n }\n\n /** Kayıt sonuçları (07 §14): created/updated → taslak düşer, değerler `row` ya da uygulanmış taslak; error → kalır. */\n const applyResult = (results: Array<SheetRowResult<Row>>) => {\n let created = 0\n let updated = 0\n let errors = 0\n for (const r of results) {\n const key = r.clientId\n const row = byKey.value.get(key)\n if (!row) continue\n if (r.status === 'error') {\n errors++\n const fe = r.fieldErrors ? new Map(Object.entries(r.fieldErrors)) : null\n if (fe?.size) serverErrors.set(key, fe)\n else serverErrors.delete(key)\n if (r.rowError) rowErrors.set(key, r.rowError)\n else rowErrors.delete(key)\n continue\n }\n if (r.status === 'created') created++\n else updated++\n base.set(key, { row: r.row ?? current(row), from: isNew(key) ? undefined : row })\n draft.delete(key)\n issues.delete(key)\n serverErrors.delete(key)\n rowErrors.delete(key)\n keyStates.delete(key)\n const a = addedByKey.value.get(key)\n if (a) added.value = added.value.map((x) => (x.key === key ? { ...x, saved: true } : x))\n }\n clearHistory()\n version.value++\n return { created, updated, errors }\n }\n // Uygulama satırları yenileyince (yeni nesneler) o anahtarların base'i düşer; aynı nesneler (eski/gecikmiş dizi) düşürmez.\n watch(\n () => toValue(o.rows),\n (rows) => {\n if (!base.size) return\n const byId = new Map<string, Row>()\n for (const r of rows) byId.set(keyOf(r), r)\n for (const [key, b] of base) {\n const now = byId.get(key)\n if (b.from && now && now !== b.from) base.delete(key)\n }\n version.value++\n },\n )\n\n return {\n keyOf,\n batch,\n allRows,\n rowByKey: (key: string) => byKey.value.get(key),\n rowNoOf,\n isNew,\n isRemoved: (key: string) => removed.has(key),\n keyState,\n setKeyState,\n setBase,\n read,\n readUntracked,\n original,\n current,\n set,\n apply,\n addRows,\n removeRows,\n undo,\n redo,\n canUndo,\n canRedo,\n clearHistory,\n version,\n rowDraft,\n rowIssues,\n rowError,\n hasError,\n counts,\n reset,\n getChanges,\n settleUntouched,\n applyResult,\n }\n}\n\nexport type SheetStore<Row extends object> = ReturnType<typeof useSheetStore<Row>>\n","// Hücre seçimi (01 · TanStack sınırı, D23): TanStack `cellSelectionFeature`, tek aralık (⌘-tık ile çoklu aralık yok, 07 §6).\n// Aktif hücre = aralığın çapası (roving tabindex 0). Sütun sırası ve görünürlüğü düzenden (useColumnLayout) gelir; satır\n// sırası gösterilen dizidir. DOM'a dokunmaz; odak ve kaydırma SheetGrid'de.\nimport { cellSelectionFeature, tableFeatures, useTable, type ColumnDef as TanstackColumnDef } from '@tanstack/vue-table'\nimport { computed, toValue, type MaybeRefOrGetter } from 'vue'\n\nconst features = tableFeatures({ cellSelectionFeature })\ntype Features = typeof features\n\nexport type Direction = 'up' | 'down' | 'left' | 'right'\n\n/** Gösterilen satır/sütun dizinlerinde dikdörtgen (TanStack `getCellSelectionBounds`). */\nexport interface SheetBounds {\n minRowIndex: number\n maxRowIndex: number\n minColumnIndex: number\n maxColumnIndex: number\n}\n\nexport interface SheetTableOptions<Row extends object> {\n rows: MaybeRefOrGetter<Row[]>\n /** Görünür sütunlar, çizim sırasında. */\n columnIds: MaybeRefOrGetter<string[]>\n rowId: (row: Row) => string\n}\n\nexport function useSheetTable<Row extends object>(o: SheetTableOptions<Row>) {\n const columns = computed<Array<TanstackColumnDef<Features, Row, unknown>>>(() =>\n toValue(o.columnIds).map((id) => ({ id, accessorFn: () => undefined })),\n )\n const table = useTable<Features, Row>({\n features,\n columns,\n data: computed(() => toValue(o.rows)),\n getRowId: o.rowId,\n // Satırlar parça parça gelirken (loading) seçim kaybolmasın; tek aralık (07 §6).\n autoResetCellSelection: false,\n enableMultiCellRangeSelection: false,\n })\n\n const active = computed<{ rowId: string; columnId: string } | null>(() => {\n const ranges = table.atoms.cellSelection.get()\n const a = ranges[ranges.length - 1]\n return a ? { rowId: a.anchorRowId, columnId: a.anchorColumnId } : null\n })\n const bounds = computed<SheetBounds | null>(() => table.getCellSelectionBounds()[0] ?? null)\n /** Aralığın hareket eden ucu (TanStack range focus): ⇧+ok ile genişlerken görünür alana getirilir. */\n const rangeEnd = computed<{ rowId: string; columnId: string } | null>(() => {\n const r = table.atoms.cellSelection.get()[0]\n return r ? { rowId: r.focusRowId, columnId: r.focusColumnId } : null\n })\n const cell = (rowId: string, columnId: string) =>\n table.getCoreRowModel().rowsById[rowId]?.getAllCellsByColumnId()[columnId]\n\n return {\n active,\n bounds,\n rangeEnd,\n focus: (rowId: string, columnId: string) => table.setFocusedCell(rowId, columnId),\n move: (d: Direction) => table.moveCellSelection(d),\n extend: (d: Direction) => table.extendCellSelection(d),\n selectAll: () => table.selectAllCells(),\n /** Gutter tıklaması: satır aralığının tüm hücreleri (07 §6). */\n selectRange: (range: { anchorRowId: string; anchorColumnId: string; focusRowId: string; focusColumnId: string }) =>\n table.selectCellRange(range),\n clear: () => table.resetCellSelection(true),\n /** Fare: mousedown (⇧ ile genişletme, sürükleme başlangıcı) ve sürüklerken mouseover (TanStack handler'ları). */\n startHandler: (rowId: string, columnId: string) => cell(rowId, columnId)?.getSelectionStartHandler(),\n extendHandler: (rowId: string, columnId: string) => cell(rowId, columnId)?.getSelectionExtendHandler(),\n }\n}\n\nexport type SheetTable<Row extends object> = ReturnType<typeof useSheetTable<Row>>\n","<script setup lang=\"ts\" generic=\"Row extends object\">\n// DataSheet (07, brief §8, handoff 06) — Faz 6a–6c: ızgara, editörler, doğrulama, taslak deposu; toolbar'da Find,\n// All / Changed / Errors, Undo/Redo, Add row, Display + Save kontrolleri; formül çubuğu; status bar; açılış ilerlemesi;\n// pano, fill handle, komut yığını; satır partisi (ekle / çıkar, lookupKeys New/Update, anahtar tekilliği); yerel\n// sıralama; kayıt akışı (hata dialog'u, `@save`, `saving`, `applyResult`, Partly saved şeridi, Copy errors); ayrılma\n// koruması. İçe/dışa aktarma ve telefon düzeni (6d) sonraki fazda. Veri çekmez, kaydetmez (D18): yalnızca `@save` yayar.\nimport {\n PhArrowUUpLeft,\n PhArrowUUpRight,\n PhCaretDown,\n PhCaretUp,\n PhCheck,\n PhCircleNotch,\n PhCopy,\n PhLock,\n PhDownloadSimple,\n PhExport,\n PhLink,\n PhMonitor,\n PhPlus,\n PhWarning,\n PhWarningCircle,\n} from '@phosphor-icons/vue'\nimport {\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuPortal,\n DropdownMenuRoot,\n DropdownMenuSub,\n DropdownMenuSubContent,\n DropdownMenuSubTrigger,\n DropdownMenuTrigger,\n ToggleGroupItem,\n ToggleGroupRoot,\n} from 'reka-ui'\nimport {\n computed,\n nextTick,\n onBeforeUnmount,\n onMounted,\n provide,\n ref,\n shallowRef,\n type Component,\n useTemplateRef,\n watch,\n} from 'vue'\nimport { comparator } from '../core/cells/compare'\nimport { formatCell, isEmptyValue, optionLabel, type FormatEnv } from '../core/cells/format'\nimport { RemoteLabels } from '../core/cells/remoteLabels'\nimport { TYPE_SPECS, typeLabelKey } from '../core/cells/specs'\nimport { useColumnLayout } from '../core/columns/useColumnLayout'\nimport { getFormat } from '../core/format'\nimport { useDelegatedTooltip } from '../core/grid/useDelegatedTooltip'\nimport { FIND_KBD, REDO_KBD, SAVE_KBD, UNDO_KBD } from '../core/interaction/kbd'\nimport { useDataTableContext } from '../core/plugin'\nimport { usePreferences } from '../core/preferences/usePreferences'\nimport StateMessage from '../core/states/StateMessage.vue'\nimport DisplayPopover from '../core/toolbar/DisplayPopover.vue'\nimport SearchBox from '../core/toolbar/SearchBox.vue'\nimport ConfirmDialog from '../core/ui/ConfirmDialog.vue'\nimport type { ColumnDef, ColumnType } from '../types/columns'\nimport type { Density, Plural, TableId } from '../types/core'\nimport type { SortRule } from '../types/query'\nimport type {\n ParsedWorkbook,\n Progress,\n SheetChanges,\n SheetFilterMode,\n SheetRowResult,\n SheetStatus,\n} from '../types/sheet'\nimport { matrixFromClipboard, parseTsv, toHtml, toTsv } from './clipboard'\nimport NumberCell from './editors/NumberCell.vue'\nimport OptionCell from './editors/OptionCell.vue'\nimport TextCell from './editors/TextCell.vue'\nimport DateCell from './editors/DateCell.vue'\nimport MultiCell from './editors/MultiCell.vue'\nimport { SHEET_EDITOR_KEY } from './editors/context'\nimport { fillValues } from './fill'\nimport ImportDialog, { type ImportPayload } from './ImportDialog.vue'\nimport { inferDecimal, inputText, parseInput, type ParseEnv } from './parse'\nimport SaveErrorsDialog, { type ErrorRowItem } from './SaveErrorsDialog.vue'\nimport SheetGrid from './SheetGrid.vue'\nimport { useSheetEditing, type SheetApi } from './useSheetEditing'\nimport { useSheetStore, type Change, type Step } from './useSheetStore'\nimport { useSheetTable } from './useSheetTable'\n\nconst props = withDefaults(\n defineProps<{\n tableId: TableId\n columns: Array<ColumnDef<Row>>\n rows: Row[]\n rowKey?: string\n /** Verilmezse tercihten (Display › Density), o da yoksa compact (02 · Yoğunluk). */\n density?: Density\n entityName?: Plural\n /** Upsert anahtarı olan sütun (ör. \"sku\"). Yüklenmiş satırlarda salt okunur; `rowKey`'den ayrıdır. */\n keyColumn: string\n /** Uygulama satırları yüklerken; sayaç verilirse \"Loading… 6,200 of 10,000\". Düzenleme false olunca açılır. */\n loading?: Progress\n /** `@save` sonrası uygulama kaydederken: grid salt okunur, ilerleme şeridi (07 §14). */\n saving?: Progress\n /** Yeni satırlarda yazılan anahtarların kontrolü (New / Update, 07 §9). Verilmezse her bilinmeyen anahtar New. */\n lookupKeys?: (keys: string[], ctx: { signal: AbortSignal }) => Promise<Record<string, Row | null>>\n /** Add row ile oluşan satırın başlangıç değerleri. */\n newRowDefaults?: () => Partial<Row>\n /** Import Excel / CSV: dosyayı uygulama ayrıştırır ve ham satırları verir (07 §13). Verilmezse Import yok. */\n parseFile?: (file: File) => Promise<ParsedWorkbook>\n /** Aşılırsa ilk `maxRows` satır kullanılır ve şerit uyarır (07 §15); yapıştırma ve ekleme bu sınırı aşamaz. */\n maxRows?: number\n /** Bu genişliğin altında veya yalnızca dokunmatikte salt okunur (D14); karar açılışta. */\n readOnlyBelow?: number\n }>(),\n { rowKey: 'id', loading: false, saving: false, maxRows: 10_000, readOnlyBelow: 768 },\n)\nconst emit = defineEmits<{\n /** Save: doğrulama geçen değişmiş + yeni satırlar. Uygulama kaydeder, `saving` verir, `applyResult` çağırır. */\n save: [changes: SheetChanges]\n /** Export: değerler güncel (kaydedilmemiş değişiklikler dahil); dosyayı uygulama yazar. */\n export: [payload: { format: 'csv' | 'xlsx'; scope: 'all' | 'visible'; columns: string[]; rows: Row[] }]\n}>()\ndefineSlots<{ empty?: () => unknown }>()\n\nconst ctx = useDataTableContext()\nconst { i18n } = ctx\nconst fmt = getFormat(ctx.locale)\nconst entity = computed<Plural>(() => props.entityName ?? { one: props.tableId, other: props.tableId })\n\nconst pref = usePreferences(() => props.tableId, ctx.preferences, {\n density: props.density ?? 'compact',\n verticalLines: true,\n pageSize: 0,\n defaultViewId: null,\n})\nconst density = computed<Density>(() => props.density ?? pref.prefs.density)\n\nconst overLimit = computed(() => props.rows.length > props.maxRows)\nconst loadedRows = computed(() => (overLimit.value ? props.rows.slice(0, props.maxRows) : props.rows))\nconst loadingNow = computed(() => props.loading !== false)\nconst savingNow = computed(() => props.saving !== false)\nconst progress = computed(() => {\n const p = loadingNow.value ? props.loading : props.saving\n return typeof p === 'object' ? p : null\n})\nconst percent = computed(() =>\n progress.value && progress.value.total > 0 ? Math.round((100 * progress.value.done) / progress.value.total) : null,\n)\n\n// Sütunlar (07 §3): anahtar 128 px sola sabit (mono), birincil ad sola sabit ve esnek; sıra sabit, genişlik oturumluk.\n// Telefon / yalnızca dokunmatik: salt okunur, karar açılışta (D14, 07 §17): anahtar 104 px sabit, kalanlar kayar.\nconst readOnlyDevice =\n typeof matchMedia === 'function' &&\n (matchMedia(`(max-width: ${props.readOnlyBelow - 1}px)`).matches || !matchMedia('(any-pointer: fine)').matches)\nconst sheetColumns = computed<Array<ColumnDef<Row>>>(() =>\n props.columns.map((d) =>\n d.id === props.keyColumn\n ? { ...d, pinned: 'left', width: readOnlyDevice ? 104 : 128 }\n : d.primary && !readOnlyDevice\n ? { ...d, pinned: 'left' }\n : d,\n ),\n)\nconst defById = computed(() => new Map(sheetColumns.value.map((d) => [d.id as string, d])))\nconst keyDef = computed(() => defById.value.get(props.keyColumn))\nconst primaryDef = computed(() => sheetColumns.value.find((d) => d.primary))\nconst store = useSheetStore<Row>({\n rows: loadedRows,\n columns: sheetColumns,\n rowKey: () => props.rowKey,\n keyColumn: () => props.keyColumn,\n i18n,\n locale: ctx.locale,\n})\n\n// Gösterim sırası (07 §10–11): parti sırası ya da header tıklamasında alınan sıralama anlık görüntüsü (düzenlenen satır\n// imlecin altından kaçmaz); eklenen satır yerine konur; All / Changed / Errors görünümü ve çıkarılanlar süzülür.\nconst sortRules = ref<SortRule[]>([])\nconst order = shallowRef<string[] | null>(null)\nconst view = ref<SheetFilterMode>('all')\nconst viewKeys = shallowRef(new Set<string>())\nconst matchesView = (key: string) =>\n view.value === 'changed'\n ? !!store.rowDraft(key)?.size || store.isNew(key)\n : view.value === 'errors'\n ? store.hasError(key)\n : true\nconst refreshView = (union: boolean) => {\n const next = union ? new Set(viewKeys.value) : new Set<string>()\n for (const r of store.batch.value) {\n const k = store.keyOf(r)\n if (matchesView(k)) next.add(k)\n }\n viewKeys.value = next\n}\n/** Görünüm değişimi eşzamanlı uygulanır: hemen ardından gelen `goToError` doğru satır listesini görür. */\nconst setView = (v: SheetFilterMode) => {\n view.value = v\n refreshView(false)\n}\n// Görünümde kalma kuralı: son hatayı düzelttiğin satır görünümden çıkana kadar yerinde kalır; yeni uyanlar eklenir.\nwatch(store.version, () => {\n if (view.value !== 'all') refreshView(true)\n})\nconst orderedBatch = computed<Row[]>(() => {\n const batch = store.batch.value\n const o = order.value\n if (!o) return batch\n const seen = new Set(o)\n const rows: Row[] = []\n for (const k of o) {\n const r = store.rowByKey(k)\n if (r) rows.push(r)\n }\n for (const r of batch) if (!seen.has(store.keyOf(r))) rows.push(r)\n return rows\n})\n/** Gösterilen satırlar: sıra + görünüm + çıkarılanlar. */\nconst rowsAll = computed<Row[]>(() => {\n const all = view.value === 'all'\n const keys = viewKeys.value\n return orderedBatch.value.filter((r) => {\n const k = store.keyOf(r)\n return !store.isRemoved(k) && (all || keys.has(k))\n })\n})\nconst layout = useColumnLayout<Row>({\n columns: sheetColumns,\n rows: rowsAll,\n rowKey: () => props.rowKey,\n flexLastStart: true,\n})\nconst table = useSheetTable<Row>({\n rows: rowsAll,\n columnIds: () => layout.columns.value.map((c) => c.id),\n rowId: store.keyOf,\n})\nconst indexByKey = computed(() => {\n const m = new Map<string, number>()\n rowsAll.value.forEach((r, i) => m.set(store.keyOf(r), i))\n return m\n})\nconst visibleCols = computed(() => layout.columns.value)\n\nconst readOnlyNow = computed(() => loadingNow.value || savingNow.value || readOnlyDevice)\n\n// Editörler filtre değer girişleriyle aynı aileden (07 §5); `boolean` editör açmaz (Space). ajax/user/object/array için\n// yalnızca özel editör (`ColumnDef.editor`).\nconst EDITORS: Partial<Record<ColumnType, Component>> = {\n string: TextCell,\n text: TextCell,\n uppercase: TextCell,\n lowercase: TextCell,\n email: TextCell,\n url: TextCell,\n phone: TextCell,\n id: TextCell,\n color: TextCell,\n int: NumberCell,\n float: NumberCell,\n percentage: NumberCell,\n currency: NumberCell,\n star: NumberCell,\n select: OptionCell,\n multiselect: MultiCell,\n date: DateCell,\n datetime: DateCell,\n}\nconst editorFor = (def: ColumnDef<Row>): Component | null => def.editor ?? EDITORS[def.type] ?? null\n/** Sütunlar varsayılan salt okunur; anahtar sütun yüklenmiş satırlarda her zaman (yeni satırda açık); yüklenirken, kaydederken ve telefonda hiçbiri. */\nconst canEdit = (row: Row, def: ColumnDef<Row>): boolean => {\n if (readOnlyNow.value) return false\n const isNew = store.isNew(store.keyOf(row))\n if (def.id === props.keyColumn) return isNew\n if (def.type !== 'boolean' && !editorFor(def)) return false\n return typeof def.editable === 'function' ? def.editable(store.current(row), { isNew }) : def.editable === true\n}\n\nconst parseEnv = (locale = ctx.locale): ParseEnv => ({\n locale,\n today: new Date(),\n todayWord: i18n.t('date.today'),\n yesWord: i18n.t('common.yes'),\n noWord: i18n.t('common.no'),\n})\nconst edit = useSheetEditing<Row>({ store, canEdit, parse: (def, text) => parseInput(def, text, parseEnv()) })\nprovide(SHEET_EDITOR_KEY, { seed: () => edit.editing.value?.seed })\nconst grid = useTemplateRef<InstanceType<typeof SheetGrid>>('grid')\nconst counts = store.counts\nconst fmtEnv: FormatEnv = { fmt, i18n, today: new Date(), labels: new RemoteLabels() }\n\n/** Aralığı seçer ve odaklar (yapıştırma, doldurma, undo sonrası). */\nconst selectCells = (r1: number, c1: number, r2: number, c2: number) => {\n const rows = rowsAll.value\n const cols = visibleCols.value\n const a = rows[r1]\n const b = rows[r2]\n if (!a || !b || !cols[c1] || !cols[c2]) return\n table.selectRange({\n anchorRowId: store.keyOf(a),\n anchorColumnId: cols[c1]!.id,\n focusRowId: store.keyOf(b),\n focusColumnId: cols[c2]!.id,\n })\n grid.value?.focusActive()\n}\nconst focusCell = (r: number, columnId: string) => {\n const row = rowsAll.value[Math.max(0, Math.min(rowsAll.value.length - 1, r))]\n if (!row) return\n table.focus(store.keyOf(row), columnId)\n grid.value?.focusActive()\n}\n/** Seçimdeki (ya da aktif) hücreler. */\nconst selectedCells = (): Array<{ r: number; c: number }> => {\n const b = table.bounds.value\n if (!b) return []\n const out: Array<{ r: number; c: number }> = []\n for (let r = b.minRowIndex; r <= b.maxRowIndex; r++)\n for (let c = b.minColumnIndex; c <= b.maxColumnIndex; c++) out.push({ r, c })\n return out\n}\n\nconst toggle = (row: Row, def: ColumnDef<Row>) => store.set(row, def, !store.read(row, def))\n/** Delete / ⌘X: seçimdeki düzenlenebilir hücreler boşalır, tek adım. */\nconst clearSelected = () => {\n const changes: Array<Change<Row>> = []\n for (const { r, c } of selectedCells()) {\n const row = rowsAll.value[r]\n const def = visibleCols.value[c]?.def\n if (row && def && canEdit(row, def)) changes.push({ row, def, value: null })\n }\n store.apply(changes)\n}\n\n// Hatalar (07 §11, §14): gösterim sırasında; görünüm gizliyorsa toast \"Next error is hidden by filters · Show it\".\nconst errorKeysInOrder = computed(() => {\n void store.version.value\n return orderedBatch.value.map((r) => store.keyOf(r)).filter((k) => !store.isRemoved(k) && store.hasError(k))\n})\nconst goToError = (dir: 1 | -1) => {\n const rows = rowsAll.value\n const n = rows.length\n const a = table.active.value\n const from = a ? (indexByKey.value.get(a.rowId) ?? -1) : -1\n for (let s = 1; s <= n; s++) {\n const i = (((from + dir * s) % n) + n) % n\n const key = store.keyOf(rows[i]!)\n if (!store.hasError(key)) continue\n const issues = store.rowIssues(key)\n const col =\n visibleCols.value.find((c) => issues?.get(c.id)?.level === 'error') ??\n (store.rowError(key) ? visibleCols.value.find((c) => c.id === props.keyColumn) : undefined)\n if (!col) continue\n table.focus(key, col.id)\n grid.value?.focusActive()\n return\n }\n if (errorKeysInOrder.value.length && view.value !== 'all')\n showToast({\n text: i18n.t('sheet.nextErrorHidden'),\n action: {\n label: i18n.t('sheet.showIt'),\n run: () => {\n setView('all')\n goToError(dir)\n },\n },\n })\n}\n\n// Pano (07 §7): görüntülenen biçimde TSV + HTML; para kodu ve \"—\" yok, tarihler ISO, listeler `; ` ile (geri yapıştırılabilir).\nconst copyText = (def: ColumnDef<Row>, row: Row, value: unknown): string => {\n if (isEmptyValue(value)) return ''\n switch (def.type) {\n case 'currency':\n return fmt.decimal(Number(value), def.decimalPlaces ?? 2)\n case 'date':\n case 'datetime':\n return value instanceof Date ? value.toISOString() : String(value)\n case 'multiselect':\n return (value as unknown[]).map((v) => optionLabel(def.options, v)).join('; ')\n case 'string':\n case 'text':\n case 'uppercase':\n case 'lowercase':\n case 'email':\n case 'url':\n case 'phone':\n case 'id':\n return String(value)\n default:\n return formatCell(def, row, value, fmtEnv)\n }\n}\nconst copyMatrix = (): string[][] | null => {\n const b = table.bounds.value\n if (!b) return null\n const out: string[][] = []\n for (let r = b.minRowIndex; r <= b.maxRowIndex; r++) {\n const row = rowsAll.value[r]\n if (!row) continue\n const line: string[] = []\n for (let c = b.minColumnIndex; c <= b.maxColumnIndex; c++) {\n const def = visibleCols.value[c]!.def\n line.push(copyText(def, row, store.read(row, def)))\n }\n out.push(line)\n }\n return out\n}\nconst copy = (data: DataTransfer | null): boolean => {\n const m = copyMatrix()\n if (!m || !data) return false\n data.setData('text/plain', toTsv(m))\n data.setData('text/html', toHtml(m))\n return true\n}\nconst cut = (data: DataTransfer | null): boolean => {\n if (!copy(data)) return false\n if (!readOnlyNow.value) clearSelected()\n return true\n}\n/** Hücre menüsü › Copy / Cut: `navigator.clipboard` (TSV + HTML; yalnızca metin destekleniyorsa TSV). */\nconst copyToClipboard = (cutAfter: boolean) => {\n const m = copyMatrix()\n const clip = typeof navigator !== 'undefined' ? navigator.clipboard : undefined\n if (!m || !clip) return\n const tsv = toTsv(m)\n const write =\n typeof ClipboardItem === 'function' && clip.write\n ? clip.write([\n new ClipboardItem({\n 'text/plain': new Blob([tsv], { type: 'text/plain' }),\n 'text/html': new Blob([toHtml(m)], { type: 'text/html' }),\n }),\n ])\n : clip.writeText(tsv)\n void write.catch(() => clip.writeText(tsv)).catch(() => {})\n if (cutAfter && !readOnlyNow.value) clearSelected()\n}\nconst pasteMatrix = (matrix: string[][]): boolean => {\n const a = table.active.value\n const width = Math.max(0, ...matrix.map((l) => l.length))\n if (!a || !matrix.length || !width || readOnlyNow.value) return false\n const cols = visibleCols.value\n const startRow = indexByKey.value.get(a.rowId)\n const startCol = cols.findIndex((c) => c.id === a.columnId)\n if (startRow === undefined || startCol < 0) return false\n const b = table.bounds.value\n const targets: Array<{ r: number; c: number; text: string }> = []\n if (\n matrix.length === 1 &&\n width === 1 &&\n b &&\n (b.maxRowIndex > b.minRowIndex || b.maxColumnIndex > b.minColumnIndex)\n ) {\n // Tek değer + aralık: değer tüm aralığa (07 §7).\n for (const { r, c } of selectedCells()) targets.push({ r, c, text: matrix[0]![0]! })\n } else {\n matrix.forEach((line, i) =>\n line.forEach((text, j) => {\n if (startCol + j < cols.length) targets.push({ r: startRow + i, c: startCol + j, text })\n }),\n )\n }\n const lastRow = Math.max(...targets.map((t) => t.r))\n const overflow = lastRow - rowsAll.value.length + 1\n if (overflow > 0 && store.allRows.value.length + overflow > props.maxRows) {\n showToast({\n text: i18n.t('sheet.limitPaste', {\n count: fmt.int(store.allRows.value.length + overflow),\n max: fmt.int(props.maxRows),\n }),\n })\n return true\n }\n // Son satırın altına taşanlar yeni satır olur; anahtar boşsa \"Required\" (07 §7).\n const addedRows = overflow > 0 ? store.addRows(overflow) : []\n if (addedRows.length && order.value) order.value = [...order.value, ...addedRows.map((x) => x.key)]\n const rows = rowsAll.value\n // Sayılar panonun yerel ayarıyla: sütun bazında çıkarım, belirsizse uygulama locale'i.\n const localeByCol = new Map<number, string>()\n for (const c of new Set(targets.map((t) => t.c))) {\n const def = cols[c]!.def\n if (!TYPE_SPECS[def.type].numeric) continue\n const dec = inferDecimal(targets.filter((t) => t.c === c).map((t) => t.text))\n localeByCol.set(c, dec === ',' ? 'de' : dec === '.' ? 'en' : ctx.locale)\n }\n const changes: Array<Change<Row>> = []\n for (const t of targets) {\n const row = rows[t.r]\n const def = cols[t.c]?.def\n if (!row || !def || !canEdit(row, def)) continue\n changes.push({ row, def, value: parseInput(def, t.text, parseEnv(localeByCol.get(t.c))) })\n }\n store.apply(changes, addedRows)\n const minR = Math.min(...targets.map((t) => t.r))\n const minC = Math.min(...targets.map((t) => t.c))\n const maxC = Math.max(...targets.map((t) => t.c))\n selectCells(minR, minC, lastRow, maxC)\n // Toast: seçenek olmayan değerler (\"2 values aren't options\") ve diğer hatalar ayrı sayılır; Review ilk sorunlu hücre.\n const issues = targets\n .map((t) => {\n const row = rows[t.r]\n const issue = row && store.rowIssues(store.keyOf(row))?.get(cols[t.c]!.id)\n return issue?.level === 'error'\n ? { ...t, option: cols[t.c]!.def.type === 'select' || cols[t.c]!.def.type === 'multiselect' }\n : null\n })\n .filter((x): x is NonNullable<typeof x> => x !== null)\n const options = issues.filter((i) => i.option).length\n const others = issues.length - options\n const dims = { rows: lastRow - minR + 1, cols: maxC - minC + 1 }\n const first = issues[0]\n showToast({\n text: i18n.t('sheet.pasted', { rows: fmt.int(dims.rows), cols: fmt.int(dims.cols) }),\n issues:\n [\n options ? i18n.t('sheet.pasteIssues', { count: options }) : '',\n others ? i18n.t('sheet.pasteErrors', { count: others }) : '',\n ]\n .filter(Boolean)\n .join(' · ') || undefined,\n review: first ? () => selectCells(first.r, first.c, first.r, first.c) : undefined,\n undo: true,\n })\n polite.value = i18n.t('sr.pasted', dims)\n return true\n}\nconst paste = (data: DataTransfer | null): boolean => pasteMatrix(matrixFromClipboard(data))\n/** Hücre menüsü › Paste: `readText` yedeği (07 §7). */\nconst pasteFromClipboard = () => {\n void navigator.clipboard\n ?.readText()\n .then((text) => pasteMatrix(parseTsv(text)))\n .catch(() => {})\n}\n\n// Doldurma (07 §8): kaynak satır aralığı, hedef satıra kadar; seri ya da kopya, read-only atlanır, tek adım.\nconst fillPlan = (fromRow: number, toRow: number, cols: [number, number], target: number) => {\n const rows = rowsAll.value\n const up = target < fromRow\n const count = up ? fromRow - target : target - toRow\n const changes: Array<Change<Row>> = []\n for (let c = cols[0]; c <= cols[1]; c++) {\n const def = visibleCols.value[c]?.def\n if (!def) continue\n const source = rows.slice(fromRow, toRow + 1).map((r) => store.read(r, def))\n const values = fillValues(source, count, up)\n for (let k = 0; k < count; k++) {\n const row = rows[up ? fromRow - 1 - k : toRow + 1 + k]\n if (row && canEdit(row, def)) changes.push({ row, def, value: values[k] })\n }\n }\n return { changes, count }\n}\nconst fill = (fromRow: number, toRow: number, cols: [number, number], target: number) => {\n const { changes } = fillPlan(fromRow, toRow, cols, target)\n store.apply(changes)\n selectCells(Math.min(fromRow, target), cols[0], Math.max(toRow, target), cols[1])\n}\nconst fillLabel = (fromRow: number, toRow: number, cols: [number, number], target: number): string => {\n const { changes, count } = fillPlan(fromRow, toRow, cols, target)\n const first = changes[0]\n const value = first ? formatCell(first.def, first.row, first.value, fmtEnv) : ''\n return i18n.t('sheet.fillPreview', { count: count * (cols[1] - cols[0] + 1), value })\n}\nconst fillDown = () => {\n const b = table.bounds.value\n if (!b || b.maxRowIndex === b.minRowIndex) return\n fill(b.minRowIndex, b.minRowIndex, [b.minColumnIndex, b.maxColumnIndex], b.maxRowIndex)\n}\n\n// Geri al / yinele (07 §12): seçim ve aktif hücre o adımın yerine taşınır.\nconst afterStep = (step: Step | null) => {\n if (!step) return\n // Listeden çıkarma geri alındı: geri gelen satıra odak (toast'taki Undo odağı ızgaradan almıştı).\n if (step.removed?.length && !step.patches.length) {\n const i = indexByKey.value.get(step.removed[0]!)\n if (i !== undefined) focusCell(i, table.active.value?.columnId ?? visibleCols.value[0]!.id)\n return\n }\n if (!step.patches.length) return\n const idx = visibleCols.value.map((c) => c.id)\n let r1 = Infinity\n let r2 = -1\n let c1 = Infinity\n let c2 = -1\n for (const p of step.patches) {\n const r = indexByKey.value.get(p.key)\n const c = idx.indexOf(p.col)\n if (r === undefined || c < 0) continue\n r1 = Math.min(r1, r)\n r2 = Math.max(r2, r)\n c1 = Math.min(c1, c)\n c2 = Math.max(c2, c)\n }\n if (r2 >= 0) selectCells(r1, c1, r2, c2)\n}\nconst undo = () => {\n if (readOnlyNow.value) return\n edit.cancel()\n afterStep(store.undo())\n}\nconst redo = () => {\n if (readOnlyNow.value) return\n edit.cancel()\n afterStep(store.redo())\n}\nconst useSuggestion = (row: Row, def: ColumnDef<Row>, value: unknown) => store.set(row, def, value)\n\n// Satır partisi (07 §9, D12): Add row / Insert row above-below (newRowDefaults, odak anahtar hücresinde, düzenleme açık);\n// Remove from list (⌘−): nötr, sunucuda silmez, toast + Undo.\nconst addRow = (at?: number) => {\n if (readOnlyNow.value) return\n if (store.allRows.value.length + 1 > props.maxRows) {\n showToast({\n text: i18n.t('sheet.limitPaste', { count: fmt.int(store.allRows.value.length + 1), max: fmt.int(props.maxRows) }),\n })\n return\n }\n edit.commit()\n const [added] = store.addRows(1)\n if (!added) return\n const defaults = props.newRowDefaults?.() ?? {}\n const changes: Array<Change<Row>> = []\n for (const [id, value] of Object.entries(defaults)) {\n const def = defById.value.get(id)\n if (def && !isEmptyValue(value)) changes.push({ row: added.row, def, value })\n }\n store.apply(changes, [added])\n if (at !== undefined) {\n const keys = order.value ?? store.batch.value.map((r) => store.keyOf(r)).filter((k) => k !== added.key)\n const pos = Math.max(0, Math.min(keys.length, at))\n order.value = [...keys.slice(0, pos), added.key, ...keys.slice(pos)]\n } else if (order.value) order.value = [...order.value, added.key]\n if (view.value !== 'all') viewKeys.value = new Set([...viewKeys.value, added.key])\n table.focus(added.key, props.keyColumn)\n // Yeni satır görünür alana kayar (sona eklenince 5.000 satır aşağıda olabilir); sanal liste yeni sayıyı bir sonraki\n // render'da öğrendiğinden nextTick. focusActive editör açıkken kaydırmaz.\n void nextTick(() => grid.value?.scrollToIndex(rowsAll.value.findIndex((r) => store.keyOf(r) === added.key)))\n grid.value?.focusActive()\n if (keyDef.value) edit.start(added.row, keyDef.value, { inCell: true })\n}\nconst insertRow = (where: 'above' | 'below') => {\n const a = table.active.value\n const i = a ? orderedBatch.value.findIndex((r) => store.keyOf(r) === a.rowId) : -1\n addRow(i < 0 ? undefined : where === 'above' ? i : i + 1)\n}\nconst removeSelectedRows = () => {\n if (readOnlyNow.value) return\n const b = table.bounds.value\n if (!b) return\n edit.cancel()\n const rows = rowsAll.value.slice(b.minRowIndex, b.maxRowIndex + 1)\n const keys = rows.map((r) => store.keyOf(r))\n if (!keys.length) return\n store.removeRows(keys)\n showToast({\n text:\n keys.length === 1\n ? i18n.t('sheet.removed', { count: 1, row: store.rowNoOf(keys[0]!), entity: entity.value })\n : i18n.t('sheet.removed', { count: keys.length, entity: entity.value }),\n undo: true,\n })\n focusCell(b.minRowIndex, table.active.value?.columnId ?? visibleCols.value[0]!.id)\n}\n\n// Yerel sıralama (07 §10): asc → desc → kapalı, ⇧ ile ikincil (en fazla 3); anlık görüntü, gutter numaraları değişmez.\nconst sort = (columnId: string, additive: boolean) => {\n const def = defById.value.get(columnId)\n if (!def || !(def.sortable ?? TYPE_SPECS[def.type].sortable)) return\n const current = sortRules.value\n const existing = current.find((s) => s.column === columnId)\n const next: SortRule | null = !existing\n ? { column: columnId, dir: 'asc' }\n : existing.dir === 'asc'\n ? { column: columnId, dir: 'desc' }\n : null\n const rest = current.filter((s) => s.column !== columnId)\n sortRules.value = additive\n ? next\n ? existing\n ? current.map((s) => (s.column === columnId ? next : s))\n : [...rest, next].slice(-3)\n : rest\n : next\n ? [next]\n : []\n if (!sortRules.value.length) {\n order.value = null\n return\n }\n const cmps = sortRules.value.map((s) => ({\n def: defById.value.get(s.column)!,\n cmp: comparator(defById.value.get(s.column)!, ctx.locale),\n sign: s.dir === 'desc' ? -1 : 1,\n }))\n order.value = [...store.batch.value]\n .sort((a, b) => {\n for (const { def: d, cmp, sign } of cmps) {\n const r = cmp(store.read(a, d), store.read(b, d)) * sign\n if (r) return r\n }\n return store.rowNoOf(store.keyOf(a)) - store.rowNoOf(store.keyOf(b))\n })\n .map((r) => store.keyOf(r))\n}\nconst sortMap = computed(() => {\n const m = new Map<string, { dir: 'asc' | 'desc'; index: number | null }>()\n sortRules.value.forEach((s, i) => m.set(s.column, { dir: s.dir, index: sortRules.value.length > 1 ? i + 1 : null }))\n return m\n})\n\n// Anahtar kontrolü (07 §9): yeni satırın anahtarı onaylanınca 300 ms sonra `lookupKeys`; yok → New, var → Update + sunucu\n// kaydı base (Q2). Verilmemişse her bilinmeyen anahtar New.\nconst looked = new Map<string, string>()\nconst pending = new Map<string, string>()\nlet lookupTimer: ReturnType<typeof setTimeout> | undefined\nlet lookupCtl: AbortController | null = null\nconst runLookup = async () => {\n const batchKeys = new Map(pending)\n pending.clear()\n if (!batchKeys.size) return\n if (!props.lookupKeys) {\n for (const rowKey of batchKeys.keys()) store.setKeyState(rowKey, 'new')\n return\n }\n for (const rowKey of batchKeys.keys()) store.setKeyState(rowKey, 'checking')\n lookupCtl?.abort()\n lookupCtl = new AbortController()\n try {\n const values = [...new Set(batchKeys.values())].slice(0, 500)\n const result = await props.lookupKeys(values, { signal: lookupCtl.signal })\n for (const [rowKey, value] of batchKeys) {\n if (looked.get(rowKey) !== value) continue\n const found = result[value]\n if (found) {\n store.setKeyState(rowKey, 'update')\n store.setBase(rowKey, found)\n } else store.setKeyState(rowKey, 'new')\n }\n } catch {\n for (const rowKey of batchKeys.keys()) store.setKeyState(rowKey, 'new')\n }\n}\nwatch(store.version, () => {\n const def = keyDef.value\n if (!def) return\n for (const r of store.batch.value) {\n const rowKey = store.keyOf(r)\n if (!store.isNew(rowKey)) continue\n const v = store.readUntracked(r, def)\n const text = isEmptyValue(v) ? '' : String(v)\n if (looked.get(rowKey) === text) continue\n looked.set(rowKey, text)\n if (text) pending.set(rowKey, text)\n else store.setKeyState(rowKey, 'new')\n }\n if (pending.size) {\n clearTimeout(lookupTimer)\n lookupTimer = setTimeout(() => void runLookup(), 300)\n }\n})\n\n// Kayıt akışı (07 §14): hatalı satır varsa dialog; `@save` yükü; uygulama `saving` verir; `applyResult` sonuçları işler;\n// bitişte status bar sonucu ya da Partly saved şeridi (görünüm Errors, aktif hücre ilk hatada).\nconst errorDialogOpen = ref(false)\nconst errorItems = computed<ErrorRowItem[]>(() =>\n errorKeysInOrder.value\n .filter((k) => !!store.rowDraft(k)?.size || store.isNew(k))\n .map((k) => {\n const row = store.rowByKey(k)!\n const issues = store.rowIssues(k)\n const first = issues ? [...issues.values()].find((i) => i.level === 'error') : undefined\n return {\n rowNo: store.rowNoOf(k),\n key: keyDef.value ? inputText(keyDef.value, store.read(row, keyDef.value)) : k,\n message: first?.message ?? store.rowError(k) ?? '',\n }\n }),\n)\nconst saveTotals = shallowRef({ created: 0, updated: 0, errors: 0 })\nconst savedSummary = shallowRef<{ count: number; created: number; updated: number } | null>(null)\nconst partly = shallowRef<{ failed: number; saved: number } | null>(null)\nconst emitSave = () => {\n saveTotals.value = { created: 0, updated: 0, errors: 0 }\n savedSummary.value = null\n partly.value = null\n store.settleUntouched()\n emit('save', store.getChanges())\n}\nconst save = () => {\n if (readOnlyNow.value) return\n edit.commit()\n if (!counts.value.changedCells && !counts.value.newRows) return\n if (errorItems.value.length) {\n errorDialogOpen.value = true\n return\n }\n emitSave()\n}\nconst fixFirst = () => {\n setView('errors')\n goToError(1)\n}\nconst finishSave = () => {\n const t = saveTotals.value\n if (!t.created && !t.updated && !t.errors) return\n if (t.errors) {\n partly.value = { failed: t.errors, saved: t.created + t.updated }\n assertive.value = i18n.t('sheet.partly.title', { count: fmt.int(t.errors) })\n setView('errors')\n goToError(1)\n } else {\n savedSummary.value = { count: t.created + t.updated, created: t.created, updated: t.updated }\n polite.value = i18n.t('sheet.saved', { count: fmt.int(t.created + t.updated) })\n }\n saveTotals.value = { created: 0, updated: 0, errors: 0 }\n}\nlet resultVersion = -1\nconst applyResult = (results: Array<SheetRowResult<Row>>) => {\n const r = store.applyResult(results)\n resultVersion = store.version.value\n const t = saveTotals.value\n saveTotals.value = { created: t.created + r.created, updated: t.updated + r.updated, errors: t.errors + r.errors }\n if (!savingNow.value) finishSave()\n}\nwatch(savingNow, (now) => {\n if (!now) finishSave()\n})\n// Sonraki düzenlemede sonuç metni gider (applyResult'ın kendi sürüm artışı sayılmaz); hata kalmayınca şerit kapanır.\nwatch(store.version, (v) => {\n if (v !== resultVersion) savedSummary.value = null\n if (partly.value && !counts.value.errorRows) partly.value = null\n})\nconst partlyIndex = computed(() => {\n const a = table.active.value\n const i = a ? errorKeysInOrder.value.indexOf(a.rowId) : -1\n return i < 0 ? 0 : i + 1\n})\n/** Copy errors (07 §14): TSV, başlık Row · anahtar sütunu · Column · Message. */\nconst copyErrors = () => {\n const lines: string[][] = [\n [\n i18n.t('sheet.err.row'),\n keyDef.value?.header ?? props.keyColumn,\n i18n.t('sheet.err.column'),\n i18n.t('sheet.err.message'),\n ],\n ]\n for (const k of errorKeysInOrder.value) {\n const row = store.rowByKey(k)!\n const keyText = keyDef.value ? inputText(keyDef.value, store.read(row, keyDef.value)) : k\n const rowErr = store.rowError(k)\n if (rowErr) lines.push([String(store.rowNoOf(k)), keyText, '', rowErr])\n for (const [col, issue] of store.rowIssues(k) ?? [])\n if (issue.level === 'error')\n lines.push([String(store.rowNoOf(k)), keyText, defById.value.get(col)?.header ?? col, issue.message])\n }\n void navigator.clipboard?.writeText(toTsv(lines)).catch(() => {})\n}\nconst openHref = (row: Row): string | undefined => {\n if (store.isNew(store.keyOf(row))) return undefined\n return keyDef.value?.href?.(row) ?? primaryDef.value?.href?.(row)\n}\n\n// Import (07 §13): listede olan anahtar güncellenir; sunucuda olan Update satırı (base), olmayan New satırı; tek undo adımı.\nconst importOpen = ref(false)\nconst keyIndexSet = computed(() => {\n void store.version.value\n const set = new Set<string>()\n const def = keyDef.value\n if (!def) return set\n for (const r of store.allRows.value) {\n const v = store.readUntracked(r, def)\n if (!isEmptyValue(v)) set.add(String(v))\n }\n return set\n})\nconst inList = (key: string) => keyIndexSet.value.has(key)\nconst applyImport = (payload: ImportPayload<Row>) => {\n if (readOnlyNow.value || !keyDef.value) return\n edit.commit()\n const def = keyDef.value\n const byKeyValue = new Map<string, Row>()\n for (const r of store.allRows.value) {\n const v = store.readUntracked(r, def)\n if (!isEmptyValue(v)) byKeyValue.set(String(v), r)\n }\n const changes: Array<Change<Row>> = []\n const addedRows: Array<{ key: string; row: Row }> = []\n const bases: Array<{ key: string; row: Row }> = []\n let updated = 0\n let news = 0\n for (const item of payload.rows) {\n let row = byKeyValue.get(item.key)\n if (!row) {\n if (item.server === null && !payload.addNew) continue\n if (store.allRows.value.length + addedRows.length + 1 > props.maxRows) break\n const [a] = store.addRows(1)\n if (!a) continue\n row = a.row\n addedRows.push(a)\n byKeyValue.set(item.key, row)\n changes.push({ row, def, value: item.key })\n if (item.server) {\n bases.push({ key: a.key, row: item.server })\n updated++\n } else news++\n } else updated++\n for (const [id, value] of Object.entries(item.values)) {\n const d = defById.value.get(id)\n if (d && canEdit(row, d)) changes.push({ row, def: d, value })\n }\n }\n for (const b of bases) {\n store.setKeyState(b.key, 'update')\n store.setBase(b.key, b.row)\n }\n store.apply(changes, addedRows)\n if (addedRows.length && order.value) order.value = [...order.value, ...addedRows.map((a) => a.key)]\n showToast({\n text: i18n.t('import.done', {\n count: fmt.int(payload.rows.length),\n updated: fmt.int(updated),\n news: fmt.int(news),\n }),\n undo: true,\n })\n // Odak ızgaraya, ilk alınan satırın anahtar hücresine (dialog kapanınca odak Import düğmesine dönerdi).\n const firstKey = payload.rows[0]?.key\n const firstRow = firstKey ? byKeyValue.get(firstKey) : undefined\n const i = firstRow ? indexByKey.value.get(store.keyOf(firstRow)) : undefined\n if (i !== undefined) focusCell(i, props.keyColumn)\n}\n/** Export (07 §2): All / Visible › CSV / Excel; değerler güncel (taslak uygulanmış), dosyayı uygulama yazar. */\nconst exportRows = (format: 'csv' | 'xlsx', scope: 'all' | 'visible') => {\n edit.commit()\n const rows = (scope === 'all' ? store.allRows.value : rowsAll.value).map((r) => store.current(r))\n emit('export', { format, scope, columns: visibleCols.value.map((c) => c.id), rows })\n}\nconst exportLabel = (scope: 'all' | 'visible') =>\n i18n.t(scope === 'all' ? 'sheet.exportAll' : 'sheet.exportVisible', {\n count: fmt.int(scope === 'all' ? store.allRows.value.length : rowsAll.value.length),\n })\nconst copyLink = () => void navigator.clipboard?.writeText(location.href).catch(() => {})\n\nconst sheet: SheetApi<Row> = {\n store,\n table,\n edit,\n canEdit,\n editorFor,\n toggle,\n clearCells: clearSelected,\n save,\n goToError,\n copy,\n cut,\n paste,\n fill,\n fillLabel,\n fillDown,\n undo,\n redo,\n useSuggestion,\n copyToClipboard,\n pasteFromClipboard,\n insertRow,\n removeSelectedRows,\n sort,\n openHref,\n}\n\n// Izgara dışına tık onaylar (07 §5): formül çubuğu ve portallı editör katmanları (`dt-sheet-layer`) dışarı sayılmaz.\nconst onDocPointerdown = (e: PointerEvent) => {\n if (!edit.editing.value) return\n const t = e.target as Element | null\n if (t?.closest('.dt-cell.is-editing, .dt-formula, .dt-sheet-layer')) return\n edit.commit()\n}\n// Ayrılma koruması (07 §14): değişiklik varken tarayıcı uyarısı; yönlendirici dialog'u uygulamanın (`isDirty()`).\nconst isDirty = () => counts.value.changedCells > 0 || counts.value.newRows > 0\nconst onBeforeUnload = (e: BeforeUnloadEvent) => {\n if (!isDirty()) return\n e.preventDefault()\n e.returnValue = ''\n}\nonMounted(() => {\n document.addEventListener('pointerdown', onDocPointerdown, true)\n window.addEventListener('beforeunload', onBeforeUnload)\n})\nonBeforeUnmount(() => {\n document.removeEventListener('pointerdown', onDocPointerdown, true)\n window.removeEventListener('beforeunload', onBeforeUnload)\n clearTimeout(toastTimer)\n clearTimeout(lookupTimer)\n lookupCtl?.abort()\n})\n\n// ⌘S / ⌘F odak sheet içindeyken (07 §2); ızgara kendi işlediyse (defaultPrevented) tekrar etmez.\nconst findBox = useTemplateRef<InstanceType<typeof SearchBox>>('findBox')\nconst onRootKeydown = (e: KeyboardEvent) => {\n if (e.defaultPrevented || !(e.metaKey || e.ctrlKey)) return\n const k = e.key.toLowerCase()\n if (k === 's') {\n e.preventDefault()\n save()\n } else if (k === 'f' && !loadingNow.value) {\n e.preventDefault()\n findBox.value?.focus()\n }\n}\n\n// Find in grid (07 §2): görünür sütunlarda görüntülenen metin; eşleşmeler vurgulanır, satır gizlenmez; Enter / ⇧Enter gezer.\nconst fold = (s: string) => s.toLocaleLowerCase(ctx.locale)\nconst findText = ref('')\nconst findIndex = ref(0)\nconst matches = computed(() => {\n const q = fold(findText.value.trim())\n if (!q) return null\n void store.version.value\n const map = new Map<string, Set<string>>()\n const list: Array<{ r: number; c: number }> = []\n const rows = rowsAll.value\n const cols = visibleCols.value\n for (let r = 0; r < rows.length; r++) {\n const row = rows[r]!\n for (let c = 0; c < cols.length; c++) {\n const def = cols[c]!.def\n const v = store.readUntracked(row, def)\n if (isEmptyValue(v) || !fold(formatCell(def, row, v, fmtEnv)).includes(q)) continue\n const key = store.keyOf(row)\n let set = map.get(key)\n if (!set) map.set(key, (set = new Set()))\n set.add(def.id as string)\n list.push({ r, c })\n }\n }\n return { map, list }\n})\nconst goToMatch = (i: number) => {\n const m = matches.value?.list[i]\n if (!m) return\n findIndex.value = i\n const row = rowsAll.value[m.r]!\n table.focus(store.keyOf(row), visibleCols.value[m.c]!.id)\n grid.value?.scrollToIndex(m.r)\n}\nwatch(\n () => matches.value?.list.length ?? 0,\n () => goToMatch(0),\n)\nconst findStep = (dir: 1 | -1) => {\n const n = matches.value?.list.length ?? 0\n if (n) goToMatch((((findIndex.value + dir) % n) + n) % n)\n}\nconst onFindKeydown = (e: KeyboardEvent) => {\n if (e.key === 'Enter') {\n e.preventDefault()\n findStep(e.shiftKey ? -1 : 1)\n } else if (e.key === 'Escape' && !findText.value) {\n e.preventDefault()\n grid.value?.focusActive()\n }\n}\nconst findCount = computed(() =>\n matches.value\n ? i18n.t('sheet.findCount', {\n index: matches.value.list.length ? findIndex.value + 1 : 0,\n total: matches.value.list.length,\n })\n : '',\n)\n\n// All / Changed / Errors sayaçları (07 §11).\nconst viewCounts = computed(() => ({\n all: store.allRows.value.length,\n changed: counts.value.changedOrNewRows,\n errors: counts.value.errorRows,\n}))\n\n// Formül çubuğu (07 §2): ad kutusu, fx, değer (buraya yazmak hücreyi düzenler), ipucu.\nconst activeRow = computed(() => {\n const a = table.active.value\n return a ? (store.rowByKey(a.rowId) ?? null) : null\n})\nconst activeDef = computed(() => {\n const a = table.active.value\n return a ? (defById.value.get(a.columnId) ?? null) : null\n})\nconst rangeDims = computed(() => {\n const b = table.bounds.value\n if (!b) return null\n const rows = b.maxRowIndex - b.minRowIndex + 1\n const cols = b.maxColumnIndex - b.minColumnIndex + 1\n return rows * cols > 1 ? { rows, cols } : null\n})\nconst rangeText = computed(() => (rangeDims.value ? i18n.t('sheet.cells', rangeDims.value) : null))\nconst nameKey = computed(() =>\n activeRow.value && keyDef.value ? inputText(keyDef.value, store.read(activeRow.value, keyDef.value)) : '',\n)\nconst formulaText = computed(() => {\n const e = edit.editing.value\n if (e) return e.text ?? inputText(e.def, e.value)\n return activeRow.value && activeDef.value\n ? inputText(activeDef.value, store.read(activeRow.value, activeDef.value))\n : ''\n})\nconst formulaEditable = computed(\n () =>\n !!activeRow.value &&\n !!activeDef.value &&\n activeDef.value.type !== 'boolean' &&\n canEdit(activeRow.value, activeDef.value),\n)\nconst onFormulaInput = (e: Event) => {\n const text = (e.target as HTMLInputElement).value\n const row = activeRow.value\n const def = activeDef.value\n if (!row || !def || !formulaEditable.value) return\n if (!edit.editing.value && !edit.start(row, def, { inCell: false })) return\n edit.setValue(parseInput(def, text, parseEnv()), text, false)\n}\nconst onFormulaKeydown = (e: KeyboardEvent) => {\n if (e.key === 'Enter') {\n e.preventDefault()\n if (edit.commit()) table.move('down')\n grid.value?.focusActive()\n } else if (e.key === 'Escape') {\n e.preventDefault()\n edit.cancel()\n grid.value?.focusActive()\n }\n}\nconst hint = computed(() => {\n const d = activeDef.value\n if (!d) return ''\n const parts = [i18n.t(typeLabelKey(d.type))]\n if (d.type === 'currency' && typeof d.currency === 'string') parts.push(d.currency)\n if (d.required) parts.push(i18n.t('sheet.required').toLocaleLowerCase(ctx.locale))\n if (d.hint) parts.push(d.hint)\n return parts.join(' · ')\n})\nconst valueAria = computed(() =>\n activeDef.value ? i18n.t('sheet.valueAria', { column: activeDef.value.header, key: nameKey.value }) : '',\n)\n\n// Status bar seçim özeti (07 §2): Count = boş olmayan; Sum / Average yalnızca sayısal hücre varsa; tek hücrede gizli.\nconst summary = computed(() => {\n void store.version.value\n const b = table.bounds.value\n if (!b || !rangeDims.value) return null\n let count = 0\n let sum = 0\n let numeric = 0\n for (let r = b.minRowIndex; r <= b.maxRowIndex; r++) {\n const row = rowsAll.value[r]\n if (!row) continue\n for (let c = b.minColumnIndex; c <= b.maxColumnIndex; c++) {\n const def = visibleCols.value[c]!.def\n const v = store.readUntracked(row, def)\n if (isEmptyValue(v)) continue\n count++\n if (TYPE_SPECS[def.type].numeric && typeof v === 'number') {\n sum += v\n numeric++\n }\n }\n }\n return { count, sum: numeric ? fmt.decimal(sum, 2) : null, avg: numeric ? fmt.decimal(sum / numeric, 2) : null }\n})\n\nconst status = computed<SheetStatus>(() => ({\n phase: loadingNow.value\n ? 'loading'\n : savingNow.value\n ? 'saving'\n : partly.value\n ? 'partly-saved'\n : savedSummary.value\n ? 'saved'\n : 'ready',\n ...counts.value,\n}))\nconst changesText = computed(() =>\n counts.value.changedCells\n ? i18n.t('sheet.changes', { cells: fmt.int(counts.value.changedCells), rows: fmt.int(counts.value.changedRows) })\n : i18n.t('sheet.noChanges'),\n)\nconst saveTip = `${i18n.t('sheet.save')} · ${SAVE_KBD}`\nconst undoTip = `${i18n.t('common.undo')} (${UNDO_KBD})`\nconst redoTip = `${i18n.t('common.redo')} (${REDO_KBD})`\nconst canSave = computed(() => !readOnlyNow.value && (counts.value.changedCells > 0 || counts.value.newRows > 0))\n\n// Toast (06 §8): yapıştırma sonucu, sınır uyarısı, listeden çıkarma, gizli hata; Review / Show it / Undo.\ninterface Toast {\n text: string\n issues?: string\n review?: () => void\n action?: { label: string; run: () => void }\n undo?: boolean\n}\nconst toast = shallowRef<Toast | null>(null)\nlet toastTimer: ReturnType<typeof setTimeout> | undefined\nconst showToast = (t: Toast) => {\n toast.value = t\n clearTimeout(toastTimer)\n toastTimer = setTimeout(() => (toast.value = null), 6000)\n}\nconst toastUndo = () => {\n toast.value = null\n undo()\n}\nconst toastAction = () => {\n const run = toast.value?.action?.run\n toast.value = null\n run?.()\n}\nconst polite = ref('')\nconst assertive = ref('')\n// Yükleme / kayıt ilerlemesi her %25'te duyurulur (08 §5).\nlet announcedQuarter = -1\nwatch(percent, (p) => {\n if (p === null) {\n announcedQuarter = -1\n return\n }\n const q = Math.floor(p / 25)\n if (q === announcedQuarter || p === 0) return\n announcedQuarter = q\n polite.value = i18n.t(loadingNow.value ? 'sr.loadingPercent' : 'sr.savingPercent', { percent: q * 25 })\n})\n\nconst discardOpen = ref(false)\nconst discard = () => {\n edit.cancel()\n store.reset()\n order.value = null\n sortRules.value = []\n partly.value = null\n savedSummary.value = null\n looked.clear()\n pending.clear()\n grid.value?.focusActive()\n}\n\nconst displayProps = computed(() => ({\n density: density.value,\n verticalLines: pref.prefs.verticalLines,\n columns: layout.panel.value,\n counts: layout.counts.value,\n persistent: pref.persistent,\n}))\nconst displayOn = {\n 'update:density': (d: Density) => pref.set({ density: d }),\n 'update:verticalLines': (on: boolean) => pref.set({ verticalLines: on }),\n 'column-visible': (id: string, visible: boolean) => layout.setVisible(id, visible),\n 'column-move': (id: string, delta: -1 | 1) => layout.move(id, delta),\n 'columns-all': (visible: boolean) => {\n for (const c of layout.panel.value) if (!c.pinned && c.canHide) layout.setVisible(c.id, visible)\n },\n 'columns-reset': () => layout.reset(),\n reset: () => pref.reset(),\n}\n\nconst rootEl = ref<HTMLElement | null>(null)\nconst tooltip = useDelegatedTooltip(rootEl)\n\ndefineExpose({\n status,\n isDirty,\n getChanges: store.getChanges,\n applyResult,\n reset: discard,\n undo,\n redo,\n goToNextError: () => goToError(1),\n})\n</script>\n\n<template>\n <div\n ref=\"rootEl\"\n class=\"dt dt-sheet\"\n :class=\"{ 'is-phone': readOnlyDevice }\"\n :data-density=\"density\"\n @keydown=\"onRootKeydown\"\n >\n <div v-if=\"readOnlyDevice\" class=\"dt-sheet-readonly\" role=\"note\">\n <PhMonitor :size=\"20\" aria-hidden=\"true\" />\n <div class=\"dt-sheet-readonly-text\">\n <strong>{{ i18n.t('sheet.readOnly.title') }}</strong>\n <span>{{ i18n.t('sheet.readOnly.body', { entity }) }}</span>\n <button type=\"button\" class=\"dt-btn has-icon\" @click=\"copyLink\">\n <PhLink :size=\"16\" aria-hidden=\"true\" />\n {{ i18n.t('common.copyLink') }}\n </button>\n </div>\n </div>\n <div class=\"dt-toolbar dt-sheet-toolbar\" role=\"toolbar\">\n <div v-if=\"loadingNow || savingNow\" class=\"dt-progress-strip\">\n <strong>\n {{\n loadingNow\n ? i18n.t('sheet.loading', { entity })\n : progress\n ? i18n.t('sheet.saving', { sent: fmt.int(progress.done), total: fmt.int(progress.total) })\n : i18n.t('sheet.savingIndeterminate')\n }}\n </strong>\n <span v-if=\"loadingNow && progress\" class=\"dt-progress-count\">\n {{ i18n.t('sheet.loadingCount', { loaded: fmt.int(progress.done), total: fmt.int(progress.total) }) }}\n </span>\n <div\n class=\"dt-progress\"\n :class=\"{ 'is-indeterminate': percent === null }\"\n role=\"progressbar\"\n aria-valuemin=\"0\"\n aria-valuemax=\"100\"\n :aria-valuenow=\"percent ?? undefined\"\n >\n <div class=\"dt-progress-fill\" :style=\"percent !== null ? { width: `${percent}%` } : undefined\" />\n </div>\n </div>\n <div v-else-if=\"readOnlyDevice\" class=\"dt-find\" @keydown=\"onFindKeydown\">\n <SearchBox\n ref=\"findBox\"\n :model-value=\"findText\"\n :placeholder=\"i18n.t('sheet.find')\"\n :kbd=\"FIND_KBD\"\n @update:model-value=\"(v) => (findText = v)\"\n />\n <span v-if=\"findCount\" class=\"dt-find-count\" role=\"status\">{{ findCount }}</span>\n </div>\n <template v-else>\n <div class=\"dt-find\" @keydown=\"onFindKeydown\">\n <SearchBox\n ref=\"findBox\"\n :model-value=\"findText\"\n :placeholder=\"i18n.t('sheet.find')\"\n :kbd=\"FIND_KBD\"\n @update:model-value=\"(v) => (findText = v)\"\n />\n <span v-if=\"findCount\" class=\"dt-find-count\" role=\"status\">{{ findCount }}</span>\n </div>\n <span class=\"dt-toolbar-sep\" aria-hidden=\"true\" />\n <ToggleGroupRoot\n class=\"dt-seg dt-sheet-views\"\n type=\"single\"\n :model-value=\"view\"\n :aria-label=\"i18n.t('sheet.showRows')\"\n @update:model-value=\"(v) => v && setView(v as SheetFilterMode)\"\n >\n <ToggleGroupItem class=\"dt-seg-item\" value=\"all\">\n {{ i18n.t('sheet.all') }}\n <span class=\"dt-seg-count\">{{ fmt.int(viewCounts.all) }}</span>\n </ToggleGroupItem>\n <ToggleGroupItem class=\"dt-seg-item\" value=\"changed\">\n {{ i18n.t('sheet.changed') }}\n <span class=\"dt-seg-count\">{{ fmt.int(viewCounts.changed) }}</span>\n </ToggleGroupItem>\n <ToggleGroupItem class=\"dt-seg-item\" :class=\"{ 'is-errors': viewCounts.errors > 0 }\" value=\"errors\">\n {{ i18n.t('sheet.errors') }}\n <span class=\"dt-seg-count\">{{ fmt.int(viewCounts.errors) }}</span>\n </ToggleGroupItem>\n </ToggleGroupRoot>\n <button\n type=\"button\"\n class=\"dt-btn dt-sheet-undo\"\n :aria-disabled=\"store.canUndo.value ? undefined : 'true'\"\n :aria-label=\"undoTip\"\n :data-dt-tip=\"undoTip\"\n @click=\"store.canUndo.value && undo()\"\n >\n <PhArrowUUpLeft :size=\"16\" aria-hidden=\"true\" />\n </button>\n <button\n type=\"button\"\n class=\"dt-btn dt-sheet-undo\"\n :aria-disabled=\"store.canRedo.value ? undefined : 'true'\"\n :aria-label=\"redoTip\"\n :data-dt-tip=\"redoTip\"\n @click=\"store.canRedo.value && redo()\"\n >\n <PhArrowUUpRight :size=\"16\" aria-hidden=\"true\" />\n </button>\n <span class=\"dt-toolbar-sep\" aria-hidden=\"true\" />\n <button type=\"button\" class=\"dt-btn dt-btn-ghost has-icon dt-sheet-add\" @click=\"addRow()\">\n <PhPlus :size=\"16\" aria-hidden=\"true\" />\n {{ i18n.t('sheet.addRow') }}\n </button>\n <button\n v-if=\"parseFile\"\n type=\"button\"\n class=\"dt-btn dt-btn-ghost has-icon dt-sheet-import\"\n @click=\"importOpen = true\"\n >\n <PhDownloadSimple :size=\"16\" aria-hidden=\"true\" />\n {{ i18n.t('sheet.import') }}\n </button>\n <DropdownMenuRoot>\n <DropdownMenuTrigger as-child>\n <button type=\"button\" class=\"dt-btn dt-btn-ghost has-icon dt-sheet-export\">\n <PhExport :size=\"16\" aria-hidden=\"true\" />\n {{ i18n.t('sheet.export') }}\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuPortal>\n <DropdownMenuContent class=\"dt-menu\" align=\"start\" :side-offset=\"4\">\n <DropdownMenuSub v-for=\"scope in ['all', 'visible'] as const\" :key=\"scope\">\n <DropdownMenuSubTrigger class=\"dt-menu-item\">{{ exportLabel(scope) }}</DropdownMenuSubTrigger>\n <DropdownMenuPortal>\n <DropdownMenuSubContent class=\"dt-menu\" :side-offset=\"4\">\n <DropdownMenuItem class=\"dt-menu-item\" @select=\"exportRows('xlsx', scope)\">\n {{ i18n.t('toolbar.xlsx') }}\n </DropdownMenuItem>\n <DropdownMenuItem class=\"dt-menu-item\" @select=\"exportRows('csv', scope)\">\n {{ i18n.t('toolbar.csv') }}\n </DropdownMenuItem>\n </DropdownMenuSubContent>\n </DropdownMenuPortal>\n </DropdownMenuSub>\n </DropdownMenuContent>\n </DropdownMenuPortal>\n </DropdownMenuRoot>\n <DisplayPopover v-bind=\"displayProps\" v-on=\"displayOn\" />\n </template>\n <span class=\"dt-toolbar-spacer\" />\n <template v-if=\"readOnlyDevice\" />\n <span v-else-if=\"!savingNow\" class=\"dt-sheet-changes\" :class=\"{ 'is-empty': !counts.changedCells }\">\n <span v-if=\"counts.changedCells\" class=\"dt-sheet-dot\" aria-hidden=\"true\" />\n {{ changesText }}\n <template v-if=\"counts.newRows\">· {{ i18n.t('sheet.newShort', { count: counts.newRows }) }}</template>\n </span>\n <button\n v-if=\"!readOnlyDevice\"\n type=\"button\"\n class=\"dt-btn dt-btn-ghost\"\n :disabled=\"savingNow || (!counts.changedCells && !counts.newRows)\"\n @click=\"discardOpen = true\"\n >\n {{ i18n.t('sheet.discard') }}\n </button>\n <button\n v-if=\"!readOnlyDevice\"\n type=\"button\"\n class=\"dt-btn dt-btn-primary has-icon dt-sheet-save\"\n :disabled=\"!savingNow && !canSave\"\n :aria-disabled=\"savingNow ? 'true' : undefined\"\n :data-dt-tip=\"savingNow ? undefined : saveTip\"\n @click=\"!savingNow && save()\"\n >\n <PhCircleNotch v-if=\"savingNow\" :size=\"16\" class=\"dt-spin\" aria-hidden=\"true\" />\n <PhCheck v-else :size=\"16\" aria-hidden=\"true\" />\n {{ savingNow ? i18n.t('sheet.savingButton') : i18n.t('sheet.save') }}\n </button>\n </div>\n\n <div v-if=\"partly\" class=\"dt-sheet-partly\" role=\"alert\">\n <PhWarningCircle :size=\"16\" aria-hidden=\"true\" />\n <span>\n <strong>{{ i18n.t('sheet.partly.title', { count: fmt.int(partly.failed) }) }}</strong>\n {{ i18n.t('sheet.partly.body', { count: fmt.int(partly.saved) }) }}\n </span>\n <span class=\"dt-partly-spacer\" />\n <span class=\"dt-partly-nav\">\n <button type=\"button\" class=\"dt-partly-btn\" :aria-label=\"i18n.t('sheet.prevError')\" @click=\"goToError(-1)\">\n <PhCaretUp :size=\"14\" aria-hidden=\"true\" />\n </button>\n <span>{{ i18n.t('sheet.findCount', { index: partlyIndex, total: errorKeysInOrder.length }) }}</span>\n <button type=\"button\" class=\"dt-partly-btn\" :aria-label=\"i18n.t('sheet.nextError')\" @click=\"goToError(1)\">\n <PhCaretDown :size=\"14\" aria-hidden=\"true\" />\n </button>\n </span>\n <span class=\"dt-partly-sep\" aria-hidden=\"true\" />\n <button type=\"button\" class=\"dt-partly-copy\" @click=\"copyErrors\">\n <PhCopy :size=\"14\" aria-hidden=\"true\" />\n {{ i18n.t('sheet.copyErrors') }}\n </button>\n </div>\n <div v-if=\"overLimit\" class=\"dt-strip dt-sheet-strip\" role=\"status\">\n <PhWarning :size=\"16\" aria-hidden=\"true\" />\n <span>{{ i18n.t('sheet.firstN', { max: fmt.int(maxRows), entity }) }}</span>\n </div>\n\n <div v-if=\"!readOnlyDevice\" class=\"dt-formula\">\n <div class=\"dt-formula-name\">\n <template v-if=\"rangeText\">{{ rangeText }}</template>\n <template v-else-if=\"activeDef\">\n <span class=\"dt-mono\">{{ nameKey }}</span>\n <span class=\"dt-formula-col\">· {{ activeDef.header }}</span>\n </template>\n </div>\n <span class=\"dt-formula-fx\" aria-hidden=\"true\">fx</span>\n <input\n class=\"dt-formula-value\"\n type=\"text\"\n :value=\"formulaText\"\n :readonly=\"!formulaEditable\"\n :aria-label=\"valueAria\"\n autocomplete=\"off\"\n @input=\"onFormulaInput\"\n @keydown=\"onFormulaKeydown\"\n />\n <span v-if=\"savingNow\" class=\"dt-formula-hint\">\n <PhLock :size=\"12\" aria-hidden=\"true\" />\n {{ i18n.t('sheet.savingReadOnly') }}\n </span>\n <span v-else-if=\"hint\" class=\"dt-formula-hint\">{{ hint }}</span>\n </div>\n\n <SheetGrid\n ref=\"grid\"\n :sheet=\"sheet\"\n :layout=\"layout\"\n :rows=\"rowsAll\"\n :density=\"density\"\n :label=\"entity.other\"\n :entity=\"entity\"\n :loading=\"loadingNow\"\n :skeleton=\"loadingNow\"\n :read-only=\"savingNow\"\n :vertical-lines=\"pref.prefs.verticalLines\"\n :key-column=\"keyColumn\"\n :found=\"matches?.map ?? null\"\n :sort=\"sortMap\"\n :phone=\"readOnlyDevice\"\n >\n <template v-if=\"!loadingNow && rowsAll.length === 0\" #state>\n <slot name=\"empty\">\n <StateMessage kind=\"empty\" :title=\"i18n.t('state.emptyTitle', { entity })\" />\n </slot>\n </template>\n </SheetGrid>\n\n <div v-if=\"readOnlyDevice\" class=\"dt-sheet-footer\" role=\"status\">\n <span>{{ i18n.t('sheet.readOnly.total', { count: fmt.int(store.allRows.value.length), entity }) }}</span>\n <span aria-hidden=\"true\">·</span>\n <span class=\"dt-sheet-footer-badge\">\n <PhLock :size=\"14\" aria-hidden=\"true\" />\n {{ i18n.t('sheet.readOnly.badge') }}\n </span>\n </div>\n <div v-else class=\"dt-status\" role=\"status\" :aria-label=\"i18n.t('sheet.statusAria')\">\n <span class=\"dt-status-rows\">\n {{\n loadingNow ? i18n.t('common.loading') : i18n.t('sheet.rows', { count: fmt.int(store.allRows.value.length) })\n }}\n </span>\n <template v-if=\"!loadingNow\">\n <span v-if=\"savedSummary\" class=\"dt-status-saved\">\n <PhCheck :size=\"14\" aria-hidden=\"true\" />\n <strong>{{ i18n.t('sheet.saved', { count: fmt.int(savedSummary.count) }) }}</strong>\n <span>\n ·\n {{\n i18n.t('sheet.savedDetail', {\n created: fmt.int(savedSummary.created),\n updated: fmt.int(savedSummary.updated),\n })\n }}\n </span>\n </span>\n <span v-else-if=\"counts.changedCells\" class=\"dt-status-changes\">\n <span class=\"dt-mark is-changed\" aria-hidden=\"true\" />\n {{ changesText }}\n </span>\n <span v-else class=\"dt-status-muted\">{{ changesText }}</span>\n <span v-if=\"counts.newRows\" class=\"dt-status-new\">\n {{ i18n.t('sheet.newRows', { count: counts.newRows }) }}\n </span>\n <button v-if=\"counts.errorRows\" type=\"button\" class=\"dt-status-errors\" @click=\"goToError(1)\">\n <span class=\"dt-mark is-error\" aria-hidden=\"true\" />\n {{ i18n.t('sheet.errorsGoTo', { count: counts.errorRows }) }}\n </button>\n <span v-if=\"summary\" class=\"dt-status-summary\" :aria-label=\"i18n.t('sheet.selectionSummary')\">\n <span>\n {{ i18n.t('sheet.agg.count') }}\n <b>{{ fmt.int(summary.count) }}</b>\n </span>\n <span v-if=\"summary.sum !== null\">\n {{ i18n.t('sheet.agg.sum') }}\n <b>{{ summary.sum }}</b>\n </span>\n <span v-if=\"summary.avg !== null\">\n {{ i18n.t('sheet.agg.avg') }}\n <b>{{ summary.avg }}</b>\n </span>\n </span>\n </template>\n </div>\n\n <div v-if=\"toast\" class=\"dt-toast dt-sheet-toast\" role=\"status\">\n <strong>{{ toast.text }}</strong>\n <template v-if=\"toast.issues\">\n <span aria-hidden=\"true\">·</span>\n <span class=\"dt-toast-warn\">{{ toast.issues }}</span>\n <button v-if=\"toast.review\" type=\"button\" class=\"dt-toast-link\" @click=\"toast.review()\">\n {{ i18n.t('sheet.review') }}\n </button>\n </template>\n <button v-if=\"toast.action\" type=\"button\" class=\"dt-toast-link\" @click=\"toastAction\">\n {{ toast.action.label }}\n </button>\n <template v-if=\"toast.undo\">\n <span class=\"dt-toast-sep\" aria-hidden=\"true\" />\n <button type=\"button\" class=\"dt-toast-undo\" @click=\"toastUndo\">\n {{ i18n.t('common.undo') }}\n <kbd class=\"dt-kbd\">{{ UNDO_KBD }}</kbd>\n </button>\n </template>\n </div>\n <span class=\"dt-sr-only\" aria-live=\"polite\">{{ polite }}</span>\n <span class=\"dt-sr-only\" aria-live=\"assertive\">{{ assertive }}</span>\n <div\n v-show=\"tooltip.open.value\"\n class=\"dt-tip\"\n :class=\"{ 'is-multi': tooltip.text.value.includes('\\n') }\"\n role=\"tooltip\"\n :style=\"tooltip.style.value\"\n >\n {{ tooltip.text.value }}\n </div>\n <ConfirmDialog\n v-model:open=\"discardOpen\"\n :title=\"i18n.t('sheet.discard.title', { cells: fmt.int(counts.changedCells), rows: fmt.int(counts.changedRows) })\"\n :body=\"i18n.t('sheet.discard.body')\"\n :confirm-label=\"i18n.t('sheet.leave.discard')\"\n :cancel-label=\"i18n.t('sheet.discard.keep')\"\n danger\n @confirm=\"discard\"\n />\n <ImportDialog\n v-if=\"parseFile && importOpen\"\n v-model:open=\"importOpen\"\n :parse-file=\"parseFile\"\n :columns=\"sheetColumns\"\n :key-column=\"keyColumn\"\n :entity=\"entity\"\n :max-rows=\"maxRows\"\n :row-count=\"store.allRows.value.length\"\n :in-list=\"inList\"\n :lookup-keys=\"lookupKeys\"\n :parse-env=\"parseEnv\"\n :fmt-env=\"fmtEnv\"\n @apply=\"applyImport\"\n />\n <SaveErrorsDialog\n v-if=\"errorDialogOpen\"\n v-model:open=\"errorDialogOpen\"\n :errors=\"errorItems\"\n :ok-rows=\"store.getChanges().rows.length\"\n @fix=\"fixFirst\"\n @save=\"emitSave\"\n />\n </div>\n</template>\n","<script setup lang=\"ts\" generic=\"Row extends object\">\n// DataSheet (07, brief §8, handoff 06) — Faz 6a–6c: ızgara, editörler, doğrulama, taslak deposu; toolbar'da Find,\n// All / Changed / Errors, Undo/Redo, Add row, Display + Save kontrolleri; formül çubuğu; status bar; açılış ilerlemesi;\n// pano, fill handle, komut yığını; satır partisi (ekle / çıkar, lookupKeys New/Update, anahtar tekilliği); yerel\n// sıralama; kayıt akışı (hata dialog'u, `@save`, `saving`, `applyResult`, Partly saved şeridi, Copy errors); ayrılma\n// koruması. İçe/dışa aktarma ve telefon düzeni (6d) sonraki fazda. Veri çekmez, kaydetmez (D18): yalnızca `@save` yayar.\nimport {\n PhArrowUUpLeft,\n PhArrowUUpRight,\n PhCaretDown,\n PhCaretUp,\n PhCheck,\n PhCircleNotch,\n PhCopy,\n PhLock,\n PhDownloadSimple,\n PhExport,\n PhLink,\n PhMonitor,\n PhPlus,\n PhWarning,\n PhWarningCircle,\n} from '@phosphor-icons/vue'\nimport {\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuPortal,\n DropdownMenuRoot,\n DropdownMenuSub,\n DropdownMenuSubContent,\n DropdownMenuSubTrigger,\n DropdownMenuTrigger,\n ToggleGroupItem,\n ToggleGroupRoot,\n} from 'reka-ui'\nimport {\n computed,\n nextTick,\n onBeforeUnmount,\n onMounted,\n provide,\n ref,\n shallowRef,\n type Component,\n useTemplateRef,\n watch,\n} from 'vue'\nimport { comparator } from '../core/cells/compare'\nimport { formatCell, isEmptyValue, optionLabel, type FormatEnv } from '../core/cells/format'\nimport { RemoteLabels } from '../core/cells/remoteLabels'\nimport { TYPE_SPECS, typeLabelKey } from '../core/cells/specs'\nimport { useColumnLayout } from '../core/columns/useColumnLayout'\nimport { getFormat } from '../core/format'\nimport { useDelegatedTooltip } from '../core/grid/useDelegatedTooltip'\nimport { FIND_KBD, REDO_KBD, SAVE_KBD, UNDO_KBD } from '../core/interaction/kbd'\nimport { useDataTableContext } from '../core/plugin'\nimport { usePreferences } from '../core/preferences/usePreferences'\nimport StateMessage from '../core/states/StateMessage.vue'\nimport DisplayPopover from '../core/toolbar/DisplayPopover.vue'\nimport SearchBox from '../core/toolbar/SearchBox.vue'\nimport ConfirmDialog from '../core/ui/ConfirmDialog.vue'\nimport type { ColumnDef, ColumnType } from '../types/columns'\nimport type { Density, Plural, TableId } from '../types/core'\nimport type { SortRule } from '../types/query'\nimport type {\n ParsedWorkbook,\n Progress,\n SheetChanges,\n SheetFilterMode,\n SheetRowResult,\n SheetStatus,\n} from '../types/sheet'\nimport { matrixFromClipboard, parseTsv, toHtml, toTsv } from './clipboard'\nimport NumberCell from './editors/NumberCell.vue'\nimport OptionCell from './editors/OptionCell.vue'\nimport TextCell from './editors/TextCell.vue'\nimport DateCell from './editors/DateCell.vue'\nimport MultiCell from './editors/MultiCell.vue'\nimport { SHEET_EDITOR_KEY } from './editors/context'\nimport { fillValues } from './fill'\nimport ImportDialog, { type ImportPayload } from './ImportDialog.vue'\nimport { inferDecimal, inputText, parseInput, type ParseEnv } from './parse'\nimport SaveErrorsDialog, { type ErrorRowItem } from './SaveErrorsDialog.vue'\nimport SheetGrid from './SheetGrid.vue'\nimport { useSheetEditing, type SheetApi } from './useSheetEditing'\nimport { useSheetStore, type Change, type Step } from './useSheetStore'\nimport { useSheetTable } from './useSheetTable'\n\nconst props = withDefaults(\n defineProps<{\n tableId: TableId\n columns: Array<ColumnDef<Row>>\n rows: Row[]\n rowKey?: string\n /** Verilmezse tercihten (Display › Density), o da yoksa compact (02 · Yoğunluk). */\n density?: Density\n entityName?: Plural\n /** Upsert anahtarı olan sütun (ör. \"sku\"). Yüklenmiş satırlarda salt okunur; `rowKey`'den ayrıdır. */\n keyColumn: string\n /** Uygulama satırları yüklerken; sayaç verilirse \"Loading… 6,200 of 10,000\". Düzenleme false olunca açılır. */\n loading?: Progress\n /** `@save` sonrası uygulama kaydederken: grid salt okunur, ilerleme şeridi (07 §14). */\n saving?: Progress\n /** Yeni satırlarda yazılan anahtarların kontrolü (New / Update, 07 §9). Verilmezse her bilinmeyen anahtar New. */\n lookupKeys?: (keys: string[], ctx: { signal: AbortSignal }) => Promise<Record<string, Row | null>>\n /** Add row ile oluşan satırın başlangıç değerleri. */\n newRowDefaults?: () => Partial<Row>\n /** Import Excel / CSV: dosyayı uygulama ayrıştırır ve ham satırları verir (07 §13). Verilmezse Import yok. */\n parseFile?: (file: File) => Promise<ParsedWorkbook>\n /** Aşılırsa ilk `maxRows` satır kullanılır ve şerit uyarır (07 §15); yapıştırma ve ekleme bu sınırı aşamaz. */\n maxRows?: number\n /** Bu genişliğin altında veya yalnızca dokunmatikte salt okunur (D14); karar açılışta. */\n readOnlyBelow?: number\n }>(),\n { rowKey: 'id', loading: false, saving: false, maxRows: 10_000, readOnlyBelow: 768 },\n)\nconst emit = defineEmits<{\n /** Save: doğrulama geçen değişmiş + yeni satırlar. Uygulama kaydeder, `saving` verir, `applyResult` çağırır. */\n save: [changes: SheetChanges]\n /** Export: değerler güncel (kaydedilmemiş değişiklikler dahil); dosyayı uygulama yazar. */\n export: [payload: { format: 'csv' | 'xlsx'; scope: 'all' | 'visible'; columns: string[]; rows: Row[] }]\n}>()\ndefineSlots<{ empty?: () => unknown }>()\n\nconst ctx = useDataTableContext()\nconst { i18n } = ctx\nconst fmt = getFormat(ctx.locale)\nconst entity = computed<Plural>(() => props.entityName ?? { one: props.tableId, other: props.tableId })\n\nconst pref = usePreferences(() => props.tableId, ctx.preferences, {\n density: props.density ?? 'compact',\n verticalLines: true,\n pageSize: 0,\n defaultViewId: null,\n})\nconst density = computed<Density>(() => props.density ?? pref.prefs.density)\n\nconst overLimit = computed(() => props.rows.length > props.maxRows)\nconst loadedRows = computed(() => (overLimit.value ? props.rows.slice(0, props.maxRows) : props.rows))\nconst loadingNow = computed(() => props.loading !== false)\nconst savingNow = computed(() => props.saving !== false)\nconst progress = computed(() => {\n const p = loadingNow.value ? props.loading : props.saving\n return typeof p === 'object' ? p : null\n})\nconst percent = computed(() =>\n progress.value && progress.value.total > 0 ? Math.round((100 * progress.value.done) / progress.value.total) : null,\n)\n\n// Sütunlar (07 §3): anahtar 128 px sola sabit (mono), birincil ad sola sabit ve esnek; sıra sabit, genişlik oturumluk.\n// Telefon / yalnızca dokunmatik: salt okunur, karar açılışta (D14, 07 §17): anahtar 104 px sabit, kalanlar kayar.\nconst readOnlyDevice =\n typeof matchMedia === 'function' &&\n (matchMedia(`(max-width: ${props.readOnlyBelow - 1}px)`).matches || !matchMedia('(any-pointer: fine)').matches)\nconst sheetColumns = computed<Array<ColumnDef<Row>>>(() =>\n props.columns.map((d) =>\n d.id === props.keyColumn\n ? { ...d, pinned: 'left', width: readOnlyDevice ? 104 : 128 }\n : d.primary && !readOnlyDevice\n ? { ...d, pinned: 'left' }\n : d,\n ),\n)\nconst defById = computed(() => new Map(sheetColumns.value.map((d) => [d.id as string, d])))\nconst keyDef = computed(() => defById.value.get(props.keyColumn))\nconst primaryDef = computed(() => sheetColumns.value.find((d) => d.primary))\nconst store = useSheetStore<Row>({\n rows: loadedRows,\n columns: sheetColumns,\n rowKey: () => props.rowKey,\n keyColumn: () => props.keyColumn,\n i18n,\n locale: ctx.locale,\n})\n\n// Gösterim sırası (07 §10–11): parti sırası ya da header tıklamasında alınan sıralama anlık görüntüsü (düzenlenen satır\n// imlecin altından kaçmaz); eklenen satır yerine konur; All / Changed / Errors görünümü ve çıkarılanlar süzülür.\nconst sortRules = ref<SortRule[]>([])\nconst order = shallowRef<string[] | null>(null)\nconst view = ref<SheetFilterMode>('all')\nconst viewKeys = shallowRef(new Set<string>())\nconst matchesView = (key: string) =>\n view.value === 'changed'\n ? !!store.rowDraft(key)?.size || store.isNew(key)\n : view.value === 'errors'\n ? store.hasError(key)\n : true\nconst refreshView = (union: boolean) => {\n const next = union ? new Set(viewKeys.value) : new Set<string>()\n for (const r of store.batch.value) {\n const k = store.keyOf(r)\n if (matchesView(k)) next.add(k)\n }\n viewKeys.value = next\n}\n/** Görünüm değişimi eşzamanlı uygulanır: hemen ardından gelen `goToError` doğru satır listesini görür. */\nconst setView = (v: SheetFilterMode) => {\n view.value = v\n refreshView(false)\n}\n// Görünümde kalma kuralı: son hatayı düzelttiğin satır görünümden çıkana kadar yerinde kalır; yeni uyanlar eklenir.\nwatch(store.version, () => {\n if (view.value !== 'all') refreshView(true)\n})\nconst orderedBatch = computed<Row[]>(() => {\n const batch = store.batch.value\n const o = order.value\n if (!o) return batch\n const seen = new Set(o)\n const rows: Row[] = []\n for (const k of o) {\n const r = store.rowByKey(k)\n if (r) rows.push(r)\n }\n for (const r of batch) if (!seen.has(store.keyOf(r))) rows.push(r)\n return rows\n})\n/** Gösterilen satırlar: sıra + görünüm + çıkarılanlar. */\nconst rowsAll = computed<Row[]>(() => {\n const all = view.value === 'all'\n const keys = viewKeys.value\n return orderedBatch.value.filter((r) => {\n const k = store.keyOf(r)\n return !store.isRemoved(k) && (all || keys.has(k))\n })\n})\nconst layout = useColumnLayout<Row>({\n columns: sheetColumns,\n rows: rowsAll,\n rowKey: () => props.rowKey,\n flexLastStart: true,\n})\nconst table = useSheetTable<Row>({\n rows: rowsAll,\n columnIds: () => layout.columns.value.map((c) => c.id),\n rowId: store.keyOf,\n})\nconst indexByKey = computed(() => {\n const m = new Map<string, number>()\n rowsAll.value.forEach((r, i) => m.set(store.keyOf(r), i))\n return m\n})\nconst visibleCols = computed(() => layout.columns.value)\n\nconst readOnlyNow = computed(() => loadingNow.value || savingNow.value || readOnlyDevice)\n\n// Editörler filtre değer girişleriyle aynı aileden (07 §5); `boolean` editör açmaz (Space). ajax/user/object/array için\n// yalnızca özel editör (`ColumnDef.editor`).\nconst EDITORS: Partial<Record<ColumnType, Component>> = {\n string: TextCell,\n text: TextCell,\n uppercase: TextCell,\n lowercase: TextCell,\n email: TextCell,\n url: TextCell,\n phone: TextCell,\n id: TextCell,\n color: TextCell,\n int: NumberCell,\n float: NumberCell,\n percentage: NumberCell,\n currency: NumberCell,\n star: NumberCell,\n select: OptionCell,\n multiselect: MultiCell,\n date: DateCell,\n datetime: DateCell,\n}\nconst editorFor = (def: ColumnDef<Row>): Component | null => def.editor ?? EDITORS[def.type] ?? null\n/** Sütunlar varsayılan salt okunur; anahtar sütun yüklenmiş satırlarda her zaman (yeni satırda açık); yüklenirken, kaydederken ve telefonda hiçbiri. */\nconst canEdit = (row: Row, def: ColumnDef<Row>): boolean => {\n if (readOnlyNow.value) return false\n const isNew = store.isNew(store.keyOf(row))\n if (def.id === props.keyColumn) return isNew\n if (def.type !== 'boolean' && !editorFor(def)) return false\n return typeof def.editable === 'function' ? def.editable(store.current(row), { isNew }) : def.editable === true\n}\n\nconst parseEnv = (locale = ctx.locale): ParseEnv => ({\n locale,\n today: new Date(),\n todayWord: i18n.t('date.today'),\n yesWord: i18n.t('common.yes'),\n noWord: i18n.t('common.no'),\n})\nconst edit = useSheetEditing<Row>({ store, canEdit, parse: (def, text) => parseInput(def, text, parseEnv()) })\nprovide(SHEET_EDITOR_KEY, { seed: () => edit.editing.value?.seed })\nconst grid = useTemplateRef<InstanceType<typeof SheetGrid>>('grid')\nconst counts = store.counts\nconst fmtEnv: FormatEnv = { fmt, i18n, today: new Date(), labels: new RemoteLabels() }\n\n/** Aralığı seçer ve odaklar (yapıştırma, doldurma, undo sonrası). */\nconst selectCells = (r1: number, c1: number, r2: number, c2: number) => {\n const rows = rowsAll.value\n const cols = visibleCols.value\n const a = rows[r1]\n const b = rows[r2]\n if (!a || !b || !cols[c1] || !cols[c2]) return\n table.selectRange({\n anchorRowId: store.keyOf(a),\n anchorColumnId: cols[c1]!.id,\n focusRowId: store.keyOf(b),\n focusColumnId: cols[c2]!.id,\n })\n grid.value?.focusActive()\n}\nconst focusCell = (r: number, columnId: string) => {\n const row = rowsAll.value[Math.max(0, Math.min(rowsAll.value.length - 1, r))]\n if (!row) return\n table.focus(store.keyOf(row), columnId)\n grid.value?.focusActive()\n}\n/** Seçimdeki (ya da aktif) hücreler. */\nconst selectedCells = (): Array<{ r: number; c: number }> => {\n const b = table.bounds.value\n if (!b) return []\n const out: Array<{ r: number; c: number }> = []\n for (let r = b.minRowIndex; r <= b.maxRowIndex; r++)\n for (let c = b.minColumnIndex; c <= b.maxColumnIndex; c++) out.push({ r, c })\n return out\n}\n\nconst toggle = (row: Row, def: ColumnDef<Row>) => store.set(row, def, !store.read(row, def))\n/** Delete / ⌘X: seçimdeki düzenlenebilir hücreler boşalır, tek adım. */\nconst clearSelected = () => {\n const changes: Array<Change<Row>> = []\n for (const { r, c } of selectedCells()) {\n const row = rowsAll.value[r]\n const def = visibleCols.value[c]?.def\n if (row && def && canEdit(row, def)) changes.push({ row, def, value: null })\n }\n store.apply(changes)\n}\n\n// Hatalar (07 §11, §14): gösterim sırasında; görünüm gizliyorsa toast \"Next error is hidden by filters · Show it\".\nconst errorKeysInOrder = computed(() => {\n void store.version.value\n return orderedBatch.value.map((r) => store.keyOf(r)).filter((k) => !store.isRemoved(k) && store.hasError(k))\n})\nconst goToError = (dir: 1 | -1) => {\n const rows = rowsAll.value\n const n = rows.length\n const a = table.active.value\n const from = a ? (indexByKey.value.get(a.rowId) ?? -1) : -1\n for (let s = 1; s <= n; s++) {\n const i = (((from + dir * s) % n) + n) % n\n const key = store.keyOf(rows[i]!)\n if (!store.hasError(key)) continue\n const issues = store.rowIssues(key)\n const col =\n visibleCols.value.find((c) => issues?.get(c.id)?.level === 'error') ??\n (store.rowError(key) ? visibleCols.value.find((c) => c.id === props.keyColumn) : undefined)\n if (!col) continue\n table.focus(key, col.id)\n grid.value?.focusActive()\n return\n }\n if (errorKeysInOrder.value.length && view.value !== 'all')\n showToast({\n text: i18n.t('sheet.nextErrorHidden'),\n action: {\n label: i18n.t('sheet.showIt'),\n run: () => {\n setView('all')\n goToError(dir)\n },\n },\n })\n}\n\n// Pano (07 §7): görüntülenen biçimde TSV + HTML; para kodu ve \"—\" yok, tarihler ISO, listeler `; ` ile (geri yapıştırılabilir).\nconst copyText = (def: ColumnDef<Row>, row: Row, value: unknown): string => {\n if (isEmptyValue(value)) return ''\n switch (def.type) {\n case 'currency':\n return fmt.decimal(Number(value), def.decimalPlaces ?? 2)\n case 'date':\n case 'datetime':\n return value instanceof Date ? value.toISOString() : String(value)\n case 'multiselect':\n return (value as unknown[]).map((v) => optionLabel(def.options, v)).join('; ')\n case 'string':\n case 'text':\n case 'uppercase':\n case 'lowercase':\n case 'email':\n case 'url':\n case 'phone':\n case 'id':\n return String(value)\n default:\n return formatCell(def, row, value, fmtEnv)\n }\n}\nconst copyMatrix = (): string[][] | null => {\n const b = table.bounds.value\n if (!b) return null\n const out: string[][] = []\n for (let r = b.minRowIndex; r <= b.maxRowIndex; r++) {\n const row = rowsAll.value[r]\n if (!row) continue\n const line: string[] = []\n for (let c = b.minColumnIndex; c <= b.maxColumnIndex; c++) {\n const def = visibleCols.value[c]!.def\n line.push(copyText(def, row, store.read(row, def)))\n }\n out.push(line)\n }\n return out\n}\nconst copy = (data: DataTransfer | null): boolean => {\n const m = copyMatrix()\n if (!m || !data) return false\n data.setData('text/plain', toTsv(m))\n data.setData('text/html', toHtml(m))\n return true\n}\nconst cut = (data: DataTransfer | null): boolean => {\n if (!copy(data)) return false\n if (!readOnlyNow.value) clearSelected()\n return true\n}\n/** Hücre menüsü › Copy / Cut: `navigator.clipboard` (TSV + HTML; yalnızca metin destekleniyorsa TSV). */\nconst copyToClipboard = (cutAfter: boolean) => {\n const m = copyMatrix()\n const clip = typeof navigator !== 'undefined' ? navigator.clipboard : undefined\n if (!m || !clip) return\n const tsv = toTsv(m)\n const write =\n typeof ClipboardItem === 'function' && clip.write\n ? clip.write([\n new ClipboardItem({\n 'text/plain': new Blob([tsv], { type: 'text/plain' }),\n 'text/html': new Blob([toHtml(m)], { type: 'text/html' }),\n }),\n ])\n : clip.writeText(tsv)\n void write.catch(() => clip.writeText(tsv)).catch(() => {})\n if (cutAfter && !readOnlyNow.value) clearSelected()\n}\nconst pasteMatrix = (matrix: string[][]): boolean => {\n const a = table.active.value\n const width = Math.max(0, ...matrix.map((l) => l.length))\n if (!a || !matrix.length || !width || readOnlyNow.value) return false\n const cols = visibleCols.value\n const startRow = indexByKey.value.get(a.rowId)\n const startCol = cols.findIndex((c) => c.id === a.columnId)\n if (startRow === undefined || startCol < 0) return false\n const b = table.bounds.value\n const targets: Array<{ r: number; c: number; text: string }> = []\n if (\n matrix.length === 1 &&\n width === 1 &&\n b &&\n (b.maxRowIndex > b.minRowIndex || b.maxColumnIndex > b.minColumnIndex)\n ) {\n // Tek değer + aralık: değer tüm aralığa (07 §7).\n for (const { r, c } of selectedCells()) targets.push({ r, c, text: matrix[0]![0]! })\n } else {\n matrix.forEach((line, i) =>\n line.forEach((text, j) => {\n if (startCol + j < cols.length) targets.push({ r: startRow + i, c: startCol + j, text })\n }),\n )\n }\n const lastRow = Math.max(...targets.map((t) => t.r))\n const overflow = lastRow - rowsAll.value.length + 1\n if (overflow > 0 && store.allRows.value.length + overflow > props.maxRows) {\n showToast({\n text: i18n.t('sheet.limitPaste', {\n count: fmt.int(store.allRows.value.length + overflow),\n max: fmt.int(props.maxRows),\n }),\n })\n return true\n }\n // Son satırın altına taşanlar yeni satır olur; anahtar boşsa \"Required\" (07 §7).\n const addedRows = overflow > 0 ? store.addRows(overflow) : []\n if (addedRows.length && order.value) order.value = [...order.value, ...addedRows.map((x) => x.key)]\n const rows = rowsAll.value\n // Sayılar panonun yerel ayarıyla: sütun bazında çıkarım, belirsizse uygulama locale'i.\n const localeByCol = new Map<number, string>()\n for (const c of new Set(targets.map((t) => t.c))) {\n const def = cols[c]!.def\n if (!TYPE_SPECS[def.type].numeric) continue\n const dec = inferDecimal(targets.filter((t) => t.c === c).map((t) => t.text))\n localeByCol.set(c, dec === ',' ? 'de' : dec === '.' ? 'en' : ctx.locale)\n }\n const changes: Array<Change<Row>> = []\n for (const t of targets) {\n const row = rows[t.r]\n const def = cols[t.c]?.def\n if (!row || !def || !canEdit(row, def)) continue\n changes.push({ row, def, value: parseInput(def, t.text, parseEnv(localeByCol.get(t.c))) })\n }\n store.apply(changes, addedRows)\n const minR = Math.min(...targets.map((t) => t.r))\n const minC = Math.min(...targets.map((t) => t.c))\n const maxC = Math.max(...targets.map((t) => t.c))\n selectCells(minR, minC, lastRow, maxC)\n // Toast: seçenek olmayan değerler (\"2 values aren't options\") ve diğer hatalar ayrı sayılır; Review ilk sorunlu hücre.\n const issues = targets\n .map((t) => {\n const row = rows[t.r]\n const issue = row && store.rowIssues(store.keyOf(row))?.get(cols[t.c]!.id)\n return issue?.level === 'error'\n ? { ...t, option: cols[t.c]!.def.type === 'select' || cols[t.c]!.def.type === 'multiselect' }\n : null\n })\n .filter((x): x is NonNullable<typeof x> => x !== null)\n const options = issues.filter((i) => i.option).length\n const others = issues.length - options\n const dims = { rows: lastRow - minR + 1, cols: maxC - minC + 1 }\n const first = issues[0]\n showToast({\n text: i18n.t('sheet.pasted', { rows: fmt.int(dims.rows), cols: fmt.int(dims.cols) }),\n issues:\n [\n options ? i18n.t('sheet.pasteIssues', { count: options }) : '',\n others ? i18n.t('sheet.pasteErrors', { count: others }) : '',\n ]\n .filter(Boolean)\n .join(' · ') || undefined,\n review: first ? () => selectCells(first.r, first.c, first.r, first.c) : undefined,\n undo: true,\n })\n polite.value = i18n.t('sr.pasted', dims)\n return true\n}\nconst paste = (data: DataTransfer | null): boolean => pasteMatrix(matrixFromClipboard(data))\n/** Hücre menüsü › Paste: `readText` yedeği (07 §7). */\nconst pasteFromClipboard = () => {\n void navigator.clipboard\n ?.readText()\n .then((text) => pasteMatrix(parseTsv(text)))\n .catch(() => {})\n}\n\n// Doldurma (07 §8): kaynak satır aralığı, hedef satıra kadar; seri ya da kopya, read-only atlanır, tek adım.\nconst fillPlan = (fromRow: number, toRow: number, cols: [number, number], target: number) => {\n const rows = rowsAll.value\n const up = target < fromRow\n const count = up ? fromRow - target : target - toRow\n const changes: Array<Change<Row>> = []\n for (let c = cols[0]; c <= cols[1]; c++) {\n const def = visibleCols.value[c]?.def\n if (!def) continue\n const source = rows.slice(fromRow, toRow + 1).map((r) => store.read(r, def))\n const values = fillValues(source, count, up)\n for (let k = 0; k < count; k++) {\n const row = rows[up ? fromRow - 1 - k : toRow + 1 + k]\n if (row && canEdit(row, def)) changes.push({ row, def, value: values[k] })\n }\n }\n return { changes, count }\n}\nconst fill = (fromRow: number, toRow: number, cols: [number, number], target: number) => {\n const { changes } = fillPlan(fromRow, toRow, cols, target)\n store.apply(changes)\n selectCells(Math.min(fromRow, target), cols[0], Math.max(toRow, target), cols[1])\n}\nconst fillLabel = (fromRow: number, toRow: number, cols: [number, number], target: number): string => {\n const { changes, count } = fillPlan(fromRow, toRow, cols, target)\n const first = changes[0]\n const value = first ? formatCell(first.def, first.row, first.value, fmtEnv) : ''\n return i18n.t('sheet.fillPreview', { count: count * (cols[1] - cols[0] + 1), value })\n}\nconst fillDown = () => {\n const b = table.bounds.value\n if (!b || b.maxRowIndex === b.minRowIndex) return\n fill(b.minRowIndex, b.minRowIndex, [b.minColumnIndex, b.maxColumnIndex], b.maxRowIndex)\n}\n\n// Geri al / yinele (07 §12): seçim ve aktif hücre o adımın yerine taşınır.\nconst afterStep = (step: Step | null) => {\n if (!step) return\n // Listeden çıkarma geri alındı: geri gelen satıra odak (toast'taki Undo odağı ızgaradan almıştı).\n if (step.removed?.length && !step.patches.length) {\n const i = indexByKey.value.get(step.removed[0]!)\n if (i !== undefined) focusCell(i, table.active.value?.columnId ?? visibleCols.value[0]!.id)\n return\n }\n if (!step.patches.length) return\n const idx = visibleCols.value.map((c) => c.id)\n let r1 = Infinity\n let r2 = -1\n let c1 = Infinity\n let c2 = -1\n for (const p of step.patches) {\n const r = indexByKey.value.get(p.key)\n const c = idx.indexOf(p.col)\n if (r === undefined || c < 0) continue\n r1 = Math.min(r1, r)\n r2 = Math.max(r2, r)\n c1 = Math.min(c1, c)\n c2 = Math.max(c2, c)\n }\n if (r2 >= 0) selectCells(r1, c1, r2, c2)\n}\nconst undo = () => {\n if (readOnlyNow.value) return\n edit.cancel()\n afterStep(store.undo())\n}\nconst redo = () => {\n if (readOnlyNow.value) return\n edit.cancel()\n afterStep(store.redo())\n}\nconst useSuggestion = (row: Row, def: ColumnDef<Row>, value: unknown) => store.set(row, def, value)\n\n// Satır partisi (07 §9, D12): Add row / Insert row above-below (newRowDefaults, odak anahtar hücresinde, düzenleme açık);\n// Remove from list (⌘−): nötr, sunucuda silmez, toast + Undo.\nconst addRow = (at?: number) => {\n if (readOnlyNow.value) return\n if (store.allRows.value.length + 1 > props.maxRows) {\n showToast({\n text: i18n.t('sheet.limitPaste', { count: fmt.int(store.allRows.value.length + 1), max: fmt.int(props.maxRows) }),\n })\n return\n }\n edit.commit()\n const [added] = store.addRows(1)\n if (!added) return\n const defaults = props.newRowDefaults?.() ?? {}\n const changes: Array<Change<Row>> = []\n for (const [id, value] of Object.entries(defaults)) {\n const def = defById.value.get(id)\n if (def && !isEmptyValue(value)) changes.push({ row: added.row, def, value })\n }\n store.apply(changes, [added])\n if (at !== undefined) {\n const keys = order.value ?? store.batch.value.map((r) => store.keyOf(r)).filter((k) => k !== added.key)\n const pos = Math.max(0, Math.min(keys.length, at))\n order.value = [...keys.slice(0, pos), added.key, ...keys.slice(pos)]\n } else if (order.value) order.value = [...order.value, added.key]\n if (view.value !== 'all') viewKeys.value = new Set([...viewKeys.value, added.key])\n table.focus(added.key, props.keyColumn)\n // Yeni satır görünür alana kayar (sona eklenince 5.000 satır aşağıda olabilir); sanal liste yeni sayıyı bir sonraki\n // render'da öğrendiğinden nextTick. focusActive editör açıkken kaydırmaz.\n void nextTick(() => grid.value?.scrollToIndex(rowsAll.value.findIndex((r) => store.keyOf(r) === added.key)))\n grid.value?.focusActive()\n if (keyDef.value) edit.start(added.row, keyDef.value, { inCell: true })\n}\nconst insertRow = (where: 'above' | 'below') => {\n const a = table.active.value\n const i = a ? orderedBatch.value.findIndex((r) => store.keyOf(r) === a.rowId) : -1\n addRow(i < 0 ? undefined : where === 'above' ? i : i + 1)\n}\nconst removeSelectedRows = () => {\n if (readOnlyNow.value) return\n const b = table.bounds.value\n if (!b) return\n edit.cancel()\n const rows = rowsAll.value.slice(b.minRowIndex, b.maxRowIndex + 1)\n const keys = rows.map((r) => store.keyOf(r))\n if (!keys.length) return\n store.removeRows(keys)\n showToast({\n text:\n keys.length === 1\n ? i18n.t('sheet.removed', { count: 1, row: store.rowNoOf(keys[0]!), entity: entity.value })\n : i18n.t('sheet.removed', { count: keys.length, entity: entity.value }),\n undo: true,\n })\n focusCell(b.minRowIndex, table.active.value?.columnId ?? visibleCols.value[0]!.id)\n}\n\n// Yerel sıralama (07 §10): asc → desc → kapalı, ⇧ ile ikincil (en fazla 3); anlık görüntü, gutter numaraları değişmez.\nconst sort = (columnId: string, additive: boolean) => {\n const def = defById.value.get(columnId)\n if (!def || !(def.sortable ?? TYPE_SPECS[def.type].sortable)) return\n const current = sortRules.value\n const existing = current.find((s) => s.column === columnId)\n const next: SortRule | null = !existing\n ? { column: columnId, dir: 'asc' }\n : existing.dir === 'asc'\n ? { column: columnId, dir: 'desc' }\n : null\n const rest = current.filter((s) => s.column !== columnId)\n sortRules.value = additive\n ? next\n ? existing\n ? current.map((s) => (s.column === columnId ? next : s))\n : [...rest, next].slice(-3)\n : rest\n : next\n ? [next]\n : []\n if (!sortRules.value.length) {\n order.value = null\n return\n }\n const cmps = sortRules.value.map((s) => ({\n def: defById.value.get(s.column)!,\n cmp: comparator(defById.value.get(s.column)!, ctx.locale),\n sign: s.dir === 'desc' ? -1 : 1,\n }))\n order.value = [...store.batch.value]\n .sort((a, b) => {\n for (const { def: d, cmp, sign } of cmps) {\n const r = cmp(store.read(a, d), store.read(b, d)) * sign\n if (r) return r\n }\n return store.rowNoOf(store.keyOf(a)) - store.rowNoOf(store.keyOf(b))\n })\n .map((r) => store.keyOf(r))\n}\nconst sortMap = computed(() => {\n const m = new Map<string, { dir: 'asc' | 'desc'; index: number | null }>()\n sortRules.value.forEach((s, i) => m.set(s.column, { dir: s.dir, index: sortRules.value.length > 1 ? i + 1 : null }))\n return m\n})\n\n// Anahtar kontrolü (07 §9): yeni satırın anahtarı onaylanınca 300 ms sonra `lookupKeys`; yok → New, var → Update + sunucu\n// kaydı base (Q2). Verilmemişse her bilinmeyen anahtar New.\nconst looked = new Map<string, string>()\nconst pending = new Map<string, string>()\nlet lookupTimer: ReturnType<typeof setTimeout> | undefined\nlet lookupCtl: AbortController | null = null\nconst runLookup = async () => {\n const batchKeys = new Map(pending)\n pending.clear()\n if (!batchKeys.size) return\n if (!props.lookupKeys) {\n for (const rowKey of batchKeys.keys()) store.setKeyState(rowKey, 'new')\n return\n }\n for (const rowKey of batchKeys.keys()) store.setKeyState(rowKey, 'checking')\n lookupCtl?.abort()\n lookupCtl = new AbortController()\n try {\n const values = [...new Set(batchKeys.values())].slice(0, 500)\n const result = await props.lookupKeys(values, { signal: lookupCtl.signal })\n for (const [rowKey, value] of batchKeys) {\n if (looked.get(rowKey) !== value) continue\n const found = result[value]\n if (found) {\n store.setKeyState(rowKey, 'update')\n store.setBase(rowKey, found)\n } else store.setKeyState(rowKey, 'new')\n }\n } catch {\n for (const rowKey of batchKeys.keys()) store.setKeyState(rowKey, 'new')\n }\n}\nwatch(store.version, () => {\n const def = keyDef.value\n if (!def) return\n for (const r of store.batch.value) {\n const rowKey = store.keyOf(r)\n if (!store.isNew(rowKey)) continue\n const v = store.readUntracked(r, def)\n const text = isEmptyValue(v) ? '' : String(v)\n if (looked.get(rowKey) === text) continue\n looked.set(rowKey, text)\n if (text) pending.set(rowKey, text)\n else store.setKeyState(rowKey, 'new')\n }\n if (pending.size) {\n clearTimeout(lookupTimer)\n lookupTimer = setTimeout(() => void runLookup(), 300)\n }\n})\n\n// Kayıt akışı (07 §14): hatalı satır varsa dialog; `@save` yükü; uygulama `saving` verir; `applyResult` sonuçları işler;\n// bitişte status bar sonucu ya da Partly saved şeridi (görünüm Errors, aktif hücre ilk hatada).\nconst errorDialogOpen = ref(false)\nconst errorItems = computed<ErrorRowItem[]>(() =>\n errorKeysInOrder.value\n .filter((k) => !!store.rowDraft(k)?.size || store.isNew(k))\n .map((k) => {\n const row = store.rowByKey(k)!\n const issues = store.rowIssues(k)\n const first = issues ? [...issues.values()].find((i) => i.level === 'error') : undefined\n return {\n rowNo: store.rowNoOf(k),\n key: keyDef.value ? inputText(keyDef.value, store.read(row, keyDef.value)) : k,\n message: first?.message ?? store.rowError(k) ?? '',\n }\n }),\n)\nconst saveTotals = shallowRef({ created: 0, updated: 0, errors: 0 })\nconst savedSummary = shallowRef<{ count: number; created: number; updated: number } | null>(null)\nconst partly = shallowRef<{ failed: number; saved: number } | null>(null)\nconst emitSave = () => {\n saveTotals.value = { created: 0, updated: 0, errors: 0 }\n savedSummary.value = null\n partly.value = null\n store.settleUntouched()\n emit('save', store.getChanges())\n}\nconst save = () => {\n if (readOnlyNow.value) return\n edit.commit()\n if (!counts.value.changedCells && !counts.value.newRows) return\n if (errorItems.value.length) {\n errorDialogOpen.value = true\n return\n }\n emitSave()\n}\nconst fixFirst = () => {\n setView('errors')\n goToError(1)\n}\nconst finishSave = () => {\n const t = saveTotals.value\n if (!t.created && !t.updated && !t.errors) return\n if (t.errors) {\n partly.value = { failed: t.errors, saved: t.created + t.updated }\n assertive.value = i18n.t('sheet.partly.title', { count: fmt.int(t.errors) })\n setView('errors')\n goToError(1)\n } else {\n savedSummary.value = { count: t.created + t.updated, created: t.created, updated: t.updated }\n polite.value = i18n.t('sheet.saved', { count: fmt.int(t.created + t.updated) })\n }\n saveTotals.value = { created: 0, updated: 0, errors: 0 }\n}\nlet resultVersion = -1\nconst applyResult = (results: Array<SheetRowResult<Row>>) => {\n const r = store.applyResult(results)\n resultVersion = store.version.value\n const t = saveTotals.value\n saveTotals.value = { created: t.created + r.created, updated: t.updated + r.updated, errors: t.errors + r.errors }\n if (!savingNow.value) finishSave()\n}\nwatch(savingNow, (now) => {\n if (!now) finishSave()\n})\n// Sonraki düzenlemede sonuç metni gider (applyResult'ın kendi sürüm artışı sayılmaz); hata kalmayınca şerit kapanır.\nwatch(store.version, (v) => {\n if (v !== resultVersion) savedSummary.value = null\n if (partly.value && !counts.value.errorRows) partly.value = null\n})\nconst partlyIndex = computed(() => {\n const a = table.active.value\n const i = a ? errorKeysInOrder.value.indexOf(a.rowId) : -1\n return i < 0 ? 0 : i + 1\n})\n/** Copy errors (07 §14): TSV, başlık Row · anahtar sütunu · Column · Message. */\nconst copyErrors = () => {\n const lines: string[][] = [\n [\n i18n.t('sheet.err.row'),\n keyDef.value?.header ?? props.keyColumn,\n i18n.t('sheet.err.column'),\n i18n.t('sheet.err.message'),\n ],\n ]\n for (const k of errorKeysInOrder.value) {\n const row = store.rowByKey(k)!\n const keyText = keyDef.value ? inputText(keyDef.value, store.read(row, keyDef.value)) : k\n const rowErr = store.rowError(k)\n if (rowErr) lines.push([String(store.rowNoOf(k)), keyText, '', rowErr])\n for (const [col, issue] of store.rowIssues(k) ?? [])\n if (issue.level === 'error')\n lines.push([String(store.rowNoOf(k)), keyText, defById.value.get(col)?.header ?? col, issue.message])\n }\n void navigator.clipboard?.writeText(toTsv(lines)).catch(() => {})\n}\nconst openHref = (row: Row): string | undefined => {\n if (store.isNew(store.keyOf(row))) return undefined\n return keyDef.value?.href?.(row) ?? primaryDef.value?.href?.(row)\n}\n\n// Import (07 §13): listede olan anahtar güncellenir; sunucuda olan Update satırı (base), olmayan New satırı; tek undo adımı.\nconst importOpen = ref(false)\nconst keyIndexSet = computed(() => {\n void store.version.value\n const set = new Set<string>()\n const def = keyDef.value\n if (!def) return set\n for (const r of store.allRows.value) {\n const v = store.readUntracked(r, def)\n if (!isEmptyValue(v)) set.add(String(v))\n }\n return set\n})\nconst inList = (key: string) => keyIndexSet.value.has(key)\nconst applyImport = (payload: ImportPayload<Row>) => {\n if (readOnlyNow.value || !keyDef.value) return\n edit.commit()\n const def = keyDef.value\n const byKeyValue = new Map<string, Row>()\n for (const r of store.allRows.value) {\n const v = store.readUntracked(r, def)\n if (!isEmptyValue(v)) byKeyValue.set(String(v), r)\n }\n const changes: Array<Change<Row>> = []\n const addedRows: Array<{ key: string; row: Row }> = []\n const bases: Array<{ key: string; row: Row }> = []\n let updated = 0\n let news = 0\n for (const item of payload.rows) {\n let row = byKeyValue.get(item.key)\n if (!row) {\n if (item.server === null && !payload.addNew) continue\n if (store.allRows.value.length + addedRows.length + 1 > props.maxRows) break\n const [a] = store.addRows(1)\n if (!a) continue\n row = a.row\n addedRows.push(a)\n byKeyValue.set(item.key, row)\n changes.push({ row, def, value: item.key })\n if (item.server) {\n bases.push({ key: a.key, row: item.server })\n updated++\n } else news++\n } else updated++\n for (const [id, value] of Object.entries(item.values)) {\n const d = defById.value.get(id)\n if (d && canEdit(row, d)) changes.push({ row, def: d, value })\n }\n }\n for (const b of bases) {\n store.setKeyState(b.key, 'update')\n store.setBase(b.key, b.row)\n }\n store.apply(changes, addedRows)\n if (addedRows.length && order.value) order.value = [...order.value, ...addedRows.map((a) => a.key)]\n showToast({\n text: i18n.t('import.done', {\n count: fmt.int(payload.rows.length),\n updated: fmt.int(updated),\n news: fmt.int(news),\n }),\n undo: true,\n })\n // Odak ızgaraya, ilk alınan satırın anahtar hücresine (dialog kapanınca odak Import düğmesine dönerdi).\n const firstKey = payload.rows[0]?.key\n const firstRow = firstKey ? byKeyValue.get(firstKey) : undefined\n const i = firstRow ? indexByKey.value.get(store.keyOf(firstRow)) : undefined\n if (i !== undefined) focusCell(i, props.keyColumn)\n}\n/** Export (07 §2): All / Visible › CSV / Excel; değerler güncel (taslak uygulanmış), dosyayı uygulama yazar. */\nconst exportRows = (format: 'csv' | 'xlsx', scope: 'all' | 'visible') => {\n edit.commit()\n const rows = (scope === 'all' ? store.allRows.value : rowsAll.value).map((r) => store.current(r))\n emit('export', { format, scope, columns: visibleCols.value.map((c) => c.id), rows })\n}\nconst exportLabel = (scope: 'all' | 'visible') =>\n i18n.t(scope === 'all' ? 'sheet.exportAll' : 'sheet.exportVisible', {\n count: fmt.int(scope === 'all' ? store.allRows.value.length : rowsAll.value.length),\n })\nconst copyLink = () => void navigator.clipboard?.writeText(location.href).catch(() => {})\n\nconst sheet: SheetApi<Row> = {\n store,\n table,\n edit,\n canEdit,\n editorFor,\n toggle,\n clearCells: clearSelected,\n save,\n goToError,\n copy,\n cut,\n paste,\n fill,\n fillLabel,\n fillDown,\n undo,\n redo,\n useSuggestion,\n copyToClipboard,\n pasteFromClipboard,\n insertRow,\n removeSelectedRows,\n sort,\n openHref,\n}\n\n// Izgara dışına tık onaylar (07 §5): formül çubuğu ve portallı editör katmanları (`dt-sheet-layer`) dışarı sayılmaz.\nconst onDocPointerdown = (e: PointerEvent) => {\n if (!edit.editing.value) return\n const t = e.target as Element | null\n if (t?.closest('.dt-cell.is-editing, .dt-formula, .dt-sheet-layer')) return\n edit.commit()\n}\n// Ayrılma koruması (07 §14): değişiklik varken tarayıcı uyarısı; yönlendirici dialog'u uygulamanın (`isDirty()`).\nconst isDirty = () => counts.value.changedCells > 0 || counts.value.newRows > 0\nconst onBeforeUnload = (e: BeforeUnloadEvent) => {\n if (!isDirty()) return\n e.preventDefault()\n e.returnValue = ''\n}\nonMounted(() => {\n document.addEventListener('pointerdown', onDocPointerdown, true)\n window.addEventListener('beforeunload', onBeforeUnload)\n})\nonBeforeUnmount(() => {\n document.removeEventListener('pointerdown', onDocPointerdown, true)\n window.removeEventListener('beforeunload', onBeforeUnload)\n clearTimeout(toastTimer)\n clearTimeout(lookupTimer)\n lookupCtl?.abort()\n})\n\n// ⌘S / ⌘F odak sheet içindeyken (07 §2); ızgara kendi işlediyse (defaultPrevented) tekrar etmez.\nconst findBox = useTemplateRef<InstanceType<typeof SearchBox>>('findBox')\nconst onRootKeydown = (e: KeyboardEvent) => {\n if (e.defaultPrevented || !(e.metaKey || e.ctrlKey)) return\n const k = e.key.toLowerCase()\n if (k === 's') {\n e.preventDefault()\n save()\n } else if (k === 'f' && !loadingNow.value) {\n e.preventDefault()\n findBox.value?.focus()\n }\n}\n\n// Find in grid (07 §2): görünür sütunlarda görüntülenen metin; eşleşmeler vurgulanır, satır gizlenmez; Enter / ⇧Enter gezer.\nconst fold = (s: string) => s.toLocaleLowerCase(ctx.locale)\nconst findText = ref('')\nconst findIndex = ref(0)\nconst matches = computed(() => {\n const q = fold(findText.value.trim())\n if (!q) return null\n void store.version.value\n const map = new Map<string, Set<string>>()\n const list: Array<{ r: number; c: number }> = []\n const rows = rowsAll.value\n const cols = visibleCols.value\n for (let r = 0; r < rows.length; r++) {\n const row = rows[r]!\n for (let c = 0; c < cols.length; c++) {\n const def = cols[c]!.def\n const v = store.readUntracked(row, def)\n if (isEmptyValue(v) || !fold(formatCell(def, row, v, fmtEnv)).includes(q)) continue\n const key = store.keyOf(row)\n let set = map.get(key)\n if (!set) map.set(key, (set = new Set()))\n set.add(def.id as string)\n list.push({ r, c })\n }\n }\n return { map, list }\n})\nconst goToMatch = (i: number) => {\n const m = matches.value?.list[i]\n if (!m) return\n findIndex.value = i\n const row = rowsAll.value[m.r]!\n table.focus(store.keyOf(row), visibleCols.value[m.c]!.id)\n grid.value?.scrollToIndex(m.r)\n}\nwatch(\n () => matches.value?.list.length ?? 0,\n () => goToMatch(0),\n)\nconst findStep = (dir: 1 | -1) => {\n const n = matches.value?.list.length ?? 0\n if (n) goToMatch((((findIndex.value + dir) % n) + n) % n)\n}\nconst onFindKeydown = (e: KeyboardEvent) => {\n if (e.key === 'Enter') {\n e.preventDefault()\n findStep(e.shiftKey ? -1 : 1)\n } else if (e.key === 'Escape' && !findText.value) {\n e.preventDefault()\n grid.value?.focusActive()\n }\n}\nconst findCount = computed(() =>\n matches.value\n ? i18n.t('sheet.findCount', {\n index: matches.value.list.length ? findIndex.value + 1 : 0,\n total: matches.value.list.length,\n })\n : '',\n)\n\n// All / Changed / Errors sayaçları (07 §11).\nconst viewCounts = computed(() => ({\n all: store.allRows.value.length,\n changed: counts.value.changedOrNewRows,\n errors: counts.value.errorRows,\n}))\n\n// Formül çubuğu (07 §2): ad kutusu, fx, değer (buraya yazmak hücreyi düzenler), ipucu.\nconst activeRow = computed(() => {\n const a = table.active.value\n return a ? (store.rowByKey(a.rowId) ?? null) : null\n})\nconst activeDef = computed(() => {\n const a = table.active.value\n return a ? (defById.value.get(a.columnId) ?? null) : null\n})\nconst rangeDims = computed(() => {\n const b = table.bounds.value\n if (!b) return null\n const rows = b.maxRowIndex - b.minRowIndex + 1\n const cols = b.maxColumnIndex - b.minColumnIndex + 1\n return rows * cols > 1 ? { rows, cols } : null\n})\nconst rangeText = computed(() => (rangeDims.value ? i18n.t('sheet.cells', rangeDims.value) : null))\nconst nameKey = computed(() =>\n activeRow.value && keyDef.value ? inputText(keyDef.value, store.read(activeRow.value, keyDef.value)) : '',\n)\nconst formulaText = computed(() => {\n const e = edit.editing.value\n if (e) return e.text ?? inputText(e.def, e.value)\n return activeRow.value && activeDef.value\n ? inputText(activeDef.value, store.read(activeRow.value, activeDef.value))\n : ''\n})\nconst formulaEditable = computed(\n () =>\n !!activeRow.value &&\n !!activeDef.value &&\n activeDef.value.type !== 'boolean' &&\n canEdit(activeRow.value, activeDef.value),\n)\nconst onFormulaInput = (e: Event) => {\n const text = (e.target as HTMLInputElement).value\n const row = activeRow.value\n const def = activeDef.value\n if (!row || !def || !formulaEditable.value) return\n if (!edit.editing.value && !edit.start(row, def, { inCell: false })) return\n edit.setValue(parseInput(def, text, parseEnv()), text, false)\n}\nconst onFormulaKeydown = (e: KeyboardEvent) => {\n if (e.key === 'Enter') {\n e.preventDefault()\n if (edit.commit()) table.move('down')\n grid.value?.focusActive()\n } else if (e.key === 'Escape') {\n e.preventDefault()\n edit.cancel()\n grid.value?.focusActive()\n }\n}\nconst hint = computed(() => {\n const d = activeDef.value\n if (!d) return ''\n const parts = [i18n.t(typeLabelKey(d.type))]\n if (d.type === 'currency' && typeof d.currency === 'string') parts.push(d.currency)\n if (d.required) parts.push(i18n.t('sheet.required').toLocaleLowerCase(ctx.locale))\n if (d.hint) parts.push(d.hint)\n return parts.join(' · ')\n})\nconst valueAria = computed(() =>\n activeDef.value ? i18n.t('sheet.valueAria', { column: activeDef.value.header, key: nameKey.value }) : '',\n)\n\n// Status bar seçim özeti (07 §2): Count = boş olmayan; Sum / Average yalnızca sayısal hücre varsa; tek hücrede gizli.\nconst summary = computed(() => {\n void store.version.value\n const b = table.bounds.value\n if (!b || !rangeDims.value) return null\n let count = 0\n let sum = 0\n let numeric = 0\n for (let r = b.minRowIndex; r <= b.maxRowIndex; r++) {\n const row = rowsAll.value[r]\n if (!row) continue\n for (let c = b.minColumnIndex; c <= b.maxColumnIndex; c++) {\n const def = visibleCols.value[c]!.def\n const v = store.readUntracked(row, def)\n if (isEmptyValue(v)) continue\n count++\n if (TYPE_SPECS[def.type].numeric && typeof v === 'number') {\n sum += v\n numeric++\n }\n }\n }\n return { count, sum: numeric ? fmt.decimal(sum, 2) : null, avg: numeric ? fmt.decimal(sum / numeric, 2) : null }\n})\n\nconst status = computed<SheetStatus>(() => ({\n phase: loadingNow.value\n ? 'loading'\n : savingNow.value\n ? 'saving'\n : partly.value\n ? 'partly-saved'\n : savedSummary.value\n ? 'saved'\n : 'ready',\n ...counts.value,\n}))\nconst changesText = computed(() =>\n counts.value.changedCells\n ? i18n.t('sheet.changes', { cells: fmt.int(counts.value.changedCells), rows: fmt.int(counts.value.changedRows) })\n : i18n.t('sheet.noChanges'),\n)\nconst saveTip = `${i18n.t('sheet.save')} · ${SAVE_KBD}`\nconst undoTip = `${i18n.t('common.undo')} (${UNDO_KBD})`\nconst redoTip = `${i18n.t('common.redo')} (${REDO_KBD})`\nconst canSave = computed(() => !readOnlyNow.value && (counts.value.changedCells > 0 || counts.value.newRows > 0))\n\n// Toast (06 §8): yapıştırma sonucu, sınır uyarısı, listeden çıkarma, gizli hata; Review / Show it / Undo.\ninterface Toast {\n text: string\n issues?: string\n review?: () => void\n action?: { label: string; run: () => void }\n undo?: boolean\n}\nconst toast = shallowRef<Toast | null>(null)\nlet toastTimer: ReturnType<typeof setTimeout> | undefined\nconst showToast = (t: Toast) => {\n toast.value = t\n clearTimeout(toastTimer)\n toastTimer = setTimeout(() => (toast.value = null), 6000)\n}\nconst toastUndo = () => {\n toast.value = null\n undo()\n}\nconst toastAction = () => {\n const run = toast.value?.action?.run\n toast.value = null\n run?.()\n}\nconst polite = ref('')\nconst assertive = ref('')\n// Yükleme / kayıt ilerlemesi her %25'te duyurulur (08 §5).\nlet announcedQuarter = -1\nwatch(percent, (p) => {\n if (p === null) {\n announcedQuarter = -1\n return\n }\n const q = Math.floor(p / 25)\n if (q === announcedQuarter || p === 0) return\n announcedQuarter = q\n polite.value = i18n.t(loadingNow.value ? 'sr.loadingPercent' : 'sr.savingPercent', { percent: q * 25 })\n})\n\nconst discardOpen = ref(false)\nconst discard = () => {\n edit.cancel()\n store.reset()\n order.value = null\n sortRules.value = []\n partly.value = null\n savedSummary.value = null\n looked.clear()\n pending.clear()\n grid.value?.focusActive()\n}\n\nconst displayProps = computed(() => ({\n density: density.value,\n verticalLines: pref.prefs.verticalLines,\n columns: layout.panel.value,\n counts: layout.counts.value,\n persistent: pref.persistent,\n}))\nconst displayOn = {\n 'update:density': (d: Density) => pref.set({ density: d }),\n 'update:verticalLines': (on: boolean) => pref.set({ verticalLines: on }),\n 'column-visible': (id: string, visible: boolean) => layout.setVisible(id, visible),\n 'column-move': (id: string, delta: -1 | 1) => layout.move(id, delta),\n 'columns-all': (visible: boolean) => {\n for (const c of layout.panel.value) if (!c.pinned && c.canHide) layout.setVisible(c.id, visible)\n },\n 'columns-reset': () => layout.reset(),\n reset: () => pref.reset(),\n}\n\nconst rootEl = ref<HTMLElement | null>(null)\nconst tooltip = useDelegatedTooltip(rootEl)\n\ndefineExpose({\n status,\n isDirty,\n getChanges: store.getChanges,\n applyResult,\n reset: discard,\n undo,\n redo,\n goToNextError: () => goToError(1),\n})\n</script>\n\n<template>\n <div\n ref=\"rootEl\"\n class=\"dt dt-sheet\"\n :class=\"{ 'is-phone': readOnlyDevice }\"\n :data-density=\"density\"\n @keydown=\"onRootKeydown\"\n >\n <div v-if=\"readOnlyDevice\" class=\"dt-sheet-readonly\" role=\"note\">\n <PhMonitor :size=\"20\" aria-hidden=\"true\" />\n <div class=\"dt-sheet-readonly-text\">\n <strong>{{ i18n.t('sheet.readOnly.title') }}</strong>\n <span>{{ i18n.t('sheet.readOnly.body', { entity }) }}</span>\n <button type=\"button\" class=\"dt-btn has-icon\" @click=\"copyLink\">\n <PhLink :size=\"16\" aria-hidden=\"true\" />\n {{ i18n.t('common.copyLink') }}\n </button>\n </div>\n </div>\n <div class=\"dt-toolbar dt-sheet-toolbar\" role=\"toolbar\">\n <div v-if=\"loadingNow || savingNow\" class=\"dt-progress-strip\">\n <strong>\n {{\n loadingNow\n ? i18n.t('sheet.loading', { entity })\n : progress\n ? i18n.t('sheet.saving', { sent: fmt.int(progress.done), total: fmt.int(progress.total) })\n : i18n.t('sheet.savingIndeterminate')\n }}\n </strong>\n <span v-if=\"loadingNow && progress\" class=\"dt-progress-count\">\n {{ i18n.t('sheet.loadingCount', { loaded: fmt.int(progress.done), total: fmt.int(progress.total) }) }}\n </span>\n <div\n class=\"dt-progress\"\n :class=\"{ 'is-indeterminate': percent === null }\"\n role=\"progressbar\"\n aria-valuemin=\"0\"\n aria-valuemax=\"100\"\n :aria-valuenow=\"percent ?? undefined\"\n >\n <div class=\"dt-progress-fill\" :style=\"percent !== null ? { width: `${percent}%` } : undefined\" />\n </div>\n </div>\n <div v-else-if=\"readOnlyDevice\" class=\"dt-find\" @keydown=\"onFindKeydown\">\n <SearchBox\n ref=\"findBox\"\n :model-value=\"findText\"\n :placeholder=\"i18n.t('sheet.find')\"\n :kbd=\"FIND_KBD\"\n @update:model-value=\"(v) => (findText = v)\"\n />\n <span v-if=\"findCount\" class=\"dt-find-count\" role=\"status\">{{ findCount }}</span>\n </div>\n <template v-else>\n <div class=\"dt-find\" @keydown=\"onFindKeydown\">\n <SearchBox\n ref=\"findBox\"\n :model-value=\"findText\"\n :placeholder=\"i18n.t('sheet.find')\"\n :kbd=\"FIND_KBD\"\n @update:model-value=\"(v) => (findText = v)\"\n />\n <span v-if=\"findCount\" class=\"dt-find-count\" role=\"status\">{{ findCount }}</span>\n </div>\n <span class=\"dt-toolbar-sep\" aria-hidden=\"true\" />\n <ToggleGroupRoot\n class=\"dt-seg dt-sheet-views\"\n type=\"single\"\n :model-value=\"view\"\n :aria-label=\"i18n.t('sheet.showRows')\"\n @update:model-value=\"(v) => v && setView(v as SheetFilterMode)\"\n >\n <ToggleGroupItem class=\"dt-seg-item\" value=\"all\">\n {{ i18n.t('sheet.all') }}\n <span class=\"dt-seg-count\">{{ fmt.int(viewCounts.all) }}</span>\n </ToggleGroupItem>\n <ToggleGroupItem class=\"dt-seg-item\" value=\"changed\">\n {{ i18n.t('sheet.changed') }}\n <span class=\"dt-seg-count\">{{ fmt.int(viewCounts.changed) }}</span>\n </ToggleGroupItem>\n <ToggleGroupItem class=\"dt-seg-item\" :class=\"{ 'is-errors': viewCounts.errors > 0 }\" value=\"errors\">\n {{ i18n.t('sheet.errors') }}\n <span class=\"dt-seg-count\">{{ fmt.int(viewCounts.errors) }}</span>\n </ToggleGroupItem>\n </ToggleGroupRoot>\n <button\n type=\"button\"\n class=\"dt-btn dt-sheet-undo\"\n :aria-disabled=\"store.canUndo.value ? undefined : 'true'\"\n :aria-label=\"undoTip\"\n :data-dt-tip=\"undoTip\"\n @click=\"store.canUndo.value && undo()\"\n >\n <PhArrowUUpLeft :size=\"16\" aria-hidden=\"true\" />\n </button>\n <button\n type=\"button\"\n class=\"dt-btn dt-sheet-undo\"\n :aria-disabled=\"store.canRedo.value ? undefined : 'true'\"\n :aria-label=\"redoTip\"\n :data-dt-tip=\"redoTip\"\n @click=\"store.canRedo.value && redo()\"\n >\n <PhArrowUUpRight :size=\"16\" aria-hidden=\"true\" />\n </button>\n <span class=\"dt-toolbar-sep\" aria-hidden=\"true\" />\n <button type=\"button\" class=\"dt-btn dt-btn-ghost has-icon dt-sheet-add\" @click=\"addRow()\">\n <PhPlus :size=\"16\" aria-hidden=\"true\" />\n {{ i18n.t('sheet.addRow') }}\n </button>\n <button\n v-if=\"parseFile\"\n type=\"button\"\n class=\"dt-btn dt-btn-ghost has-icon dt-sheet-import\"\n @click=\"importOpen = true\"\n >\n <PhDownloadSimple :size=\"16\" aria-hidden=\"true\" />\n {{ i18n.t('sheet.import') }}\n </button>\n <DropdownMenuRoot>\n <DropdownMenuTrigger as-child>\n <button type=\"button\" class=\"dt-btn dt-btn-ghost has-icon dt-sheet-export\">\n <PhExport :size=\"16\" aria-hidden=\"true\" />\n {{ i18n.t('sheet.export') }}\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuPortal>\n <DropdownMenuContent class=\"dt-menu\" align=\"start\" :side-offset=\"4\">\n <DropdownMenuSub v-for=\"scope in ['all', 'visible'] as const\" :key=\"scope\">\n <DropdownMenuSubTrigger class=\"dt-menu-item\">{{ exportLabel(scope) }}</DropdownMenuSubTrigger>\n <DropdownMenuPortal>\n <DropdownMenuSubContent class=\"dt-menu\" :side-offset=\"4\">\n <DropdownMenuItem class=\"dt-menu-item\" @select=\"exportRows('xlsx', scope)\">\n {{ i18n.t('toolbar.xlsx') }}\n </DropdownMenuItem>\n <DropdownMenuItem class=\"dt-menu-item\" @select=\"exportRows('csv', scope)\">\n {{ i18n.t('toolbar.csv') }}\n </DropdownMenuItem>\n </DropdownMenuSubContent>\n </DropdownMenuPortal>\n </DropdownMenuSub>\n </DropdownMenuContent>\n </DropdownMenuPortal>\n </DropdownMenuRoot>\n <DisplayPopover v-bind=\"displayProps\" v-on=\"displayOn\" />\n </template>\n <span class=\"dt-toolbar-spacer\" />\n <template v-if=\"readOnlyDevice\" />\n <span v-else-if=\"!savingNow\" class=\"dt-sheet-changes\" :class=\"{ 'is-empty': !counts.changedCells }\">\n <span v-if=\"counts.changedCells\" class=\"dt-sheet-dot\" aria-hidden=\"true\" />\n {{ changesText }}\n <template v-if=\"counts.newRows\">· {{ i18n.t('sheet.newShort', { count: counts.newRows }) }}</template>\n </span>\n <button\n v-if=\"!readOnlyDevice\"\n type=\"button\"\n class=\"dt-btn dt-btn-ghost\"\n :disabled=\"savingNow || (!counts.changedCells && !counts.newRows)\"\n @click=\"discardOpen = true\"\n >\n {{ i18n.t('sheet.discard') }}\n </button>\n <button\n v-if=\"!readOnlyDevice\"\n type=\"button\"\n class=\"dt-btn dt-btn-primary has-icon dt-sheet-save\"\n :disabled=\"!savingNow && !canSave\"\n :aria-disabled=\"savingNow ? 'true' : undefined\"\n :data-dt-tip=\"savingNow ? undefined : saveTip\"\n @click=\"!savingNow && save()\"\n >\n <PhCircleNotch v-if=\"savingNow\" :size=\"16\" class=\"dt-spin\" aria-hidden=\"true\" />\n <PhCheck v-else :size=\"16\" aria-hidden=\"true\" />\n {{ savingNow ? i18n.t('sheet.savingButton') : i18n.t('sheet.save') }}\n </button>\n </div>\n\n <div v-if=\"partly\" class=\"dt-sheet-partly\" role=\"alert\">\n <PhWarningCircle :size=\"16\" aria-hidden=\"true\" />\n <span>\n <strong>{{ i18n.t('sheet.partly.title', { count: fmt.int(partly.failed) }) }}</strong>\n {{ i18n.t('sheet.partly.body', { count: fmt.int(partly.saved) }) }}\n </span>\n <span class=\"dt-partly-spacer\" />\n <span class=\"dt-partly-nav\">\n <button type=\"button\" class=\"dt-partly-btn\" :aria-label=\"i18n.t('sheet.prevError')\" @click=\"goToError(-1)\">\n <PhCaretUp :size=\"14\" aria-hidden=\"true\" />\n </button>\n <span>{{ i18n.t('sheet.findCount', { index: partlyIndex, total: errorKeysInOrder.length }) }}</span>\n <button type=\"button\" class=\"dt-partly-btn\" :aria-label=\"i18n.t('sheet.nextError')\" @click=\"goToError(1)\">\n <PhCaretDown :size=\"14\" aria-hidden=\"true\" />\n </button>\n </span>\n <span class=\"dt-partly-sep\" aria-hidden=\"true\" />\n <button type=\"button\" class=\"dt-partly-copy\" @click=\"copyErrors\">\n <PhCopy :size=\"14\" aria-hidden=\"true\" />\n {{ i18n.t('sheet.copyErrors') }}\n </button>\n </div>\n <div v-if=\"overLimit\" class=\"dt-strip dt-sheet-strip\" role=\"status\">\n <PhWarning :size=\"16\" aria-hidden=\"true\" />\n <span>{{ i18n.t('sheet.firstN', { max: fmt.int(maxRows), entity }) }}</span>\n </div>\n\n <div v-if=\"!readOnlyDevice\" class=\"dt-formula\">\n <div class=\"dt-formula-name\">\n <template v-if=\"rangeText\">{{ rangeText }}</template>\n <template v-else-if=\"activeDef\">\n <span class=\"dt-mono\">{{ nameKey }}</span>\n <span class=\"dt-formula-col\">· {{ activeDef.header }}</span>\n </template>\n </div>\n <span class=\"dt-formula-fx\" aria-hidden=\"true\">fx</span>\n <input\n class=\"dt-formula-value\"\n type=\"text\"\n :value=\"formulaText\"\n :readonly=\"!formulaEditable\"\n :aria-label=\"valueAria\"\n autocomplete=\"off\"\n @input=\"onFormulaInput\"\n @keydown=\"onFormulaKeydown\"\n />\n <span v-if=\"savingNow\" class=\"dt-formula-hint\">\n <PhLock :size=\"12\" aria-hidden=\"true\" />\n {{ i18n.t('sheet.savingReadOnly') }}\n </span>\n <span v-else-if=\"hint\" class=\"dt-formula-hint\">{{ hint }}</span>\n </div>\n\n <SheetGrid\n ref=\"grid\"\n :sheet=\"sheet\"\n :layout=\"layout\"\n :rows=\"rowsAll\"\n :density=\"density\"\n :label=\"entity.other\"\n :entity=\"entity\"\n :loading=\"loadingNow\"\n :skeleton=\"loadingNow\"\n :read-only=\"savingNow\"\n :vertical-lines=\"pref.prefs.verticalLines\"\n :key-column=\"keyColumn\"\n :found=\"matches?.map ?? null\"\n :sort=\"sortMap\"\n :phone=\"readOnlyDevice\"\n >\n <template v-if=\"!loadingNow && rowsAll.length === 0\" #state>\n <slot name=\"empty\">\n <StateMessage kind=\"empty\" :title=\"i18n.t('state.emptyTitle', { entity })\" />\n </slot>\n </template>\n </SheetGrid>\n\n <div v-if=\"readOnlyDevice\" class=\"dt-sheet-footer\" role=\"status\">\n <span>{{ i18n.t('sheet.readOnly.total', { count: fmt.int(store.allRows.value.length), entity }) }}</span>\n <span aria-hidden=\"true\">·</span>\n <span class=\"dt-sheet-footer-badge\">\n <PhLock :size=\"14\" aria-hidden=\"true\" />\n {{ i18n.t('sheet.readOnly.badge') }}\n </span>\n </div>\n <div v-else class=\"dt-status\" role=\"status\" :aria-label=\"i18n.t('sheet.statusAria')\">\n <span class=\"dt-status-rows\">\n {{\n loadingNow ? i18n.t('common.loading') : i18n.t('sheet.rows', { count: fmt.int(store.allRows.value.length) })\n }}\n </span>\n <template v-if=\"!loadingNow\">\n <span v-if=\"savedSummary\" class=\"dt-status-saved\">\n <PhCheck :size=\"14\" aria-hidden=\"true\" />\n <strong>{{ i18n.t('sheet.saved', { count: fmt.int(savedSummary.count) }) }}</strong>\n <span>\n ·\n {{\n i18n.t('sheet.savedDetail', {\n created: fmt.int(savedSummary.created),\n updated: fmt.int(savedSummary.updated),\n })\n }}\n </span>\n </span>\n <span v-else-if=\"counts.changedCells\" class=\"dt-status-changes\">\n <span class=\"dt-mark is-changed\" aria-hidden=\"true\" />\n {{ changesText }}\n </span>\n <span v-else class=\"dt-status-muted\">{{ changesText }}</span>\n <span v-if=\"counts.newRows\" class=\"dt-status-new\">\n {{ i18n.t('sheet.newRows', { count: counts.newRows }) }}\n </span>\n <button v-if=\"counts.errorRows\" type=\"button\" class=\"dt-status-errors\" @click=\"goToError(1)\">\n <span class=\"dt-mark is-error\" aria-hidden=\"true\" />\n {{ i18n.t('sheet.errorsGoTo', { count: counts.errorRows }) }}\n </button>\n <span v-if=\"summary\" class=\"dt-status-summary\" :aria-label=\"i18n.t('sheet.selectionSummary')\">\n <span>\n {{ i18n.t('sheet.agg.count') }}\n <b>{{ fmt.int(summary.count) }}</b>\n </span>\n <span v-if=\"summary.sum !== null\">\n {{ i18n.t('sheet.agg.sum') }}\n <b>{{ summary.sum }}</b>\n </span>\n <span v-if=\"summary.avg !== null\">\n {{ i18n.t('sheet.agg.avg') }}\n <b>{{ summary.avg }}</b>\n </span>\n </span>\n </template>\n </div>\n\n <div v-if=\"toast\" class=\"dt-toast dt-sheet-toast\" role=\"status\">\n <strong>{{ toast.text }}</strong>\n <template v-if=\"toast.issues\">\n <span aria-hidden=\"true\">·</span>\n <span class=\"dt-toast-warn\">{{ toast.issues }}</span>\n <button v-if=\"toast.review\" type=\"button\" class=\"dt-toast-link\" @click=\"toast.review()\">\n {{ i18n.t('sheet.review') }}\n </button>\n </template>\n <button v-if=\"toast.action\" type=\"button\" class=\"dt-toast-link\" @click=\"toastAction\">\n {{ toast.action.label }}\n </button>\n <template v-if=\"toast.undo\">\n <span class=\"dt-toast-sep\" aria-hidden=\"true\" />\n <button type=\"button\" class=\"dt-toast-undo\" @click=\"toastUndo\">\n {{ i18n.t('common.undo') }}\n <kbd class=\"dt-kbd\">{{ UNDO_KBD }}</kbd>\n </button>\n </template>\n </div>\n <span class=\"dt-sr-only\" aria-live=\"polite\">{{ polite }}</span>\n <span class=\"dt-sr-only\" aria-live=\"assertive\">{{ assertive }}</span>\n <div\n v-show=\"tooltip.open.value\"\n class=\"dt-tip\"\n :class=\"{ 'is-multi': tooltip.text.value.includes('\\n') }\"\n role=\"tooltip\"\n :style=\"tooltip.style.value\"\n >\n {{ tooltip.text.value }}\n </div>\n <ConfirmDialog\n v-model:open=\"discardOpen\"\n :title=\"i18n.t('sheet.discard.title', { cells: fmt.int(counts.changedCells), rows: fmt.int(counts.changedRows) })\"\n :body=\"i18n.t('sheet.discard.body')\"\n :confirm-label=\"i18n.t('sheet.leave.discard')\"\n :cancel-label=\"i18n.t('sheet.discard.keep')\"\n danger\n @confirm=\"discard\"\n />\n <ImportDialog\n v-if=\"parseFile && importOpen\"\n v-model:open=\"importOpen\"\n :parse-file=\"parseFile\"\n :columns=\"sheetColumns\"\n :key-column=\"keyColumn\"\n :entity=\"entity\"\n :max-rows=\"maxRows\"\n :row-count=\"store.allRows.value.length\"\n :in-list=\"inList\"\n :lookup-keys=\"lookupKeys\"\n :parse-env=\"parseEnv\"\n :fmt-env=\"fmtEnv\"\n @apply=\"applyImport\"\n />\n <SaveErrorsDialog\n v-if=\"errorDialogOpen\"\n v-model:open=\"errorDialogOpen\"\n :errors=\"errorItems\"\n :ok-rows=\"store.getChanges().rows.length\"\n @fix=\"fixFirst\"\n @save=\"emitSave\"\n />\n </div>\n</template>\n"],"mappings":";;;;;;;;;AAIA,IAAMkQ,MAAW,MAAuB,YAAY,KAAKC,CAAC,IAAI,IAAIA,EAAE,QAAQ,MAAM,MAAI,EAAE,KAAKA,GAChFC,MAAS,MAA+BC,EAAO,KAAK,MAAMC,EAAE,IAAIJ,EAAO,CAAC,CAAC,KAAK,GAAI,CAAC,CAAC,CAAC,KAAK,IAAI,GAErGK,MAAc,MAClBJ,EAAE,QAAQ,MAAM,OAAO,CAAC,CAAC,QAAQ,MAAM,MAAM,CAAC,CAAC,QAAQ,MAAM,MAAM,CAAC,CAAC,QAAQ,OAAO,MAAM,GAC/EK,MAAU,MACrB,iBAAiBH,EAAO,KAAK,MAAM,OAAOC,EAAE,KAAK,MAAM,OAAOC,GAAWE,CAAC,EAAE,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;AAGhH,SAAgBC,GAAS,GAA0B;CACjD,IAAMC,IAAmB,CAAC,GACtBC,IAAgB,CAAC,GACjBC,IAAO,IACPC,IAAS;CACb,KAAK,IAAIC,IAAI,GAAGA,IAAIC,EAAK,QAAQ,KAAK;EACpC,IAAMC,IAAKD,EAAKD;EAChB,AAAID,IACEG,MAAO,OACLD,EAAKD,IAAI,OAAO,QAClB,KAAQ,MACR,OACK,IAAS,KACX,KAAQE,IAGbA,MAAO,QAAOJ,MAAS,KAAI,IAAS,KAC/BI,MAAO,OACdL,EAAI,KAAKC,CAAI,GACb,IAAO,MACEI,MAAO,QAAQA,MAAO,QAC3BA,MAAO,QAAQD,EAAKD,IAAI,OAAO,QAAM,KACzCH,EAAI,KAAKC,CAAI,GACbF,EAAK,KAAKC,CAAG,GACb,IAAM,CAAC,GACP,IAAO,MACF,KAAQK;CACjB;CAMA,QALIJ,MAAS,MAAMD,EAAI,YACrBA,EAAI,KAAKC,CAAI,GACbF,EAAK,KAAKC,CAAG,IAEXD,EAAK,SAAS,KAAKA,EAAKA,EAAK,SAAS,EAAE,CAAE,OAAO,MAAMF,MAAM,EAAE,KAAGE,EAAK,IAAI,GACxEA;AACT;AAGA,SAAgBO,GAAe,GAA0B;CAGvD,OAFI,OAAO,YAAc,MAAoB,CAAC,IAEvC,CAAC,GADI,IAAI,UAAU,CAAC,CAAC,gBAAgBC,GAAM,WACvC,CAAA,CAAI,iBAAiB,IAAI,CAAC,CAAC,CAAC,KAAK,MAC1C,CAAC,GAAGC,EAAG,iBAAiB,QAAQ,CAAC,CAAC,CAAC,KAAK,OAAQC,EAAG,eAAe,GAAA,CAAI,QAAQ,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,CACtG;AACF;AAGA,SAAgBC,GAAoB,GAAuC;CACzE,IAAMN,IAAOO,GAAM,QAAQ,YAAY,KAAK;CAC5C,IAAIP,GAAM,OAAON,GAASM,CAAI;CAC9B,IAAMG,IAAOI,GAAM,QAAQ,WAAW,KAAK;CAC3C,OAAOJ,IAAOD,GAAeC,CAAI,IAAI,CAAC;AACxC;;;AC5CA,IAAMK,MAAe,GAAsB,GAAc,MAA4B;CACnF,IAAMC,IAAIC,EAAQ,MAAM,MAAQ1R,GAAK4R,EAAI,OAAOC,CAAM,MAAM7R,GAAKgR,GAAMa,CAAM,KAAK,OAAOD,EAAI,KAAK,MAAMZ,EAAK,KAAK,CAAC;CACnH,OAAOS,IAAIA,EAAE,QAAQT,EAAK,KAAK;AACjC,GAEMc,MAAa,MACjB3B,EACG,MAAM,MAAM,CAAC,CACb,KAAK,MAAM4B,EAAE,KAAK,CAAC,CAAC,CACpB,OAAO,OAAO;AAGnB,SAAgBC,GAAa,GAAmC;CAC9D,KAAK,IAAMC,KAAOC,GAAO;EACvB,IAAM/B,IAAI8B,EAAI,QAAQ,0BAA0B,EAAE,GAC5CE,IAAQhC,EAAE,YAAY,GAAG,GACzBiC,IAAMjC,EAAE,YAAY,GAAG;EAC7B,IAAIgC,KAAS,KAAKC,KAAO,GAAG,OAAOD,IAAQC,IAAM,MAAM;EACvD,IAAID,KAAS,KAAK,YAAY,KAAKhC,CAAC,KAAK,CAAC,qBAAqB,KAAKA,CAAC,GAAG,OAAO;EAC/E,IAAIiC,KAAO,KAAK,aAAa,KAAKjC,CAAC,KAAK,CAAC,sBAAsB,KAAKA,CAAC,GAAG,OAAO;CACjF;CACA,OAAO;AACT;AAEA,IAAMnQ,MAAQ,GAAW,MAA2BmQ,EAAE,KAAK,CAAC,CAAC,kBAAkB0B,CAAM,CAAC,CAAC,QAAQ,SAAS,GAAG,GAErGQ,MAAY,GAAW,GAAW,MAA6B;CACnE,IAAMC,IAAK,IAAI,KAAKC,GAAGC,IAAI,GAAGC,CAAC;CAC/B,OAAOH,EAAG,YAAY,MAAMC,KAAKD,EAAG,SAAS,MAAME,IAAI,KAAKF,EAAG,QAAQ,MAAMG,IAAIpD,EAAOiD,CAAE,IAAI;AAChG;AAGA,SAAgBI,GAAe,GAAc,GAA8B;CACzE,IAAMvC,IAAIa,EAAK,KAAK;CACpB,IAAI,CAACb,GAAG,OAAO;CACf,IAAMwC,IAAM3S,GAAKmQ,GAAGyC,EAAI,MAAM;CAC9B,IAAID,MAAQ,WAAWA,MAAQ3S,GAAK4S,EAAI,WAAWA,EAAI,MAAM,GAAG,OAAOvD,EAAOuD,EAAI,KAAK;CACvF,IAAMC,IAAM,kBAAkB,KAAK1C,CAAC;CACpC,IAAI0C,GAAK;EACP,IAAMJ,IAAI,IAAI,KAAKG,EAAI,KAAK;EAE5B,OADAH,EAAE,QAAQA,EAAE,QAAQ,KAAKI,EAAI,OAAO,MAAM,KAAK,KAAK,OAAOA,EAAI,EAAE,CAAC,GAC3DxD,EAAOoD,CAAC;CACjB;CACA,IAAMK,IAAM,2BAA2B,KAAK3C,CAAC;CAC7C,IAAI2C,GAAK,OAAOT,GAAS,CAACS,EAAI,IAAK,CAACA,EAAI,IAAK,CAACA,EAAI,EAAG;CACrD,IAAMC,IAAM,iDAAiD,KAAK5C,CAAC;CAKnE,OAJI4C,IAEKV,GADGU,EAAI,KAAMA,EAAI,EAAE,CAAC,WAAW,IAAI,MAAO,CAACA,EAAI,KAAK,CAACA,EAAI,KAAMH,EAAI,MAAM,YAAY,GACzE,CAACG,EAAI,IAAK,CAACA,EAAI,EAAG,IAEhC;AACT;AAGA,SAAgBC,GAAW,GAAgB,GAAc,GAAwB;CAC/E,IAAM7C,IAAIa,EAAK,KAAK;CACpB,IAAIb,MAAM,IAAI,OAAO;CACrB,IAAInC,EAAWiF,EAAI,KAAK,CAAC,WAAWA,EAAI,SAAS,QAG/C,OADI9C,EAAE,WAAW,GAAG,IAAUA,IACvB9B,EAAYuE,EAAI,QAAQzC,CAAC,KAAKA;CAEvC,QAAQ8C,EAAI,MAAZ;EACE,KAAK;EACL,KAAK,YACH,OAAOP,GAAevC,GAAGyC,CAAG,KAAKzC;EACnC,KAAK,UACH,OAAOqB,GAAYyB,EAAI,SAAS9C,GAAGyC,EAAI,MAAM;EAC/C,KAAK,eACH,OAAOd,GAAU3B,CAAC,CAAC,CAAC,KAAK,MAASqB,GAAYyB,EAAI,SAASC,GAAMN,EAAI,MAAM,CAAC;EAC9E,KAAK,WAAW;GACd,IAAMO,IAAInT,GAAKmQ,GAAGyC,EAAI,MAAM;GAG5B,OAFI;IAAC;IAAQ;IAAK;IAAO5S,GAAK4S,EAAI,SAASA,EAAI,MAAM;GAAC,CAAC,CAAC,SAASO,CAAC,IAAU,KAC5E,CAAI;IAAC;IAAS;IAAK;IAAMnT,GAAK4S,EAAI,QAAQA,EAAI,MAAM;GAAC,CAAC,CAAC,SAASO,CAAC,KAC1DhD;EACT;EACA,KAAK,aACH,OAAOA,EAAE,kBAAkByC,EAAI,MAAM;EACvC,KAAK,aACH,OAAOzC,EAAE,kBAAkByC,EAAI,MAAM;EACvC,SACE,OAAOzC;CACX;AACF;AAGA,SAAgBiD,GAAU,GAAgB,GAAwB;CAKhE,OAJIC,KAAU,OAAoC,KAC9CJ,EAAI,SAAS,WAAiB7E,EAAY6E,EAAI,SAASI,CAAK,IAC5D,MAAM,QAAQA,CAAK,IAAUA,EAAM,KAAK,IAAI,IAC5C,OAAOA,KAAU,WAAiB,KAAK,UAAUA,CAAK,IACnD,OAAOA,CAAK;AACrB;;;AC5GA,SAAgBC,KAA8B;CAC5C,IAAM,EAAE,SAAM,cAAWrD,GAAoB;CAC7C,cAAc;EACZ;EACA,uBAAO,IAAI,KAAK;EAChB,WAAWsD,EAAK,EAAE,YAAY;EAC9B,SAASA,EAAK,EAAE,YAAY;EAC5B,QAAQA,EAAK,EAAE,WAAW;CAC5B;AACF;AAGA,SAAgBC,GAAS,GAAmD;CAC1E,IAAI,CAACC,GAAI;CACT,EAAG,MAAM,EAAE,eAAe,GAAK,CAAC;CAChC,IAAMC,IAAID,EAAG,MAAM;CACnB,EAAG,kBAAkBC,GAAGA,CAAC;AAC3B;;;;;;;;;;;;;;;;ECbA,IAAMO,IAAQC,GACRC,IAAOH,GACPpB,IAAMU,GAAY,GAClBG,IAAKW,EAA6B,IAAI,GACtCpD,IAAOoD,EAAIhB,GAAUa,EAAM,QAAQA,EAAM,UAAU,CAAC,GACpDI,IAASC,QAAe;GAC5B,IAAM7D,IAAIwD,EAAM;GAChB,OAAOxD,EAAE,SAAS,cAAc,OAAOA,EAAE,YAAa,WAAWA,EAAE,WAAWA,EAAE,SAAS,eAAe,MAAM;EAChH,CAAC;EACD,SAAgB+C,GAASC,EAAG,KAAK,CAAC;EAClC,IAAMc,UAAgB;GAEpB,AADA,EAAK,QAAQd,EAAG,MAAO,OACvBU,EAAK,qBAAqBnB,GAAWiB,EAAM,QAAQjD,EAAK,OAAO4B,EAAI,CAAC,CAAC;EACvE;E,kBAIExS,EAAA,GAAAC,EAYO,QAZPJ,IAYO,CAXLK,EASE,SAAA;GARI,SAAA;GAAJ,KAAImT;GACJ,OAAM;GACN,MAAK;GACL,WAAU;GACT,OAAOzC,EAAA;GACP,cAAYkD,EAAA,OAAO;GACpB,cAAa;GACL;E,kBAEEG,EAAA,SAAZjU,EAAA,GAAAC,EAAyE,QAAzEF,IAAyEI,EAAhB8T,EAAA,KAAM,GAAA,CAAA,K;;;;;;;;;;;EEdnE,IAAMJ,IAAQC,GACRC,IAAOH,GACP,EAAE,YAAS/D,GAAoB,GAC/B2C,IAAMU,GAAY,GAClBL,IAAMqB,QAAeL,EAAM,MAAgD,GAE3EvC,IAAU4C,QAAe;GAC7B,IAAM7B,IAAIQ,EAAI;GACd,OAAOR,EAAE,gBAAgBA,EAAE,QAAQ,QAAQ,MAAMA,EAAE,cAAehB,GAAGwC,EAAM,GAAG,CAAC,IAAIxB,EAAE;EACvF,CAAC,GACKqC,IAAOV,EAAI,EAAI,GAEfW,IAASX,EAAwB;EACvC,GACEU,IACC,MAAM;GACL,AAAKrD,KACLuD,SAAoB;IAClB,EAAO,QAAQ,SAAS,cAA2B,iCAA+B,CAAC,EAAE,MAAM,KAAA;GAC7F,CAAC;EACH,GACA,EAAE,WAAW,GAAK,CACpB;EACA,IAAMhE,IAAOoD,EAAIhB,GAAUa,EAAM,QAAQA,EAAM,UAAU,CAAC,GACpDgB,IAAQb,EAAsC,IAAI,GAClDc,UAAgBD,EAAM,OAAO,OAAO;EAC1C,SAAgB,KAAKD,SAAexB,GAAS0B,EAAQ,CAAC,CAAC,CAAC;EAExD,IAAMC,KAAU,MAAc;GAE5B,AADA,EAAK,QAAQhC,GACbgB,EAAK,qBAAqBnB,GAAWiB,EAAM,QAAQd,GAAGP,EAAI,CAAC,CAAC;EAC9D,GACMwC,KAAY,MAAe;GAC/B,AAAIjC,KAAyB,SAC7BgB,EAAK,qBAAqBhB,CAAC,GAC3B,EAAK,QAAQ/E,EAAY6E,EAAI,MAAM,SAASE,CAAC,GAC7C,EAAK,QAAQ,IACb6B,SAAoBxB,GAAS0B,EAAQ,CAAC,CAAC;EACzC,GACMG,KAAa,MAAqB;GACtC,AAAI,EAAE,UAAU,EAAE,QAAQ,gBACxB,EAAE,eAAe,GACjB,EAAK,QAAQ;EAEjB,GAEMC,KAAQ,MAAwBzH,EAAMkE,EAAE,EAAE,MAAMA,EAAE,EAAE,KAAK;E,kBAI7DrR,EAAA,GAAAC,EA4CeC,EAAA6U,EAAA,GAAA;GA3CL,MAAMX,EAAA;GAAA,iBAAA,AAAAY,EAAA,QAAA,MAAA,EAAI,QAAAC;GAClB,OAAM;GACL,eAAczB,EAAA,cAA8C,KAAA;GAC5D,6BAA2B;GAC3B,uBAAoBkB;;GAGrB,SAAAvU,QAYiB,CAZjBC,EAYiBF,EAAAkV,EAAA,GAAA,EAZD,OAAM,iBAAgB,GAAA;IACpC,SAAAjV,QAUE,CAVFC,EAUEF,EAAAmV,EAAA,GAAA;KATI,SAAA;KAAJ,KAAId;KACJ,OAAM;KACN,cAAa;KACZ,cAAYf,EAAA,OAAO;KACnB,iBAAea,EAAA;KACf,eAAa/D,EAAA;KACb,uBAAqBA,EAAA;KACrB,uBAAoBmE;KACX;;;;;;;;G,IAGdrU,EAsBiBF,EAAAoV,EAAA,GAAA,MAAA;IArBf,SAAAnV,QAoBkB,CApBlBC,EAoBkBF,EAAAqV,EAAA,GAAA;KAnBhB,OAAM;KACN,UAAS;KACT,OAAM;KACL,eAAa;KACb,cAAY/B,EAAA,OAAO;;KAEpB,SAAArT,QAYmB,CAZnBC,EAYmBF,EAAAsV,EAAA,GAAA,MAAA;MAVf,SAAArV,QAAoB,EADtBH,EAAA,EAAA,GAAAK,EASeC,GAAA,MAAAC,GARDyQ,EAAA,QAAL,OADThR,EAAA,GAAAC,EASeC,EAAAyV,EAAA,GAAA;OAPZ,KAAK,OAAO5E,EAAE,KAAK;OACpB,OAAM;OACL,OAAOA,EAAE;OACT,cAAYA,EAAE;;OAEf,SAAA5Q,QAAe,CAAfC,EAAewU,GAAA,EAAL,KAAC,GAAA,MAAA,GAAA,CAAA,GAAA,CAAA,GACX,AAAAI,EAAA,OAAAxU,EAAmE,OAAA;QAA9D,OAAM;QAA8B,eAAY;OAAO,GAAA,KAAC,EAAA,C;;M,4CAE/DJ,EAAsFF,EAAA0V,EAAA,GAAA,EAAvE,OAAM,mBAAkB,GAAA;OAAC,SAAAzV,QAA8B,CAA3BM,EAAAC,EAAAR,EAAA2S,CAAA,CAAI,CAAC,EAAC,gBAAA,CAAA,GAAA,CAAA,C;;;;;;;;;;;;;;;;;;;;;EExG3D,IAAMU,IAAQC,GACRC,IAAOH,GACPpB,IAAMU,GAAY,GAClBG,IAAKW,EAAmD,IAAI,GAC5DpD,IAAOoD,EAAIhB,GAAUa,EAAM,QAAQA,EAAM,UAAU,CAAC;EAC1D,SAAgBT,GAASC,EAAG,KAAK,CAAC;EAClC,IAAMc,UAAgB;GAEpB,AADA,EAAK,QAAQd,EAAG,MAAO,OACvBU,EAAK,qBAAqBnB,GAAWiB,EAAM,QAAQjD,EAAK,OAAO4B,EAAI,CAAC,CAAC;EACvE;E,iBAKUsB,EAAA,OAAO,SAAI,UADnB1S,EAAA,GAAAC,EAQE,YAAA;;GANI,SAAA;GAAJ,KAAIgS;GACJ,OAAM;GACL,OAAOzC,EAAA;GACP,cAAYkD,EAAA,OAAO;GACpB,MAAK;GACG;E,qBAEV1S,EAAA,GAAAC,EASE,SAAA;;GAPI,SAAA;GAAJ,KAAIgS;GACJ,OAAM;GACN,MAAK;GACJ,OAAOzC,EAAA;GACP,cAAYkD,EAAA,OAAO;GACpB,cAAa;GACL;;;;;;;;;;;;;;;EEPZ,IAAMD,IAAQC,GACRC,IAAOH,GACP,EAAE,SAAM,cAAW/D,GAAoB,GACvC2C,IAAMU,GAAY,GAClB0D,IAAMpJ,EAAUiE,CAAM,GACtBoF,IAAS,IAAI,KAAK,eAAepF,GAAQ;GAAE,SAAS;GAAS,OAAO;GAAS,KAAK;EAAU,CAAC,GAC7F4B,IAAKW,EAA6B,IAAI,GACtCU,IAAOV,EAAI,EAAK,GAChBpD,IAAOoD,EAAIhB,GAAUa,EAAM,QAAQA,EAAM,UAAU,CAAC;EAC1D,SAAgBT,GAASC,EAAG,KAAK,CAAC;EAElC,IAAMyD,IAAKC,GAAiB,GACtBC,IAAMC,GAAMH,CAAE,GACdI,IAAeC,GAAaC,GAAYJ,GAAKvF,CAAM,GAAG,OAAO,GAC7D4F,KAAQ,MAAsC;GAClD,IAAI;IACF,OAAO,OAAOtH,KAAM,YAAYA,IAAIuH,GAAUvH,EAAE,MAAM,GAAG,EAAE,CAAC,IAAI,KAAA;GAClE,QAAQ;IACN;GACF;EACF,GACMwH,IAASrD,QAAemD,EAAKxD,EAAM,UAAU,CAAC,GAC9C2D,IAAWtD,QAAe;GAC9B,IAAMnB,IAAIc,EAAM;GAChB,IAAI,OAAOd,KAAM,YAAY,CAACwE,EAAO,OAAO,OAAO;GACnD,IAAMlF,IAAIxD,EAAOkE,EAAE,MAAM,GAAG,EAAE,CAAC;GAC/B,OAAO;IAAE,KAAK8D,EAAO,OAAOxE,CAAC;IAAG,UAAUuE,EAAI,SAASvE,CAAC;GAAE;EAC5D,CAAC,GAEK8B,UAAgB;GAEpB,AADA,EAAK,QAAQd,EAAG,MAAO,OACvBU,EAAK,qBAAqBnB,GAAWiB,EAAM,QAAQjD,EAAK,OAAO4B,EAAI,CAAC,CAAC;EACvE,GACMiF,KAAU,MAA6B;GAC3C,IAAI,CAACpF,GAAG;GACR,IAAMK,IAAML,EAAE,SAAS;GAGvB,AAFA,EAAK,QAAQK,GACbqB,EAAK,qBAAqBrB,CAAG,GAC7B,EAAK,QAAQ;EACf,GACMgF,KAAW,MAAa;GAE5B,AADA,EAAE,eAAe,GACjB9C,SAAoBxB,GAASC,EAAG,KAAK,CAAC;EACxC,GACM4B,MAAa,MAAqB;GACtC,AAAI,EAAE,UAAU,EAAE,QAAQ,gBACxB,EAAE,eAAe,GACjB,EAAK,QAAQ;EAEjB;E,kBAIEtT,EAAA,GAAAC,EA4DO,QA5DPL,IA4DO,CA3DLM,EASE,SAAA;GARI,SAAA;GAAJ,KAAIwR;GACJ,OAAM;GACN,MAAK;GACJ,OAAOzC,EAAA;GACP,cAAYkD,EAAA,OAAO;GACpB,cAAa;GACL;GACE;E,kBAEZhS,EAgDcC,EAAA4V,EAAA,GAAA;GAhDO,MAAMjD,EAAA;GAAA,iBAAA,AAAAY,EAAA,QAAA,MAAA,EAAI,QAAAC;;GAC7B,SAAAvT,QAIiB,CAJjBF,EAIiBC,EAAA6V,EAAA,GAAA,EAJD,YAAA,GAAQ,GAAA;IACtB,SAAA5V,QAES,CAFTH,EAES,UAAA;KAFD,MAAK;KAAS,OAAM;KAAqB,UAAS;KAAM,cAAYE,EAAAoR,CAAA,CAAI,CAAC,EAAC,WAAA;I,IAChFrR,EAAiDC,EAAA8V,EAAA,GAAA;KAA/B,MAAM;KAAI,eAAY;;;G,IAG5C/V,EAyCgBC,EAAA+V,EAAA,GAAA,MAAA;IAxCd,SAAA9V,QAuCiB,CAvCjBF,EAuCiBC,EAAAgW,EAAA,GAAA;KAtCf,OAAM;KACN,OAAM;KACL,eAAa;KACb,kBAAkBL;;KAEnB,SAAA1V,QAGM,CAHKwV,EAAA,SAAX7V,EAAA,GAAAC,EAGM,OAHNF,IAGM,CAFJG,EAAmC,UAAA,MAAAI,EAAxBuV,EAAA,MAAS,GAAG,GAAA,CAAA,GACvB3V,EAAoC,QAAA,MAAAI,EAA3BuV,EAAA,MAAS,QAAQ,GAAA,CAAA,C,iBAE5B1V,EA4BeC,EAAAiW,EAAA,GAAA;MA1Bb,OAAM;MACL,eAAaT,EAAA;MACb,QAAQxV,EAAA0P,CAAA;MACR,kBAAgB1P,EAAAmV,CAAA;MAChB,aAAaK,EAAA,SAAUxV,EAAAiV,CAAA;MACvB,uBAAkB,AAAA1B,EAAA,QAAG,MAAMmC,EAAOpF,CAAC;;MAEpC,SAAArQ,GAIiB,EAZP,aAAU,cAAI,CAQxBF,EAIiBC,EAAAkW,EAAA,GAAA,EAJD,OAAM,cAAa,GAAA;OACjC,SAAAjW,QAAiG;QAAjGF,EAAiGC,EAAAmW,EAAA,GAAA,EAAnF,OAAM,iBAAgB,GAAA;SAAC,SAAAlW,QAA6C,CAA7CF,EAA6CC,EAAAoW,CAAA,GAAA;UAA/B,MAAM;UAAI,eAAY;;;;QACzErW,EAAwCC,EAAAqW,EAAA,GAAA,EAAvB,OAAM,eAAc,CAAA;QACrCtW,EAAkGC,EAAAsW,EAAA,GAAA,EAApF,OAAM,iBAAgB,GAAA;SAAC,SAAArW,QAA8C,CAA9CF,EAA8CC,EAAAuW,CAAA,GAAA;UAA/B,MAAM;UAAI,eAAY;;;;;;M,KAE5E3W,EAAA,EAAA,GAAAC,EAaeO,GAAA,MAAAC,GAbemW,IAAT,OAArB5W,EAAA,GAAAU,EAaeN,EAAAyW,EAAA,GAAA;OAbsB,KAAKC,EAAM,MAAM,SAAQ;OAAI,OAAM;;OACtE,SAAAzW,QAImB,CAJnBF,EAImBC,EAAA2W,EAAA,GAAA,MAAA;QAHjB,SAAA1W,QAEkB,CAFlBF,EAEkBC,EAAA4W,EAAA,GAAA,MAAA;SADE,SAAA3W,QAAuB,EAAzCL,EAAA,EAAA,GAAAC,EAAoGO,GAAA,MAAAC,GAApEwW,IAAP,OAAzBjX,EAAA,GAAAU,EAAoGN,EAAA8W,EAAA,GAAA;UAAzD,KAAKC;UAAK,OAAM;;UAAa,SAAA9W,QAAS,CAANM,EAAAL,EAAA6W,CAAG,GAAA,CAAA,C;;;;;;O,UAGlFhX,EAMmBC,EAAAgX,EAAA,GAAA,MAAA;QALA,SAAA/W,QAA+B,EAAhDL,EAAA,EAAA,GAAAC,EAIkBO,GAAA,MAAAC,GAJmBqW,EAAM,OAAlB,GAAM,OAA/B9W,EAAA,GAAAU,EAIkBN,EAAA4W,EAAA,GAAA,EAJgC,KAAKhI,EAAC,GAAA;SACxC,SAAA3O,QAAiB,EAA/BL,EAAA,EAAA,GAAAC,EAEeO,GAAA,MAAAC,GAFW4W,IAAL,OAArBrX,EAAA,GAAAU,EAEeN,EAAAkX,EAAA,GAAA;UAFkB,KAAK5G,EAAE,SAAQ;UAAK,MAAMA;UAAG,OAAM;;UAClE,SAAArQ,QAAwE,CAAxEF,EAAwEC,EAAAmX,EAAA,GAAA;WAAlD,KAAK7G;WAAI,OAAOoG,EAAM;WAAO,OAAM;;;;;;;;;;;;;;;;;;;;;;;;A,IE/HhEU,KAAqD,OAAO,iBAAiB,GAE7EC,WAA2CC,EAAOF,IAAkB,EAAE,YAAY,KAAA,EAAU,CAAC,G;;;;;;;;;ECe1G,IAAMtF,IAAQC,GACRC,IAAOH,GACP,EAAE,cAAW/D,GAAoB,GACjC0J,KAAS,MAAcC,EAAE,kBAAkB/H,CAAM,GACjDgI,IAAQL,GAAe,GAEvBvG,IAAMqB,QAAeL,EAAM,MAAqD,GAChF6F,IAASxF,QAAyB,MAAM,QAAQL,EAAM,UAAU,IAAKA,EAAM,aAAyB,CAAC,CAAE,GAEvG8F,IAAczF,QAA4B;GAC9C,IAAM7B,IAAIQ,EAAI;GACd,OAAOR,EAAE,QAAQ,QAAQ,MAAMqH,EAAO,MAAM,SAASrI,EAAE,KAAK,KAAK,CAACgB,EAAE,iBAAiBA,EAAE,cAAchB,GAAGwC,EAAM,GAAG,CAAC;EACpH,CAAC,GAEK+F,IAAS5F,EAAIyF,EAAM,KAAK,KAAK,EAAE,GAE/BI,IAAQ3F,QAAe;GAC3B,IAAM4F,IAAIP,EAAMK,EAAO,MAAM,KAAK,CAAC;GACnC,OAAOE,IAAIH,EAAY,MAAM,QAAQ,MAAMJ,EAAMlI,EAAE,KAAK,CAAC,CAAC,SAASyI,CAAC,CAAC,IAAIH,EAAY;EACvF,CAAC,GACKI,IAAW/F,EAAI,EAAI,GACnBU,IAAOR,EAAS;GAAE,WAAW6F,EAAS,SAASF,EAAM,MAAM,SAAS;GAAG,MAAM,MAAO,EAAS,QAAQ9G;EAAG,CAAC,GAEzG4B,IAASX,EAAwB;EACvC,GACEU,IACC,MAAM;GACL,AAAIrD,KACFuD,SAAoB;IAClB,EAAO,QAAQ,SAAS,cAA2B,iCAA+B,CAAC,EAAE,MAAM,KAAA;GAC7F,CAAC;EACL,GACA,EAAE,WAAW,GAAK,CACpB;EAEA,IAAM6C,KAAU,MAAe;GAC7B,AAAK,MAAM,QAAQ1E,CAAC,MACpBgB,EAAK,qBAAqBhB,EAAE,SAASA,IAAI,IAAI,GAC7C,EAAO,QAAQ,IACf6B,GAAcoF,CAAM;EACtB,GACM/E,KAAa,MAAqB;GACtC,AAAI,EAAE,UAAU,EAAE,QAAQ,gBACxB,EAAE,eAAe,GACjB,EAAK,QAAQ;EAEjB,GACMJ,IAAQb,EAAsC,IAAI,GAClDgG,UAAe5G,GAASyB,EAAM,OAAO,OAAO,IAAI;EACtD,SAAgB,KAAKD,GAASoF,CAAM,CAAC;EAGrC,IAAM9E,KAAQ,MAAwBzH,EAAMkE,EAAE,EAAE,MAAMA,EAAE,EAAE,KAAK;E,kBAI7DnP,EAAA,GAAAC,EA+CeC,EAAA2S,EAAA,GAAA;GA9CL,MAAMX,EAAA;GAAA,iBAAA,AAAAY,EAAA,QAAA,MAAA,EAAI,QAAAC;GAClB,OAAM;GACN,UAAA;GACC,eAAamE,EAAA;GACb,6BAA2B;GAC3B,+BAA6B;GAC9B,iBAAA;GACC,uBAAoBjC;;GAErB,SAAA9U,QAWiB,CAXjBC,EAWiBF,EAAAgT,EAAA,GAAA,EAXD,OAAM,iBAAgB,GAAA;IACpC,SAAA/S,QASE,CATFC,EASEF,EAAAiT,EAAA,GAAA;KARI,SAAA;KAAJ,KAAId;KACK,YAAA+E,EAAA;KAAA,uBAAA,AAAAtE,EAAA,QAAA,MAAA,EAAM,QAAAC;KACf,OAAM;KACL,uBAAqBqE,EAAA;KACtB,cAAa;KACZ,cAAY9F,EAAA,OAAO;KACnB,iBAAea,EAAA;KACN;;;;;;;;G,IAGd/R,EAwBiBF,EAAAkT,EAAA,GAAA,MAAA;IAvBf,SAAAjT,QAsBkB,CAtBlBC,EAsBkBF,EAAAmT,EAAA,GAAA;KArBhB,OAAM;KACN,UAAS;KACT,OAAM;KACL,eAAa;KACb,cAAY/B,EAAA,OAAO;;KAEpB,SAAAnR,QAcmB,CAdnBC,EAcmBF,EAAAoT,EAAA,GAAA,MAAA;MAZf,SAAAnT,QAAkB,EADpBH,EAAA,EAAA,GAAAK,EAYeC,GAAA,MAAAC,GAXD8W,EAAA,QAAL,OADTrX,EAAA,GAAAC,EAYeC,EAAAuT,EAAA,GAAA;OAVZ,KAAK,OAAO5E,EAAE,KAAK;OACpB,OAAM;OACL,OAAOA,EAAE;OACT,cAAYA,EAAE;;OAEf,SAAA1O,QAAe;QAAfC,EAAesS,GAAA,EAAL,KAAC,GAAA,MAAA,GAAA,CAAA,GAAA,CAAA;QACXtS,EAEwBF,EAAAuX,EAAA,GAAA,EAFD,OAAM,uBAAsB,GAAA;SACjD,SAAAtX,QAAyC,CAAzCC,EAAyCF,EAAAwX,EAAA,GAAA;UAA/B,MAAM;UAAI,eAAY;;;;QAElC,AAAA5E,EAAA,OAAAtS,EAAmE,OAAA;SAA9D,OAAM;SAA8B,eAAY;QAAO,GAAA,KAAC,EAAA;;;;;;;;;;;;;;;;AEvHzE,SAAgBmX,GAAW,GAAmB,GAAe,IAAK,IAAkB;CAClF,IAAI,CAACC,EAAO,UAAUC,KAAS,GAAG,OAAO,CAAC;CAC1C,IAAMC,IAAOF,EAAO,OAAO,MAAM,OAAOrH,KAAM,QAAQ,IAAKqH,IAAsB;CACjF,IAAIE,KAAQA,EAAK,UAAU,GAAG;EAC5B,IAAMC,IAAOD,EAAK,KAAMA,EAAK;EAC7B,IAAIA,EAAK,OAAO,GAAG,MAAM3J,MAAM,KAAK,KAAK,IAAIoC,IAAIuH,EAAK3J,IAAI,KAAM4J,CAAI,IAAI,IAAI,GAAG;GAC7E,IAAMC,IAAOC,IAAKH,EAAK,KAAMA,EAAKA,EAAK,SAAS,IAC1CI,IAAMD,IAAK,KAAK;GACtB,OAAO,MAAM,KAAK,EAAE,QAAQJ,EAAM,IAAI,GAAG,MAAMM,GAAMH,IAAOE,IAAMH,KAAQ5J,IAAI,EAAE,CAAC;EACnF;CACF;CACA,IAAM2C,IAAI8G,EAAO;CACjB,OAAO,MAAM,KAAK,EAAE,QAAQC,EAAM,IAAI,GAAG,MAAOI,IAAKL,GAAQ9G,IAAI,IAAK3C,IAAI2C,IAAKA,KAAKA,KAAK8G,EAAOzJ,IAAI2C,EAAG;AACzG;AAGA,IAAMqH,MAAS,MAAsB,OAAOrH,EAAE,YAAY,EAAE,CAAC;;;ACd7D,SAAgBsH,GAAS,GAAoB;CAG3C,OAFI7H,KAAM,OAAgC,KACtCA,aAAa,OAAa,OAAO,MAAMA,EAAE,QAAQ,CAAC,IAAI,KAAK9D,EAAO8D,CAAC,IAChE,OAAOA,CAAC,CAAC,CAAC,KAAK;AACxB;AAGA,IAAM8H,KAA6B;CAAE,GAAG;CAAK,IAAI;CAAK,GAAG;CAAK,GAAG;CAAK,GAAG;CAAK,GAAG;CAAK,GAAG;CAAK,GAAG;CAAK,GAAG;CAAK,GAAG;AAAI,GACxGC,MAAmB,MAC9B/K,EACG,kBAAkB,IAAI,CAAC,CACvB,QAAQ,0BAA0B,MAAO8K,GAAGhK,MAAOA,CAAE,CAAC,CACtD,QAAQ,eAAe,GAAG,CAAC,CAC3B,KAAK,GAEJkK,MAAgB,MAAc,gCAAgC,KAAKhL,CAAC;AAM1E,SAAgBiL,GAAgB,GAA2B;CACzD,IAAIC,IAAO,IACPC,IAAY;CAChB,KAAK,IAAIvK,IAAI,GAAGA,IAAI,KAAK,IAAIJ,EAAK,QAAQ,EAAE,GAAG,KAAK;EAClD,IAAM4K,KAAS5K,EAAKI,MAAM,CAAC,EAAA,CAAG,IAAIiK,EAAQ,CAAC,CAAC,OAAO,OAAO;EAC1D,AAAKO,EAAM,WACKA,EAAM,QAAQ,MAAM,CAACJ,GAAa1K,CAAC,CAAC,CAAC,CAAC,SACxC,IAAI8K,EAAM,UACpBA,EAAM,SAASD,MACjB,IAAYC,EAAM,QAClB,IAAOxK;CAEX;CACA,IAAIsK,KAAQ,GAAG,OAAOA;CACtB,IAAMG,IAAQ7K,EAAK,WAAW,OAAOL,KAAK,CAAC,EAAA,CAAG,MAAM,MAAM0K,GAASvK,CAAC,MAAM,EAAE,CAAC;CAC7E,OAAO+K,IAAQ,IAAI,IAAIA;AACzB;AAMA,SAAgBC,GACd,GAEA,GACwB;CACxB,IAAMC,IAA8B,CAAC,GAC/BC,IAAQC,EAAQ,KAAK,MAAM,IAAI,IAAI;EAACnL,EAAE;EAAQ,OAAOA,EAAE,EAAE;EAAG,GAAIA,EAAE,iBAAiB,CAAC;CAAE,CAAC,CAAC,IAAIyK,EAAe,CAAC,CAAC;CAOnH,OANAW,EAAQ,SAAS,GAAG,MAAM;EACxB,IAAMnI,IAAIwH,GAAgBY,CAAC;EAC3B,IAAI,CAACpI,GAAG;EACR,IAAMqI,IAAOH,EAAQ,QAAQ,GAAG,MAAMD,EAAMK,EAAE,CAAE,IAAItI,CAAC,CAAC;EACtD,AAAIqI,EAAK,WAAW,MAAG,EAAI,KAAK,OAAOA,EAAK,EAAE,CAAE,EAAE;CACpD,CAAC,GACML;AACT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;A,wDCDMiD,KAAO,Y;;;;;;;;;;;;;;;;;;;;;;EAhBb,IAAM1K,IAAQC,GAaRC,IAAOH,GACPc,IAAO9O,GAAoBkO,GAAC,MAA0B,GACtD,EAAE,SAAM,cAAWjE,GAAoB,GAGvC+O,IAAS1K,QAAeL,EAAM,QAAQ,MAAM,MAAMxD,EAAE,OAAOwD,EAAM,SAAS,CAAC,GAC3EgL,IAAY3K,QAAe0K,EAAO,OAAO,UAAU/K,EAAM,SAAS,GAElEiL,IAAS5K,QACbL,EAAM,QACH,QAAQ,MAAMxD,EAAE,OAAOwD,EAAM,SAAS,CAAA,CACtC,KAAK,OAAO;GAAE,IAAIxD,EAAE;GAAc,KAAKA;GAAG,UAAU,CAAC,CAACA,EAAE;EAAS,EAAE,CACxE,GAEM0O,IAAOC,EAAwB,IAAI,GACnCC,IAAWD,EAAkC,IAAI,GACjDE,IAAUlL,EAAI,EAAK,GACnBmL,IAASnL,EAAI,EAAK,GAElBoL,IAAapL,EAAI,EAAE,GACnBqL,IAAarL,EAAI,CAAC,GAClBsL,IAAYtL,EAAI,CAAC,GACjBuL,IAAUvL,EAA4B,CAAC,CAAC,GACxCwL,IAASxL,EAAmB,IAAI,GAChCyL,IAASzL,EAAI,EAAI,GACjB0L,IAAU1L,EAAI,EAAK,GACnB2L,KAAW3L,EAAI,EAAK,GACpBa,IAAQb,EAA6B,IAAI,GAEzCzD,IAAO2D,QAAe+K,EAAS,OAAO,OAAOI,EAAW,MAAM,EAAE,QAAQ,CAAC,CAAC,GAC1E5D,KAAUvH,SAAgB3D,EAAK,MAAM+O,EAAU,UAAU,CAAC,EAAA,CAAG,IAAI1E,EAAQ,CAAC,GAC1EgF,KAAW1L,QACf3D,EAAK,MAAM,MAAM+O,EAAU,QAAQ,CAAC,CAAC,CAAC,QAAQ,OAAOpP,KAAK,CAAC,EAAA,CAAG,MAAM,MAAM0K,GAASvK,CAAC,MAAM,EAAE,CAAC,CAC/F,GACMwP,IAAgB3L,QAAe,KAAK,IAAI3D,EAAK,MAAM,QAAQ,EAAE,CAAC,GAE9DuP,UAAgB;GACpB,IAAMC,IAAO1E,GAAaI,GAAQ,OAAO5H,EAAM,OAAO,GAChDzB,IAA4B,CAAC,GAC/B4N,IAAqB;GACzB,KAAK,IAAM,CAAC,GAAGC,MAAO,OAAO,QAAQF,CAAI,GACvC,AAAIE,MAAOpM,EAAM,YAAW,MAAa,OAAO,CAAC,IACxCiL,EAAO,MAAM,MAAM,MAAMoB,EAAE,OAAOD,CAAE,CAAC,EAAE,aAAU,EAAE,OAAO,CAAC,KAAKA;GAI3E,AAFA,EAAQ,QAAQ7N,GAChB,EAAO,QAAQ4N,GACf,EAAQ,QAAQ;EAClB,GACMG,KAAO,OAAO,MAAY;GAG9B,AAFA,EAAK,QAAQD,GACb,EAAO,QAAQ,IACf,EAAQ,QAAQ;GAChB,IAAI;IACF,IAAME,IAAK,MAAMvM,EAAM,UAAUqM,CAAC;IAIlC,AAHA,EAAS,QAAQE,GACjB,EAAW,QAAQ,GACnB,EAAU,QAAQpF,GAAgBoF,EAAG,OAAO,EAAE,EAAE,QAAQ,CAAC,CAAC,GAC1DN,EAAQ;GACV,SAAS,GAAG;IAGV,AAFA,EAAS,QAAQ,MACjB,EAAO,QAAQ,IACf,EAAW,QAAQ,aAAa,QAAQ,EAAE,UAAU;GACtD,UAAU;IACR,EAAQ,QAAQ;GAClB;EACF;EACA,GAAMT,SAAkB;GAEtB,AADA,EAAU,QAAQrE,GAAgBzK,EAAK,KAAK,GAC5CuP,EAAQ;EACV,CAAC;EACD,IAAMO,KAAe,MAAc;GAEjC,AADA,EAAU,QAAQ/M,GAClBwM,EAAQ;EACV,GACMrI,MAAU,MAAa;GAC3B,IAAMyI,IAAK,EAAE,OAA4B,QAAQ;GAEhD,AADGA,KAAGC,GAAUD,CAAC,GACjB,EAAG,OAA4B,QAAQ;EAC1C,GACMI,MAAU,MAAiB;GAC/B,GAAS,QAAQ;GACjB,IAAMJ,IAAI,EAAE,cAAc,QAAQ;GAClC,AAAIA,KAAGC,GAAUD,CAAC;EACpB,GACMK,WAAc;GAMlB,AALA,EAAK,QAAQ,MACb,EAAS,QAAQ,MACjB,EAAO,QAAQ,IACf,EAAQ,QAAQ,CAAC,GACjB,EAAO,QAAQ,MACf,EAAO,QAAQ;EACjB;EACA,GAAM7L,IAAO,MAAM;GACjB,AAAKrD,KAAGkP,GAAM;EAChB,CAAC;EAGD,IAAMC,KAAWtM,QACfsL,EAAO,UAAU,OAAO,CAAC,IAAII,GAAS,MAAM,KAAK,MAAMhF,GAAS1K,IAAIsP,EAAO,MAAO,CAAC,CAAC,CAAC,OAAO,OAAO,CACrG,GACMiB,IAASzB,EAA2C,IAAI,GAC1D0B,KAA8B;EAClC,GAAMF,IAAU,OAAO,MAAS;GAE9B,AADA,EAAO,QAAQ,MACfE,IAAK,MAAM;GACX,IAAMC,IAAU,CAAC,GAAG,IAAI,IAAIC,EAAK,QAAQ,MAAM,CAAC/M,EAAM,OAAOgN,CAAC,CAAC,CAAC,CAAC;GACjE,IAAI,CAACF,EAAQ,UAAU,CAAC9M,EAAM,YAAY;IACxC,EAAO,QAAQ,IAAI,IAAI8M,EAAQ,KAAK,MAAM,CAACE,GAAG,IAAI,CAAC,CAAC;IACpD;GACF;GACA,KAAM,IAAI,gBAAgB;GAC1B,IAAMC,oBAAM,IAAI,IAAwB;GACxC,IAAI;IACF,KAAK,IAAInQ,IAAI,GAAGA,IAAIgQ,EAAQ,QAAQ,KAAK,KAAK;KAC5C,IAAMI,IAAQJ,EAAQ,MAAMhQ,GAAGA,IAAI,GAAG,GAChCqQ,IAAM,MAAMnN,EAAM,WAAWkN,GAAO,EAAE,QAAQL,GAAI,OAAO,CAAC;KAChE,KAAK,IAAMG,KAAKE,GAAO,EAAI,IAAIF,GAAGG,EAAIH,MAAM,IAAI;IAClD;IACA,EAAO,QAAQC;GACjB,QAAQ;IACN,AAAKJ,GAAI,OAAO,YAAS,EAAO,QAAQ,IAAI,IAAIC,EAAQ,KAAK,MAAM,CAACE,GAAG,IAAI,CAAC,CAAC;GAC/E;EACF,CAAC;EACD,IAAMI,IAAU/M,QAAe;GAC7B,IAAI,CAACsM,GAAS,MAAM,QAAQ,OAAO;GACnC,IAAMU,oBAAO,IAAI,IAAY,GACzBC,IAAS,GACTC,IAAS,GACPC,IAAiB,CAAC;GACxB,KAAK,IAAMR,KAAKL,GAAS,OACvB,AAAIU,EAAK,IAAIL,CAAC,MACdK,EAAK,IAAIL,CAAC,GACNhN,EAAM,OAAOgN,CAAC,IAAG,MACZJ,EAAO,OAAO,IAAII,CAAC,IAAG,MAC1BQ,EAAK,KAAKR,CAAC;GAElB,OAAO;IAAE,SAASM,IAASC;IAAQ;IAAM,SAASX,EAAO,UAAU,QAAQ,CAAC,CAAC5M,EAAM;GAAW;EAChG,CAAC,GACKyN,IAAYpN,QAAe;GAC/B,IAAMnE,IAAIkR,EAAQ;GAClB,OAAO,CAAC,CAAClR,KAAK0P,EAAO,SAAS5L,EAAM,WAAW9D,EAAE,KAAK,SAAS8D,EAAM;EACvE,CAAC,GACK0N,IAAWrN,QACT,CAAC,CAAC+K,EAAS,SAASO,EAAO,UAAU,QAAQ,CAAC,CAACyB,EAAQ,SAAS,CAACA,EAAQ,MAAM,WAAW,CAACK,EAAU,KAC7G,GAGME,MAAa,GAAa,MAAgC;GAC9D,IAAI,CAAC5T,EAAWiF,EAAI,KAAK,CAAC,SAAS,OAAOpB;GAC1C,IAAMgQ,IAAM7P,GAAagO,GAAS,MAAM,MAAM,GAAG,EAAE,CAAC,CAAC,KAAK,MAAMhF,GAAS1K,IAAIwR,EAAI,CAAC,CAAC;GACnF,OAAOD,MAAQ,MAAM,OAAOA,MAAQ,MAAM,OAAOhQ;EACnD,GACMkQ,MAAW,GAAa,GAAqB,MAA0B;GAC3E,IAAI,OAAO9P,KAAQ,YAAY,OAAOA,KAAQ,WAAW,OAAOA;GAChE,IAAIA,aAAe,MAAM,OAAO+I,GAAS/I,CAAG;GAC5C,IAAMjB,IAAOgK,GAAS/I,CAAG;GACzB,OAAOjB,MAAS,KAAK,OAAOgC,GAAWC,GAAKjC,GAAMiD,EAAM,SAAS2N,GAAUE,GAAK7O,CAAG,CAAC,CAAC;EACvF,GACM+O,MAAW,MAAuD;GACtE,IAAMpR,IAAMoP,GAAS,MAAM,IACrB/N,IAAM+I,GAASpK,IAAMkR,EAAI,GACzBzB,IAAKV,EAAQ,MAAMmC,IACnB7O,IAAMoN,IAAKpM,EAAM,QAAQ,MAAM,MAAMxD,EAAE,OAAO4P,CAAE,IAAI,KAAA;GAC1D,IAAI,CAACpN,KAAO,CAAChB,GAAK,OAAO;IAAE;IAAK,OAAO;GAAK;GAC5C,IAAMoB,IAAQ0O,GAAQD,GAAK7O,GAAKrC,IAAMkR,EAAI,GACpC7H,IAAQvL,EAAWuE,GAAK,CAAC,GAAUI,GAAOY,EAAM,MAAM;GAC5D,OAAO;IAAE;IAAK,OAAOgG,MAAUhI,IAAM,OAAOgI;GAAM;EACpD,GAEMgI,WAAc;GAClB,IAAI,CAACN,EAAS,SAAS/B,EAAO,UAAU,MAAM;GAC9C,IAAMlE,IAA6B,CAAC;GACpC,KAAK,IAAMpL,KAAK0P,GAAS,OAAO;IAC9B,IAAMI,IAAMpF,GAAS1K,IAAIsP,EAAO,MAAM;IACtC,IAAI,CAACQ,GAAK;IACV,IAAMtG,IAAkC,CAAC;IACzC,KAAK,IAAM,CAACgI,GAAKzB,MAAO,OAAO,QAAQV,EAAQ,KAAK,GAAG;KACrD,IAAI,CAACU,KAAMA,MAAO1B,IAAM;KACxB,IAAM1L,IAAMgB,EAAM,QAAQ,MAAM,MAAMxD,EAAE,OAAO4P,CAAE,GAC3CpO,IAAM3B,IAAI,OAAOwR,CAAG;KAC1B,AAAK7O,KAAO+H,GAAS/I,CAAG,MAAM,OAC9B,EAAOoO,KAAM0B,GAAQ,OAAOD,CAAG,GAAG7O,GAAKhB,CAAG;IAC5C;IACA,EAAI,KAAK;KAAE;KAAK;KAAQ,QAAQgC,EAAM,OAAOmM,CAAG,IAAI,KAAA,IAAaS,EAAO,OAAO,IAAIT,CAAG,KAAK;IAAM,CAAC;GACpG;GAEA,AADAjM,EAAK,SAAS;IAAE,MAAMuH;IAAK,QAAQmE,EAAO;GAAM,CAAC,GACjD,EAAK,QAAQ;EACf,GACMqC,KAAY5N,QAAe;GAC/B,IAAMnE,IAAIkP,EAAS,OAAO,OAAOI,EAAW;GAC5C,OAAOtP,IAAIoD,EAAK,EAAE,oBAAoB;IAAE,OAAOpD,EAAE;IAAM,OAAO6P,GAAS,MAAM;GAAO,CAAC,IAAI;EAC3F,CAAC;E,kBAIC/Z,EAAA,GAAAC,EA6LaC,EAAAgc,EAAA,GAAA;GA7LO,MAAMrN,EAAA;GAAA,iBAAA,AAAAY,EAAA,QAAA,MAAA,EAAI,QAAAC;;GAC5B,SAAAvP,QA2Le,CA3LfC,EA2LeF,EAAAic,EAAA,GAAA,MAAA;IA1Lb,SAAAhc,QAAkC,CAAlCC,EAAkCF,EAAAkc,EAAA,GAAA,EAAnB,OAAM,WAAU,CAAA,GAC/Bhc,EAwLgBF,EAAAmc,EAAA,GAAA,EAxLD,OAAM,sBAAqB,GAAA;KACxC,SAAAlc,QAUM;MAVNE,EAUM,OAVNhD,IAUM,CATJgD,EAKM,OAAA,MAAA,CAJJD,EAA+EF,EAAAoc,EAAA,GAAA,EAAlE,OAAM,kBAAiB,GAAA;OAAC,SAAAnc,QAA4B,CAAzBG,EAAAC,EAAAL,EAAAoN,CAAA,CAAI,CAAC,EAAC,cAAA,CAAA,GAAA,CAAA,C;;M,IAC9ClN,EAEoBF,EAAAqc,EAAA,GAAA,EAFD,OAAM,iBAAgB,GAAA;OACvC,SAAApc,QAAuD,CAApDG,EAAAC,EAAAL,EAAAoN,CAAA,CAAI,CAAC,EAAC,eAAA;QAAA,KAAuB0L,EAAA;QAAS,QAAE/K,EAAA;OAAM,CAAA,CAAA,GAAA,CAAA,C;;M,MAGrD7N,EAEcF,EAAAsc,EAAA,GAAA;OAFD,OAAM;OAAmC,cAAYtc,EAAAoN,CAAA,CAAI,CAAC,EAAC,cAAA;;OACtE,SAAAnN,QAAqC,CAArCC,EAAqCF,EAAAuc,EAAA,GAAA;QAA/B,MAAM;QAAI,eAAY;;;;MAGhCpc,EAqKM,OArKN/C,IAqKM;OApKJ+C,EAA4G,SAAA;QAAjG,SAAA;QAAJ,KAAI2O;QAAQ,MAAK;QAAO,OAAM;QAAa,QAAO;QAAkB,UAAS;QAAM,UAAQ4C;;OAEzFwH,EAAA,SAaTpZ,EAAA,GAAAQ,EAgJWG,GAAA,EAAA,KAAA,EAAA,GAAA;QA/ITN,EAgBM,OAhBN5C,IAgBM;SAfJ4C,EAAkF,QAAlF3C,IAAkF,CAAhD0C,EAAyCF,EAAAwc,EAAA,GAAA;UAA/B,MAAM;UAAI,eAAY;;SAClErc,EAUO,QAVP1C,IAUO,CATL0C,EAAiC,UAAA,MAAAE,EAAtB2Y,EAAA,OAAM,IAAI,GAAA,CAAA,GACRE,EAAA,MAAS,OAAO,SAAM,KAAnCpZ,EAAA,GAAAQ,EAMQ,SANR5C,IAMQ,CALNgD,GAAAP,EAIS,UAAA;UAJQ,uBAAA,AAAAoP,EAAA,QAAA,MAAA,EAAU,QAAAC;UAAG,cAAYxP,EAAAoN,CAAA,CAAI,CAAC,EAAC,oBAAA;WAAA,OAAA;WAAA,OAAA;UAAA,CAAA;S,KAC9CtN,EAAA,EAAA,GAAAQ,EAESG,GAAA,MAAAE,GAFgBuY,EAAA,MAAS,SAAlB,GAAG,OAAnBpZ,EAAA,GAAAQ,EAES,UAAA;UAFkC,KAAKsK;UAAI,OAAOA;SACtD,GAAAvK,EAAAL,EAAAoN,CAAA,CAAI,CAAC,EAAC,oBAAA;UAAA,OAA8BpD,EAAE;UAAI,OAASA,EAAE,KAAK;SAAM,CAAA,CAAA,GAAA,GAAApM,EAAA,E,oBAFtD,CAAAgD,IAAA0Y,EAAA,KAAU,C,SAM7BxZ,EAAA,GAAAQ,EAAgE,QAAhEzC,IAAgEwC,EAAnB0b,GAAA,KAAS,GAAA,CAAA,E;SAExD5b,EAES,UAAA;UAFD,MAAK;UAAS,OAAM;UAAoB,SAAK,AAAAoP,EAAA,QAAA,MAAET,EAAA,OAAO,MAAK;SAC9D,GAAAzO,EAAAL,EAAAoN,CAAA,CAAI,CAAC,EAAC,gBAAA,CAAA,GAAA,CAAA;;QAGbjN,EA+BM,OA/BNrC,IA+BM;SA9BJqC,EAAyE,QAAzEpC,IAAyEsC,EAAlCL,EAAAoN,CAAA,CAAI,CAAC,EAAC,gBAAA,CAAA,GAAA,CAAA;SAC7CjN,EAGO,QAHPnC,IAGO,CAFLkC,EAAwCF,EAAA2c,EAAA,GAAA;UAA/B,MAAM;UAAI,eAAY;S,IAC/Bxc,EAA4C,QAA5ClC,IAA4CoC,EAAnByY,EAAA,KAAS,GAAA,CAAA,C;SAEpC5Y,EAA6CF,EAAA4c,CAAA,GAAA;UAA/B,MAAM;UAAI,eAAY;;SACpCzc,EAcQ,SAAA,EAdD,OAAKI,GAAA,CAAC,8BAA4B,EAAA,cAAyBkZ,EAAA,UAAM,KAAA,CAAA,CAAA,E,IACtEtZ,EAYS,UAAA;UAXN,OAAOsZ,EAAA,SAAM;UACb,cAAYzZ,EAAAoN,CAAA,CAAI,CAAC,EAAC,oBAAA;UAClB,UAAM,AAAAmC,EAAA,QAAA,MAAuB,EAAA,QAAgCC,EAAO,OAA6B,UAAK,K,OAAiE,OAAQA,EAAO,OAA6B,KAAK;S,IAOzNrP,EAA4D,UAA5DhC,IAA4DkC,EAAxCL,EAAAoN,CAAA,CAAI,CAAC,EAAC,oBAAA,CAAA,GAAA,CAAA,IAC1BtN,EAAA,EAAA,GAAAQ,EAAqFG,GAAA,MAAAE,GAA5D+U,GAAA,QAAT,GAAG,OAAnB5V,EAAA,GAAAQ,EAAqF,UAAA;UAAlD,KAAKsK;UAAI,OAAOA;UAAI,UAAQ,CAAG+K;SAAM,GAAAtV,EAAAsV,CAAC,GAAA,GAAAvX,EAAA,E;SAG7E,AAAAmR,EAAA,QAAApP,EAAiC,QAAA,EAA3B,OAAM,mBAAkB,GAAA,MAAA,EAAA;SAC9BA,EAOQ,SAPR9B,IAOQ,CANN8B,EAA2E,QAA3E7B,IAA2E+B,EAApCL,EAAAoN,CAAA,CAAI,CAAC,EAAC,kBAAA,CAAA,GAAA,CAAA,GAC7CjN,EAIS,UAAA;UAJA,OAAOoZ,EAAA;UAAY,UAAM,AAAAhK,EAAA,QAAA,MAAE+K,EAAY,OAAQ9K,EAAO,OAA6B,KAAK,CAAA;S,KAC/F1P,EAAA,EAAA,GAAAQ,EAESG,GAAA,MAAAE,GAFWmZ,EAAA,QAAL,OAAfha,EAAA,GAAAQ,EAES,UAAA;UAF2B,KAAKiN;UAAI,OAAOA,IAAC;SAChD,GAAAlN,EAAAL,EAAAoN,CAAA,CAAI,CAAC,EAAC,qBAAA,EAAwB,KAAC,CAAA,CAAA,GAAA,GAAA5O,EAAA,E;;QAKjCib,EAAA,UAAM,QAAf3Z,EAAA,GAAAQ,EAGI,KAHJ7B,IAGI,CAFFyB,EAAiDF,EAAA8c,EAAA,GAAA;SAA/B,MAAM;SAAI,eAAY;Q,IAAS1c,EAAA,MACjDC,EAAGL,EAAAoN,CAAA,CAAI,CAAC,EAAC,sBAAA,EAAA,KAA8B0L,EAAA,MAAS,CAAA,CAAA,GAAA,CAAA,C;QAElD3Y,EAyDQ,SAzDRzB,IAyDQ;SAxDN,AAAA6Q,EAAA,QAAApP,EAKW,YAAA,MAAA;UAJTA,EAAmC,OAAA,EAA9B,OAAM,sBAAqB,CAAA;UAChCA,EAAmC,OAAA,EAA9B,OAAM,sBAAqB,CAAA;UAChCA,EAAmC,OAAA,EAA9B,OAAM,sBAAqB,CAAA;UAChCA,EAAO,KAAA;;SAETA,EAOQ,SAAA,MAAA,CANNA,EAKK,MAAA,MAAA;UAJHA,EAA2C,MAAA,MAAAE,EAApCL,EAAAoN,CAAA,CAAI,CAAC,EAAC,oBAAA,CAAA,GAAA,CAAA;UACb,AAAAmC,EAAA,QAAApP,EAAM,MAAA,MAAA,MAAA,EAAA;UACNA,EAAqC,MAAA,MAAAE,EAA9BL,EAAAoN,CAAA,CAAI,CAAC,EAAC,cAAA,CAAA,GAAA,CAAA;UACbjN,EAA0C,MAAA,MAAAE,EAAnCL,EAAAoN,CAAA,CAAI,CAAC,EAAC,mBAAA,CAAA,GAAA,CAAA;;SAGjBjN,EAyCQ,SAAA,MAAA,EAxCNL,EAAA,EAAA,GAAAQ,EAuCKG,GAAA,MAAAE,GAtCc+U,GAAA,QAAT,GAAG,OADb5V,EAAA,GAAAQ,EAuCK,MAAA;UArCF,KAAKsK;UACL,OAAKrK,GAAA,EAAA,cAAkBqK,MAAM6O,EAAA,UAAWD,EAAA,MAAQ5O,MAAC,QAAa4N,GAAI,CAAA;;UAEnErY,EAAiD,MAAA;WAA7C,OAAM;WAAiB,OAAOwV;UAAM,GAAAtV,EAAAsV,CAAC,GAAA,GAAAhX,EAAA;UACzCwB,EAAuD,MAAA,MAAA,CAAnDD,EAA8CF,EAAA+c,EAAA,GAAA;WAA/B,MAAM;WAAI,eAAY;;UACzC5c,EAkBK,MAAA,MAAA,CAjBayK,MAAM6O,EAAA,SAAtB3Z,EAAA,GAAAQ,EAGWG,GAAA,EAAA,KAAA,EAAA,GAAA,CAFTN,EAA4C,QAA5CvB,IAA4CyB,EAAnByY,EAAA,KAAS,GAAA,CAAA,GAClC3Y,EAAoE,QAApEtB,IAAoEwB,EAAnCL,EAAAoN,CAAA,CAAI,CAAC,EAAC,iBAAA,CAAA,GAAA,CAAA,C,WAEzCtN,EAAA,GAAAQ,EAYQ,SAZRxB,IAYQ,CAXNqB,EAUS,UAAA;WATN,OAAOqZ,EAAA,MAAQ5O,MAAC;WAChB,cAAY5K,EAAAoN,CAAA,CAAI,CAAC,EAAC,cAAA;WAClB,WAAM,MAAE,EAAA,QAAO;YAAA,GAAQoM,EAAA;aAAU5O,IAAK4E,EAAO,OAA6B;WAAK;;WAEhFrP,EAAqE,UAArEnB,IAAqEqB,EAAxCL,EAAAoN,CAAA,CAAI,CAAC,EAAC,oBAAA,CAAA,GAAA,CAAA;WACnCjN,EAA0D,UAAA,EAAjD,OAAOqY,GAAI,GAAAnY,EAAKL,EAAAoN,CAAA,CAAI,CAAC,EAAC,aAAA,CAAA,GAAA,CAAA;YAC/BtN,EAAA,EAAA,GAAAQ,EAESG,GAAA,MAAAE,GAFWoY,EAAA,QAAL,OAAfjZ,EAAA,GAAAQ,EAES,UAAA;YAFoB,KAAK6Z,EAAE;YAAK,OAAOA,EAAE;YAAK,UAAQ,CAAGA,EAAE;WAC/D,GAAA9Z,EAAA8Z,EAAE,IAAI,MAAM,IAAA9Z,EAAM8Z,EAAE,WAAQ,KAAA,MAAcna,EAAAoN,CAAA,CAAI,CAAC,EAAC,sBAAA,GAAA,GAAA,GAAAnO,EAAA,E;;UAK3DkB,EAYK,MAZLjB,IAYK,CAXa0L,MAAM6O,EAAA,SACpB3Z,EAAA,GAAAQ,EAAiD,QAAjDnB,IAAiDkB,EAAxBwb,GAAQjR,CAAC,CAAA,CAAE,GAAG,GAAA,CAAA,KAEpBiR,GAAQjR,CAAC,CAAA,CAAE,SAAhC9K,EAAA,GAAAQ,EAIWG,GAAA,EAAA,KAAA,EAAA,GAAA;WAHTN,EAAyD,QAAzDf,IAAyDiB,EAAxBwb,GAAQjR,CAAC,CAAA,CAAE,GAAG,GAAA,CAAA;WAC/C1K,EAA8CF,EAAA+c,EAAA,GAAA;YAA/B,MAAM;YAAI,eAAY;;WACrC5c,EAAuC,UAAA,MAAAE,EAA5Bwb,GAAQjR,CAAC,CAAA,CAAE,KAAK,GAAA,CAAA;U,WAE7B9K,EAAA,GAAAQ,EAEO,QAAA;;WAFO,OAAKC,GAAA,EAAA,mBAAA,CAAwBiZ,EAAA,MAAQ5O,MAAM4O,EAAA,MAAQ5O,OAAO4N,GAAI,CAAA;UACvE,GAAAnY,EAAAwb,GAAQjR,CAAC,CAAA,CAAE,GAAG,GAAA,CAAA,E;;;QAMhBsQ,EAAA,SAAWzB,EAAA,UAAM,QAA5B3Z,EAAA,GAAAQ,EA+BM,OA/BNjB,IA+BM;SA9BJc,EAoBM,OApBNb,IAoBM;UAnBJY,EAAwCF,EAAAgd,EAAA,GAAA;WAA/B,MAAM;WAAI,eAAY;;UAC/B7c,EASO,QAAA,MAAAE,EAPHL,EAAAoN,CAAA,CAAI,CAAC,EAAC,kBAAA;WAAoD,SAAA8N,EAAA,MAAQ;WAAqC,MAAAA,EAAA,MAAQ,KAAK;WAA8B,QAAAnN,EAAA;WAAmC,KAAA+K,EAAA;;UASjLoC,EAAA,MAAQ,KAAK,UADrBpb,EAAA,GAAAQ,EAOS,UAAA;;WALP,MAAK;WACL,OAAM;WACL,SAAK,AAAAiP,EAAA,QAAA,MAAE,EAAA,QAAO,CAAIoK,EAAA;UAEhB,GAAAtZ,EAAAL,EAAAoN,CAAA,CAAI,CAAC,EAAC,iBAAA,EAAA,KAAyB0L,EAAA,MAAS,CAAA,CAAA,GAAA,CAAA,K;;SAGpCa,EAAA,SAAX7Z,EAAA,GAAAQ,EAAyF,OAAzFf,IAAyFc,EAAhC6a,EAAA,MAAQ,KAAK,KAAI,IAAA,CAAA,GAAA,CAAA,K;SAC7DA,EAAA,MAAQ,KAAK,UAA1Bpb,EAAA,GAAAQ,EAGQ,SAHRd,IAGQ,CAFNkB,GAAAP,EAA8D,SAAA;UAA9C,uBAAA,AAAAoP,EAAA,QAAA,MAAA,EAAM,QAAAC;UAAE,MAAK;UAAW,OAAM;S,gBAA9B,CAAA1O,IAAA4Y,EAAA,KAAM,C,IAAwCtZ,EAAA,MAC9DC,EAAGL,EAAAoN,CAAA,CAAI,CAAC,EAAC,iBAAA;UAAA,OAA2B8N,EAAA,MAAQ,KAAK;UAAM,KAAOpC,EAAA;SAAS,CAAA,CAAA,GAAA,CAAA,C;SAEhEyC,EAAA,SAATzb,EAAA,GAAAQ,EAGI,KAHJb,IAGI,CAFFS,EAAiDF,EAAA8c,EAAA,GAAA;UAA/B,MAAM;UAAI,eAAY;S,IAAS1c,EAAA,MACjDC,EAAGL,EAAAoN,CAAA,CAAI,CAAC,EAAC,mBAAA;UAAA,OAA6BW,EAAA,WAAWmN,EAAA,MAAQ,KAAK;UAAM,KAAOnN,EAAA;SAAO,CAAA,CAAA,GAAA,CAAA,C;;O,WA3JxFjO,EAAA,GAAAQ,EAaS,UAAA;;QAXP,MAAK;QACL,OAAKC,GAAA,CAAC,kBAAgB;SAAA,WACDqZ,GAAA;SAAQ,aAAeR,EAAA;QAAM,CAAA,CAAA;QACjD,aAAWD,EAAA,QAAO,SAAY,KAAA;QAC9B,SAAK,AAAA5J,EAAA,QAAA,MAAET,EAAA,OAAO,MAAK;QACnB,YAAQ,AAAAS,EAAA,OAAA/O,IAAA,MAAU,GAAA,QAAQ,IAAA,CAAA,SAAA,CAAA;QAC1B,aAAS,AAAA+O,EAAA,QAAA,MAAE,GAAA,QAAQ;QACnB,QAAI/O,GAAU+Z,IAAM,CAAA,SAAA,CAAA;O,IAErBpa,EAAyF,QAAzF7C,IAAyF,CAAvD4C,EAAgDF,EAAAmd,EAAA,GAAA;QAA/B,MAAM;QAAI,eAAY;O,MACzEhd,EAAwC,QAAA,MAAAE,EAA/BL,EAAAoN,CAAA,CAAI,CAAC,EAAC,aAAA,CAAA,GAAA,CAAA,C;OAmJRgM,EAAA,SAAM,CAAKF,EAAA,SAApBpZ,EAAA,GAAAQ,EAGI,KAHJZ,IAGI,CAFCU,EAAAC,EAAAL,EAAAoN,CAAA,CAAI,CAAC,EAAC,eAAA,CAAA,IAAoB,KAC7B,CAAA,GAAgBiM,EAAA,SAAhBvZ,EAAA,GAAAQ,EAAyDG,GAAA,EAAA,KAAA,EAAA,GAAA,CAA7BL,EAAA,OAAEC,EAAGgZ,EAAA,KAAU,GAAA,CAAA,C;;MAG/ClZ,EAKM,OALNR,IAKM,CAJJO,EAAuEF,EAAAsc,EAAA,GAAA,EAA1D,OAAM,SAAQ,GAAA;OAAC,SAAArc,QAA6B,CAA1BG,EAAAC,EAAAL,EAAAoN,CAAA,CAAI,CAAC,EAAC,eAAA,CAAA,GAAA,CAAA,C;;M,IACrCjN,EAES,UAAA;OAFD,MAAK;OAAS,OAAM;OAAyB,UAAQ,CAAGqb,EAAA;OAAW,SAAOM;MAC7E,GAAAzb,EAAAL,EAAAoN,CAAA,CAAI,CAAC,EAAC,cAAA,CAAA,GAAA,GAAAxN,EAAA,C;;;;;;;;;;;;;;;;;;;;;;;EE5ZrB,IAAMoO,IAAOH,GACPc,IAAOrN,GAAoByM,GAAC,MAA0B,GACtD,EAAE,YAASjE,GAAoB,GAC/B6T,UAAa;GAEjB,AADA3P,EAAK,MAAM,GACX,EAAK,QAAQ;EACf;E,kBAIEzM,EAAA,GAAAC,EA0BkBC,EAAAmc,EAAA,GAAA;GA1BO,MAAMjP,EAAA;GAAA,iBAAA,AAAAY,EAAA,QAAA,MAAA,EAAI,QAAAC;;GACjC,SAAA9N,QAwBoB,CAxBpBC,EAwBoBF,EAAAoc,EAAA,GAAA,MAAA;IAvBlB,SAAAnc,QAAuC,CAAvCC,EAAuCF,EAAAqc,EAAA,GAAA,EAAnB,OAAM,WAAU,CAAA,GACpCnc,EAqBqBF,EAAAsc,EAAA,GAAA,EArBD,OAAM,6BAA4B,GAAA;KACpD,SAAArc,QAEmB;MAFnBC,EAEmBF,EAAAuc,EAAA,GAAA,EAFD,OAAM,kBAAiB,GAAA;OACvC,SAAAtc,QAA+D,CAA5DE,EAAAC,EAAAJ,EAAA2L,CAAA,CAAI,CAAC,EAAC,yBAAA,EAAA,OAAmCW,EAAA,OAAO,OAAM,CAAA,CAAA,GAAA,CAAA,C;;;MAE3DpM,EAEyBF,EAAAwc,EAAA,GAAA,EAFD,OAAM,iBAAgB,GAAA;OAC5C,SAAAvc,QAAuD,CAApDE,EAAAC,EAAAJ,EAAA2L,CAAA,CAAI,CAAC,EAAC,wBAAA,EAAA,OAAkCW,EAAA,OAAM,CAAA,CAAA,GAAA,CAAA,C;;;MAEnDjM,EAOK,MAPLd,IAOK,EANHO,EAAA,EAAA,GAAAQ,EAKKC,GAAA,MAAAC,GALW8L,EAAA,OAAO,MAAK,GAAA,CAAA,IAAjB,OAAXxM,EAAA,GAAAQ,EAKK,MAAA;OALgC,KAAK,EAAE;OAAO,OAAM;;OACvDJ,EAAiDF,EAAAqb,EAAA,GAAA;QAA/B,MAAM;QAAI,eAAY;;OACxChb,EAA8C,QAA9Cb,IAA8CY,EAAjB,EAAE,KAAK,GAAA,CAAA;OACpCC,EAAwC,QAAxCZ,IAAwCW,EAAf,EAAE,GAAG,GAAA,CAAA;OAC9BC,EAAiD,QAAjDX,IAAiDU,EAAnB,EAAE,OAAO,GAAA,CAAA;;MAG3CC,EAKM,OALNV,IAKM,CAJJO,EAA8GF,EAAAyc,EAAA,GAAA;OAA3F,OAAM;OAAU,SAAK,AAAA3O,EAAA,QAAA,MAAEvB,EAAI,KAAA;;OAAS,SAAAtM,QAAmC,CAAhCE,EAAAC,EAAAJ,EAAA2L,CAAA,CAAI,CAAC,EAAC,qBAAA,CAAA,GAAA,CAAA,C;;M,IAChEtL,EAES,UAAA;OAFD,MAAK;OAAS,OAAM;OAAyB,UAAQ,CAAGiM,EAAA;OAAS,SAAO4P;MAC3E,GAAA9b,EAAAJ,EAAA2L,CAAA,CAAI,CAAC,EAAC,wBAAA,EAAA,OAAkCW,EAAA,OAAM,CAAA,CAAA,GAAA,GAAA1M,EAAA,C;;;;;;;;;;;;;;;;;;EEtC7D,IAAM,EAAE,YAASyI,GAAoB,GAC/B6U,IAAI;GAAE,KAAKxW,IAAM,OAAO;GAAU,MAAMA,IAAM,OAAO;GAAU,OAAOA,IAAM,OAAO;GAAU,OAAO;EAAM;E,kBAI9GzF,EAAA,GAAAC,EAwCoBC,EAAAgc,EAAA,GAAA,MAAA;GAvClB,SAAA/b,QAsCqB,CAtCrBC,EAsCqBF,EAAAic,EAAA,GAAA,EAtCD,OAAM,wBAAuB,GAAA;IAC/C,SAAAhc,QAGkB;KAHlBC,EAGkBF,EAAAkc,EAAA,GAAA;MAHD,OAAM;MAAgB,UAAU/Q,EAAA;MAAW,UAAM,AAAAwB,EAAA,QAAA,MAAExB,EAAA,MAAM,gBAAe,EAAA;;MACvF,SAAAlL,QAA8B,CAA3BE,EAAAC,EAAAJ,EAAAwK,CAAA,CAAI,CAAC,EAAC,gBAAA,CAAA,IAAqB,KAC9B,CAAA,GAAAnK,EAAqC,OAArCd,IAAqCa,EAAd2b,EAAE,GAAG,GAAA,CAAA,C;;;KAE9B7b,EAGkBF,EAAAkc,EAAA,GAAA;MAHD,OAAM;MAAgB,UAAM,AAAAvP,EAAA,QAAA,MAAExB,EAAA,MAAM,gBAAe,EAAA;;MAClE,SAAAlL,QAA+B,CAA5BE,EAAAC,EAAAJ,EAAAwK,CAAA,CAAI,CAAC,EAAC,iBAAA,CAAA,IAAsB,KAC/B,CAAA,GAAAnK,EAAsC,OAAtCb,IAAsCY,EAAf2b,EAAE,IAAI,GAAA,CAAA,C;;;KAE/B7b,EAGkBF,EAAAkc,EAAA,GAAA;MAHD,OAAM;MAAgB,UAAU/Q,EAAA;MAAW,UAAM,AAAAwB,EAAA,QAAA,MAAExB,EAAA,MAAM,mBAAkB;;MAC1F,SAAAlL,QAAgC,CAA7BE,EAAAC,EAAAJ,EAAAwK,CAAA,CAAI,CAAC,EAAC,kBAAA,CAAA,IAAuB,KAChC,CAAA,GAAAnK,EAAuC,OAAvCZ,IAAuCW,EAAhB2b,EAAE,KAAK,GAAA,CAAA,C;;;KAEhC7b,EAGkBF,EAAAkc,EAAA,GAAA;MAHD,OAAM;MAAgB,UAAU/Q,EAAA;MAAW,UAAM,AAAAwB,EAAA,QAAA,MAAExB,EAAA,MAAM,SAAQ;;MAChF,SAAAlL,QAAmC,CAAhCE,EAAAC,EAAAJ,EAAAwK,CAAA,CAAI,CAAC,EAAC,qBAAA,CAAA,IAA0B,KACnC,CAAA,GAAAnK,EAAwC,OAAxCX,IAAwCU,EAAjBJ,EAAAoG,EAAA,CAAQ,GAAA,CAAA,C;;;KAEjClG,EAGkBF,EAAAkc,EAAA,GAAA;MAHD,OAAM;MAAgB,UAAU/Q,EAAA;MAAW,UAAM,AAAAwB,EAAA,QAAA,MAAExB,EAAA,MAAM,WAAU;;MAClF,SAAAlL,QAAgC,CAA7BE,EAAAC,EAAAJ,EAAAwK,CAAA,CAAI,CAAC,EAAC,kBAAA,CAAA,IAAuB,KAChC,CAAA,GAAAnK,EAAuC,OAAvCV,IAAuCS,EAAhB2b,EAAE,KAAK,GAAA,CAAA,C;;;KAEhC7b,EAA4CF,EAAAmc,EAAA,GAAA,EAAtB,OAAM,cAAa,CAAA;KACzCjc,EAEkBF,EAAAkc,EAAA,GAAA;MAFD,OAAM;MAAgB,UAAU/Q,EAAA;MAAW,UAAM,AAAAwB,EAAA,QAAA,MAAExB,EAAA,MAAM,UAAS,OAAA;;MACjF,SAAAlL,QAAsC,CAAnCE,EAAAC,EAAAJ,EAAAwK,CAAA,CAAI,CAAC,EAAC,wBAAA,CAAA,GAAA,CAAA,C;;;KAEXtK,EAEkBF,EAAAkc,EAAA,GAAA;MAFD,OAAM;MAAgB,UAAU/Q,EAAA;MAAW,UAAM,AAAAwB,EAAA,QAAA,MAAExB,EAAA,MAAM,UAAS,OAAA;;MACjF,SAAAlL,QAAsC,CAAnCE,EAAAC,EAAAJ,EAAAwK,CAAA,CAAI,CAAC,EAAC,wBAAA,CAAA,GAAA,CAAA,C;;;KAEXtK,EAGkBF,EAAAkc,EAAA,GAAA;MAHD,OAAM;MAAgB,UAAU/Q,EAAA;MAAW,UAAM,AAAAwB,EAAA,QAAA,MAAExB,EAAA,MAAM,mBAAkB;;MAC1F,SAAAlL,QAAiC,CAA9BE,EAAAC,EAAAJ,EAAAwK,CAAA,CAAI,CAAC,EAAC,mBAAA,CAAA,IAAwB,KACjC,CAAA,GAAAnK,EAA0C,OAA1CT,IAA0CQ,EAAnBJ,EAAAiH,CAAA,CAAU,GAAA,CAAA,C;;;KAEnBkE,EAAA,QAAhBrL,EAAA,GAAAQ,EAKWC,GAAA,EAAA,KAAA,EAAA,GAAA,CAJTL,EAA4CF,EAAAmc,EAAA,GAAA,EAAtB,OAAM,cAAa,CAAA,GACzCjc,EAEkBF,EAAAkc,EAAA,GAAA;MAFD,YAAA;MAAS,OAAM;;MAC9B,SAAAjc,QAA8F,CAA9FI,EAA8F,KAAA;OAA1F,MAAM8K,EAAA;OAAM,QAAO;OAAS,KAAI;MAAc,GAAA/K,EAAAJ,EAAAwK,CAAA,CAAI,CAAC,EAAC,mBAAA,EAAA,QAAsBW,EAAA,OAAM,CAAA,CAAA,GAAA,GAAAtL,EAAA,C;;;;;;;;;A,IErBxFuc,qBAAY,IAAI,QAA8C,GAC9DC,MAAS,MAA8C;CAC3D,IAAI,CAACnS,EAAI,MAAM,OAAOA;CACtB,IAAIlB,IAAIoT,GAAU,IAAIlS,CAAG;CAEzB,OADKlB,KAAGoT,GAAU,IAAIlS,GAAM,IAAI;EAAE,GAAGA;EAAK,MAAM,KAAA;CAAU,CAAE,GACrDlB;AACT,GAEAsT,KAAetR,EAAgB;CAC7B,MAAM;CACN,OAAO;EACL,KAAK;GAAE,MAAM;GAA4B,UAAU;EAAK;EACxD,OAAO;GAAE,MAAM;GAAQ,UAAU;EAAK;EAEtC,OAAO;GAAE,MAAM;GAAQ,UAAU;EAAK;EACtC,SAAS;GAAE,MAAM;GAAgD,UAAU;EAAK;EAChF,KAAK;GAAE,MAAM;GAA+B,UAAU;EAAK;EAC3D,WAAW;GAAE,MAAM;GAAQ,UAAU;EAAK;EAC1C,MAAM;GAAE,MAAM;GAAwE,UAAU;EAAK;EACrG,UAAU;GAAE,MAAM;GAAwE,UAAU;EAAK;EACzG,SAAS;GAAE,MAAM;GAAwE,UAAU;EAAK;EAExG,SAAS;GAAE,MAAM;GAA+C,UAAU;EAAK;EAC/E,WAAW;GAAE,MAAM;GAAoE,UAAU;EAAK;EACtG,OAAO;GAAE,MAAM;GAAuC,SAAS,KAAA;EAAU;EACzE,QAAQ;GAAE,MAAM;GAAqC,SAAS,KAAA;EAAU;EAExE,OAAO;GAAE,MAAM;GAAS,SAAS;EAAM;EACvC,UAAU;GAAE,MAAM;GAA0C,SAAS,KAAA;EAAU;EAE/E,UAAU;GAAE,MAAM;GAAwC,SAAS,KAAA;EAAU;EAE7E,QAAQ;GAAE,MAAM;GAAmC,SAAS;EAAK;EACjE,WAAW;GAAE,MAAM;GAAyC,SAAS;EAAK;EAE1E,UAAU;GAAE,MAAM;GAAmC,SAAS;EAAK;EACnE,MAAM;GAAE,MAAM;GAAoC,SAAS;EAAK;EAEhE,OAAO;GAAE,MAAM;GAA8B,SAAS,KAAA;EAAU;EAChE,SAAS;GAAE,MAAM;GAAwC,SAAS;EAAK;EAEvE,UAAU;GAAE,MAAM;GAAS,SAAS;EAAM;EAE1C,QAAQ;GAAE,MAAM;GAAS,SAAS;EAAK;EAEvC,KAAK;GAAE,MAAM;GAAQ,SAAS;EAAK;EACnC,OAAO;GAAE,MAAM;GAA4C,SAAS,KAAA;EAAU;CAChF;CACA,OAAO,CAAC,cAAc,gBAAgB;CACtC,MAAM,GAAO,EAAE,WAAQ;EACrB,IAAM6F,KAAK,GAAa,MAA6C3F,EAAM,IAAI,KAAK,EAAEmM,GAAKkF,CAAM,GAE3FC,KAAc,GAA2B,MAA0B;GACvE,IAAMtS,IAAM6O,EAAI,KACVzB,IAAKyB,EAAI,IACTzO,IAAQY,EAAM,KAAKA,EAAM,KAAKhB,CAAG,GACjCuS,IAAWvR,EAAM,QAAQA,EAAM,KAAKhB,CAAG,GACvCwS,IAAQxR,EAAM,QAAQ,IAAIoM,CAAE,GAC5BqF,IAAUzR,EAAM,OAAO,IAAIoM,CAAE,KAAK,IAClCsF,IAAW1R,EAAM,WAAWoM,GAC5BuF,IAAM3R,EAAM,WACZ4R,IAAQ,CAAC,CAACD,KAAO,KAAKA,EAAI,QAAQ,KAAKA,EAAI,IAC3CE,IAAO7R,EAAM,MACb8R,IAAS,CAAC,CAACD,KAAQ,KAAKA,EAAK,QAAQ,KAAKA,EAAK,IAC/CE,IAAK/R,EAAM,SAAS,aAAaoM,IAAKpM,EAAM,UAAU,MACtDgS,IAAQ5F,MAAOpM,EAAM,WAEvBiS;GACJ,IAAIF,GAAI,QAAQ;IACd,IAAMG,IAASlS,EAAM,UAAUhB,CAAG;IAClC,KAAU6I,EAAEqK,GAAQ;KAClB,YAAYH,EAAG;KACf,KAAK/R,EAAM,QAAQA,EAAM,GAAG;KAC5B,QAAQhB;KACR,wBAAwB,MAAekB,EAAK,cAAchB,CAAC;IAC7D,CAAC;GACH,OAAO,AAIL+S,KAJSF,IAAclK,EAAE,QAAQ,EAAE,OAAO,kBAAkB,GAAG1I,GAAUH,GAAK+S,EAAG,KAAK,CAAC,IAChFP,GAAO,UAAU,WAAW7W,EAAayE,CAAK,KAAKoS,EAAM,YAAY7L,EAAE,gBAAgB,IACpFkC,EAAE,QAAQ,EAAE,OAAO,mCAAmC,GAAG2J,EAAM,OAAO,IAEtE3J,EAAE,QAAQ,EAAE,OAAO,kBAAkB,GAAG,CAAC7N,EAAkBmX,GAAMnS,CAAG,GAAGgB,EAAM,KAAKZ,GAAOY,EAAM,GAAG,CAAC,CAAC;GAEhH,IAAMmS,IAAyB,CAACF,EAAO;GAkBvC,AAjBID,KAAShS,EAAM,SAAS,CAAC+R,KAC3BI,EAAS,KACPnS,EAAM,aAAa,aACf6H,EAAEuK,IAAe;IACf,MAAM;IACN,OAAO;IACP,MAAM;IACN,cAAczM,EAAE,gBAAgB;GAClC,CAAC,IACDkC,EACE,QACA,EAAE,OAAO,CAAC,cAAc,EAAE,aAAa7H,EAAM,aAAa,SAAS,CAAC,EAAE,GACtE2F,EAAE3F,EAAM,aAAa,WAAW,qBAAqB,eAAe,CACtE,CACN,GACEgS,KAAShS,EAAM,YAAY,CAAC+R,KAC9BI,EAAS,KAAKtK,EAAE,QAAQ;IAAE,OAAO;IAAwB,MAAM;GAAU,GAAG7H,EAAM,QAAQ,CAAC,GACzF,CAACuR,KAAY,CAACS,KAChBG,EAAS,KACPtK,EAAEgH,IAAQ;IAAE,MAAM;IAAI,OAAO;IAAgB,MAAM;IAAO,cAAclJ,EAAE,sBAAsB;GAAE,CAAC,CACrG;GACF,IAAM0M,IAAQb,IAAQ,GAAGxR,EAAM,IAAI,GAAGA,EAAM,MAAM,GAAG,MAAM,KAAA;GAqB3D,OApBIwR,KACFW,EAAS,KACPtK,EAAE,QAAQ;IAAE,IAAIwK;IAAO,OAAO,CAAC,eAAe,MAAMb,EAAM,OAAO;IAAG,MAAM;GAAU,GAAG,CACrFA,EAAM,SACNA,EAAM,UACF3J,EACE,UACA;IACE,MAAM;IACN,OAAO;IACP,UAAU;IACV,eAAe3H,EAAK,kBAAkBlB,GAAKwS,EAAM,QAAS,KAAK;GACjE,GACA7L,EAAE,mBAAmB,EAAE,QAAQ6L,EAAM,QAAQ,MAAM,CAAC,CACtD,IACA,IACN,CAAC,CACH,GACExR,EAAM,aAAaoM,KAAM,CAAC2F,KAAII,EAAS,KAAKtK,EAAE,QAAQ;IAAE,OAAO;IAAkB,eAAe;GAAO,CAAC,CAAC,GAEtGA,EACL,OACA;IACE,OAAO;KACL;KACA,MAAM3N,EAAQ8E,CAAG;KACjB;MACE,cAAcxD,EAAcwD,EAAI,IAAI;MACpC,UAAUgT;MACV,UAAUA,KAAShS,EAAM;MACzB,eAAe,CAACuR;MAChB,aAAaG;MACb,eAAeE;MACf,aAAaA,KAAS,MAAMD,EAAK;MACjC,aAAaC,KAAS,MAAMD,EAAK;MACjC,aAAaC,KAASD,EAAK;MAC3B,aAAaC,KAASD,EAAK;MAC3B,WAAWG;MACX,eAAeA,KAAUD,EAAM;MAC/B,YAAY7R,EAAM,OAAO,IAAIoM,CAAE,KAAK;MACpC,cAAc,CAAC,CAAC2F;MAChB,cAAcN;MACd,YAAYD,GAAO,UAAU,WAAYQ,KAAS,CAAC,CAAChS,EAAM;MAC1D,cAAcwR,GAAO,UAAU;MAC/B,gBAAgBxR,EAAM;MACtB,mBAAmB6N,EAAI,WAAW;MAClC,iBAAiBA,EAAI,WAAW;MAChC,eAAeA,EAAI;KACrB;IACF;IACA,OAAO;KACL,GAAIA,EAAI,WAAW,UACf,EAAE,MAAM,OAAOA,EAAI,UAAU,GAAG,IAChCA,EAAI,WAAW,QACb,EAAE,OAAO,OAAOA,EAAI,UAAU,GAAG,IACjC;KACN,GAAGtT,EAAcyE,GAAKI,CAAK;IAC7B;IACA,MAAM;IACN,UAAUsS,IAAW,IAAI;IACzB,iBAAiBH,IAAW,KAAA,IAAY;IACxC,iBAAiBK,IAAQ,SAAS,KAAA;IAClC,oBAAoBS;IACpB,gBAAgBb,GAAO,UAAU,UAAU,SAAS,KAAA;IACpD,YAAYpF;IAEZ,eACEqF,KAAW,CAACD,KAAS,CAACO,KAAM,CAAC/R,EAAM,QAC/B2F,EAAE,aAAa,EAAE,OAAOlL,EAAWuE,GAAKgB,EAAM,KAAKA,EAAM,SAASA,EAAM,KAAKhB,CAAG,GAAGgB,EAAM,GAAG,EAAE,CAAC,IAC/F,KAAA;GACR,GACAmS,CACF;EACF,GAEMG,UAAe;GACnB,IAAIC,IAAW,CAAC,CAACvS,EAAM;GACvB,KAAK,IAAMlD,KAAKkD,EAAM,QAAQ,OAAO,KAAK,CAAC,GAAG,AAAIlD,EAAE,UAAU,YAAS,IAAW;GAClF,IAAM2U,IAAU,CAAC,CAACzR,EAAM,OAAO;GAC/B,OAAO6H,EACL,OACA;IACE,OAAO;KAAC;KAAW;KAAa;IAAiB;IACjD,OAAO,EAAE,MAAM,MAAM;IACrB,MAAM;IACN,eAAe7H,EAAM;GACvB,GACA,CACEuS,IACI1K,EAAEmH,IAAiB;IACjB,MAAM;IACN,OAAO;IACP,MAAM;IACN,cAAcrJ,EAAE,iBAAiB;GACnC,CAAC,IACD3F,EAAM,QACJ6H,EAAE2K,IAAQ;IAAE,MAAM;IAAI,OAAO;IAAkB,MAAM;IAAO,cAAc7M,EAAE,eAAe;GAAE,CAAC,IAC9F8L,IACE5J,EAAE,QAAQ;IAAE,OAAO;IAAsB,MAAM;IAAO,cAAclC,EAAE,eAAe;GAAE,CAAC,IACxF,MACRkC,EAAE,QAAQ,EAAE,OAAO,eAAe,GAAG,OAAO7H,EAAM,KAAK,CAAC,CAC1D,CACF;EACF;EAEA,aAAa;GACX,IAAMyS,IAAQ,IAAI,IAAIzS,EAAM,QAAQ,KAAK,GAAG,MAAM,CAACxD,EAAE,IAAIM,CAAC,CAAC,CAAC;GAC5D,OAAO+K,EACL,OACA;IACE,OAAO,CAAC,UAAU,EAAE,iBAAiB7H,EAAM,WAAW,KAAK,CAAC;IAC5D,MAAM;IACN,iBAAiBA,EAAM,QAAQ;IAC/B,cAAcA,EAAM;IACpB,OAAOA,EAAM;GACf,GACA,CAACA,EAAM,SAASsS,EAAO,IAAI,MAAM,GAAG/W,EAASyE,EAAM,UAAU,MAAQsR,EAAWzD,GAAK4E,EAAM,IAAI5E,EAAI,EAAE,CAAE,CAAC,CAAC,CAC3G;EACF;CACF;AACF,CAAC,G;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;A,GC5OK6F,KAAc,IAEdC,KAAO,IACPC,KAAc,I;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAEpB,IAAM5T,IAAQC,GAoCR8T,IAAM/X,GAAoB,GAC1BgY,IAAMC,GAAM,GACZC,IAAO/T,EAAwB,IAAI,GACnCgU,IAAWhU,EAAwB,IAAI,GACvCiU,IAASpU,EAAM,QACf4F,IAAQ5F,EAAM,OACdqU,IAAQzO,EAAM,OACd0O,IAAQ1O,EAAM,OACd2O,IAAQD,EAAM,OAEdE,IAAS,OAAO,cAAe,cAAc,WAAW,mBAAmB,CAAC,CAAC,SAC7EC,IAAUpU,QAAyBmU,KAAUxU,EAAM,YAAY,YAAY,aAAaA,EAAM,OAAQ,GAEtG0U,IAAWrU,QAAgBL,EAAM,QAAQ,IAAI0T,EAAY;EAE/D,SACQ;GACJ,IAAMlU,IAAK0U,EAAK;GAChB,IAAI,CAAC1U,GAAI;GACT,IAAMmV,IAAID,EAAS;GAEnB,AADAlV,EAAG,MAAM,YAAY,UAAU,GAAGmV,IAAI,GAAGA,EAAE,OAAO,KAAKP,EAAO,QAAQ,OAAO,GAC7E5U,EAAG,MAAM,YAAY,cAAc,GAAG4U,EAAO,SAAS,QAAQO,EAAE,GAAG;GACnE,IAAMC,IAAY,IAAI,IAAIR,EAAO,MAAM,MAAM,KAAK,MAAM5X,EAAE,SAAS,CAAC;GACpE,KAAK,IAAM,CAACqY,GAAMzV,MAAU,OAAO,QAAQgV,EAAO,WAAW,KAAK,GAChE,EAAG,MAAM,YAAYS,GAAMD,EAAU,IAAIC,CAAI,IAAI,GAAG,WAAWzV,CAAK,IAAIuV,EAAE,MAAMvV,CAAK;EACzF,GACA,EAAE,OAAO,OAAO,CAClB;EAEA,IAAM0V,IAAY3U,EAAI,EAAE,GAIlB4U,IAAQ5U,EAAI,EAAE,GACd6U,KAAO7U,EAAI,CAAC,GACZ8U,UAAiB;GACrB,IAAMzV,IAAK2U,EAAS;GACpB,GAAK,QAAQ3U,IAAK,KAAK,IAAI,GAAGA,EAAG,eAAeA,EAAG,YAAY,IAAI;EACrE,GACM0V,UAAsB;GAC1B,IAAMhW,IAAIgV,EAAK,QAAQ,WAAW,iBAAiBA,EAAK,KAAK,CAAC,CAAC,iBAAiB,YAAY,CAAC,IAAI;GAGjG,AAFA,EAAU,QAAQ,OAAO,SAAShV,CAAC,IAAIA,IAAI,IAC3C,EAAM,QAAQgV,EAAK,OAAO,cAA2B,UAAU,CAAC,EAAE,gBAAgBa,EAAM,OACxFE,EAAS;EACX;EAEA,AADAE,GAAUD,CAAa,GACvBE,GAAMX,SAAe,sBAAsBS,CAAa,CAAC;EAEzD,IAAMG,KAAS,IAAI3a,EAAa,GAC1BiE,KAAM0B,SAA2B;GACrC,KAAK1G,EAAUoa,EAAI,MAAM;GACzB,MAAMA,EAAI;GACV,uBAAO,IAAI,KAAK;GAChB;GACA,SAASU,EAAQ;GACjB;EACF,EAAE,GACI9M,IAAUtH,QAAe+T,EAAO,QAAQ,KAAK,GAC7CkB,KAAUjV,QAAe,IAAI,IAAIsH,EAAQ,MAAM,KAAK,MAAM,CAACnL,EAAE,IAAIA,EAAE,GAAG,CAAC,CAAC,CAAC,GACzE+Y,IAAalV,QAAe;GAChC,IAAM9B,oBAAI,IAAI,IAAoB;GAElC,OADAyB,EAAM,KAAK,SAAS,GAAG,MAAMzB,EAAE,IAAIgW,EAAMlY,CAAC,GAAGS,CAAC,CAAC,GACxCyB;EACT,CAAC,GACKiX,KAASnB,EAAM,QACfoB,KAAcpV,QAAgBmV,GAAO,QAASD,EAAW,MAAM,IAAIC,GAAO,MAAM,KAAK,KAAK,KAAM,EAAG,GAEnGE,KAAQrV,QAAe;GAC3B,IAAMsV,IAAItB,EAAM,OAAO;GACvB,OAAO,CAAC,CAACsB,MAAMA,EAAE,cAAcA,EAAE,eAAeA,EAAE,iBAAiBA,EAAE;EACvE,CAAC,GACKC,KAAgB,MAAmC;GACvD,IAAMD,IAAItB,EAAM,OAAO;GAEvB,OADI,CAACsB,KAAK,CAACD,GAAM,SAAS5Y,IAAI6Y,EAAE,eAAe7Y,IAAI6Y,EAAE,cAAoB,OAClE;IAAE,MAAMA,EAAE;IAAgB,IAAIA,EAAE;IAAgB,KAAK7Y,MAAM6Y,EAAE;IAAa,QAAQ7Y,MAAM6Y,EAAE;GAAY;EAC/G,GAEME,MAAa,MAA6B;GAC9C,IAAMF,IAAItB,EAAM,OAAO;GAGvB,OAFI,CAACsB,KAAKG,EAAS,SAAS9V,EAAM,QAAc,OAC3C0V,GAAM,QACJ5Y,MAAM6Y,EAAE,cAAehO,EAAQ,MAAMgO,EAAE,eAAe,EAAE,MAAM,OAAQ,OADpD7Y,MAAM2Y,GAAY,QAASD,GAAO,OAAO,YAAY,OAAQ;EAExF,GACMO,KAAc,MAAkC;GACpD,IAAMC,IAAIpQ,EAAM,KAAK,QAAQ,OACvBjJ,IAAMqD,EAAM,KAAKlD;GACvB,OAAOkZ,KAAKrZ,KAAO4X,EAAMyB,EAAE,GAAG,MAAMzB,EAAM5X,CAAG,IACzC;IAAE,UAAUqZ,EAAE,IAAI;IAAc,OAAOA,EAAE;IAAO,QAAQA,EAAE;GAAO,IACjE;EACN,GACMC,KAAY,MAAc;GAC9B,IAAMtZ,IAAMqD,EAAM,KAAKlD;GACvB,OAAOH,IAAMqD,EAAM,OAAO,IAAIuU,EAAM5X,CAAG,CAAC,IAAI,KAAA;EAC9C,GAEM6J,IAAQnG,QAAgBL,EAAM,WAAW,KAAKA,EAAM,KAAK,MAAO,GAChEkW,IAAcC,GAClB9V,SAAgB;GACd,OAAOmG,EAAM;GACb,wBAAwB2N,EAAS;GACjC,oBAAoBW,EAAU,QAAQ;GACtC,cAAcC,EAAM;GACpB,oBAAoBA,EAAM;GAC1B,kBAAkBC,GAAK;GACvB,UAAU;GACV,aAAa,MAAehV,EAAM,WAAW,MAAMlD,MAAMyX,EAAMvU,EAAM,KAAKlD,EAAG;GAE7E,iBAAiB,MAAqF;IACpG,IAAMsZ,IAAQ,KAAK,IAAI,GAAGC,EAAM,aAAaA,EAAM,QAAQ,GACrDC,IAAM,KAAK,IAAID,EAAM,QAAQ,GAAGA,EAAM,WAAWA,EAAM,QAAQ,GAC/D5O,IAAgB,CAAC,GACjB8O,IAAIvW,EAAM,WAAW,KAAKyV,GAAY;IAC5C,AAAIc,KAAK,KAAKA,IAAIH,KAAO3O,EAAI,KAAK8O,CAAC;IACnC,KAAK,IAAIzZ,IAAIsZ,GAAOtZ,KAAKwZ,GAAK,KAAK,EAAI,KAAKxZ,CAAC;IAE7C,OADIyZ,IAAID,KAAOC,IAAIF,EAAM,SAAO5O,EAAI,KAAK8O,CAAC,GACnC9O;GACT;EACF,EAAE,CACJ,GACM+O,KAAcnW,QAAe6V,EAAY,MAAM,gBAAgB,CAAC,GAChEO,KAAYpW,QAAe6V,EAAY,MAAM,aAAa,CAAC;EACjE,GAAMpB,SAAiBoB,EAAY,MAAM,QAAQ,CAAC;EAElD,IAAMQ,KAAgBvL,EAAW,EAAK,GAChCwL,UAAiB;GAErB,AADA1B,EAAS,GACT,GAAc,SAASd,EAAS,OAAO,cAAc,KAAK;EAC5D,GAGMyC,MAAU,GAAW,MAAyC;GAClE,IAAMja,IAAMuX,EAAK,OAAO,cAA2B,uBAAuBpX,EAAE,GAAG;GAC/E,IAAI,CAACH,GAAK,OAAO;GACjB,KAAK,IAAMH,KAAKG,EAAI,iBAA8B,oBAAoB,GAAG,IAAIH,EAAE,QAAQ,QAAQqa,GAAU,OAAOra;GAChH,OAAO;EACT,GACMsa,WAA4B;GAChC,IAAIC,IAAI;GACR,KAAK,IAAMva,KAAK0X,EAAK,OAAO,iBAA8B,2BAA2B,KAAK,CAAC,GAAG,KAAK1X,EAAE;GACrG,OAAOua;EACT,GAEMC,KAAW,MAAoB;GACnC,IAAMC,IAAK9C,EAAS;GACpB,IAAI,CAAC8C,KAAMzX,EAAG,UAAU,SAAS,iBAAiB,GAAG;GACrD,IAAMnD,IAAImD,EAAG,sBAAsB,GAC7BtD,IAAI+a,EAAG,sBAAsB,GAC7BC,IAAOhb,EAAE,OAAO4a,GAAY;GAClC,AAAIza,EAAE,OAAO6a,IAAM,EAAG,cAAcA,IAAO7a,EAAE,OACpCA,EAAE,QAAQH,EAAE,UAAO,EAAG,cAAcG,EAAE,QAAQH,EAAE;EAC3D,GAEMib,WAAkB;GACtB,IAAMb,IAAMjC,EAAM,SAAS,OACrBvX,IAAIwZ,IAAMf,EAAW,MAAM,IAAIe,EAAI,KAAK,IAAI,KAAA;GAClD,AAAKA,KAAOxZ,MAAM,KAAA,MAClBoZ,EAAY,MAAM,cAAcpZ,GAAG,EAAE,OAAO,OAAO,CAAC,GACpD,4BAA4B;IAC1B,IAAM0C,IAAKoX,GAAO9Z,GAAGwZ,EAAI,QAAQ;IACjC,AAAI9W,KAAIwX,EAAQxX,CAAE;GACpB,CAAC;EACH,GAGM4X,WAAoB,KAAKrW,SAAesW,GAAS,CAAC,CAAC,GACnDA,MAAY,MAAkB;GAClC,IAAMd,IAAIf,GAAO;GAEjB,IAAI,CAACe,KAAK3Q,EAAM,KAAK,QAAQ,OAAO,QAAQ;GAC5C,IAAM9I,IAAIyY,EAAW,MAAM,IAAIgB,EAAE,KAAK;GACtC,IAAIzZ,MAAM,KAAA,GAAW;IACnB,AAAIgK,IAAQ,KAAG,4BAA4BuQ,GAASvQ,IAAQ,CAAC,CAAC;IAC9D;GACF;GACA,EAAY,MAAM,cAAchK,GAAG,EAAE,OAAO,OAAO,CAAC;GACpD,IAAMwa,KAAY,MAAoB;IACpC,IAAM9X,IAAKoX,GAAO9Z,GAAGyZ,EAAE,QAAQ;IAC/B,AAAI/W,KACFA,EAAG,MAAM,EAAE,eAAe,GAAK,CAAC,GAChCwX,EAAQxX,CAAE,KACD+X,IAAU,KAAG,4BAA4BD,EAASC,IAAU,CAAC,CAAC;GAC3E;GACA,EAAS,CAAC;EACZ,GAEMC,MAAa,GAAW,MAAqB;GACjD,IAAM7a,IAAMqD,EAAM,KAAK,KAAK,IAAI,GAAG,KAAK,IAAIA,EAAM,KAAK,SAAS,GAAGlD,CAAC,CAAC;GACrE,AAAKH,MACL0X,EAAM,MAAME,EAAM5X,CAAG,GAAGka,CAAQ,GAChCO,GAAY;EACd,GAEM1Q,MAAQ,MAA0B;GACtC,IAAM6P,IAAIf,GAAO;GACjB,IAAI,CAACe,GAAG;GACR,IAAMkB,IAAO9P,EAAQ,OACf+P,IAAKD,EAAK,WAAW,MAAMjb,EAAE,OAAO+Z,EAAE,QAAQ,GAC9CoB,IAAKlC,GAAY;GAMvB,AALI5O,MAAQ,UACN6Q,IAAKD,EAAK,SAAS,IAAGpD,EAAM,KAAK,OAAO,IACnCsD,IAAK3X,EAAM,KAAK,SAAS,KAAGqU,EAAM,MAAME,EAAMvU,EAAM,KAAK2X,IAAK,EAAE,GAAGF,EAAK,EAAE,CAAE,EAAE,IAC9EC,IAAK,IAAGrD,EAAM,KAAK,MAAM,IAC3BsD,IAAK,KAAGtD,EAAM,MAAME,EAAMvU,EAAM,KAAK2X,IAAK,EAAE,GAAGF,EAAKA,EAAK,SAAS,EAAE,CAAE,EAAE,GACjFL,GAAY;EACd,GAEMQ,MAAQ,MAAmB;GAC/B,IAAMrB,IAAIf,GAAO,OACXiC,IAAO9P,EAAQ;GACrB,IAAId,MAAQ,QAAQ,EAAM,MAAM0P,EAAE,OAAOkB,EAAK,EAAE,CAAE,EAAE;QAC/C,IAAI5Q,MAAQ,SAAS,EAAM,MAAM0P,EAAE,OAAOkB,EAAKA,EAAK,SAAS,EAAE,CAAE,EAAE;QACnE;IACH,IAAM9a,IAAMqD,EAAM,KAAK6G,MAAQ,OAAO,IAAI7G,EAAM,KAAK,SAAS;IAC9D,AAAIrD,KAAK0X,EAAM,MAAME,EAAM5X,CAAG,GAAG4Z,EAAE,QAAQ;GAC7C;EACF,GACMsB,WAAiB,KAAK,IAAI,GAAG,KAAK,OAAO1D,EAAS,OAAO,gBAAgB,MAAMW,EAAU,QAAQ,EAAE,IAAI,CAAC,GACxGgD,IAAiC;GAAE,SAAS;GAAM,WAAW;GAAQ,WAAW;GAAQ,YAAY;EAAQ,GAC5Gzd,KAAM,OAAO,YAAc,OAAe,kBAAkB,KAAK,UAAU,QAAQ,GAEnF+G,MAAa,MAAqB;GACtC,IAAM2W,IAAS,EAAE,QACXhG,IAAKnM,EAAM,KAAK,QAAQ;GAC9B,IAAImM,GAAI,QAAQ;IAGd,IAAI,EAAE,QAAQ,OAAO;KAGnB,AAFA,EAAE,eAAe,GACjBnM,EAAM,KAAK,OAAO,GAClBc,GAAK,EAAE,WAAW,SAAS,OAAO;KAClC;IACF;IAEA,IAAI,EAAE,QAAQ,YAAYqL,EAAG,IAAI,SAAS,iBAAiB,CAACA,EAAG,IAAI,QAAQ;KAGzE,AAFA,EAAE,eAAe,GACjBnM,EAAM,KAAK,OAAO,GAClBwR,GAAY;KACZ;IACF;IACA,IAAI,EAAE,oBAAoBW,EAAO,aAAa,eAAe,MAAM,UAAUA,EAAO,YAAY,UAAU;IAC1G,AAAI,EAAE,QAAQ,WAAW,EAAE,EAAE,YAAYA,EAAO,YAAY,eAC1D,EAAE,eAAe,GACjBnS,EAAM,KAAK,OAAO,GAClByO,EAAM,KAAK,MAAM,GACjB+C,GAAY,KACH,EAAE,QAAQ,aACnB,EAAE,eAAe,GACjBxR,EAAM,KAAK,OAAO,GAClBwR,GAAY;IAEd;GACF;GACA,IAAMxa,IAAOmb,EAAO,QAAqB,oBAAoB;GAC7D,IAAI,CAACnb,GAAM;GACX,IAAImb,MAAWnb,GAAM;IAEnB,AAAI,EAAE,QAAQ,aACZ,EAAE,eAAe,GACjBA,EAAK,MAAM;IAEb;GACF;GACA,IAAM2Z,IAAIf,GAAO,OACX7Y,IAAMqD,EAAM,KAAKyV,GAAY,QAC7BzW,IAAMuX,IAAIjB,GAAQ,MAAM,IAAIiB,EAAE,QAAQ,IAAI,KAAA;GAChD,IAAI,CAACA,KAAK,CAAC5Z,KAAO,CAACqC,GAAK;GACxB,IAAMuS,IAAW3L,EAAM,QAAQjJ,GAAKqC,CAAG,GACjCgZ,IAAM,EAAE,WAAW,EAAE,SACrBnR,IAAMiR,EAAI,EAAE;GAClB,IAAIjR,GAAK;IAEP,IADA,EAAE,eAAe,GACb,EAAE,UAAU;KAEd,AADAwN,EAAM,OAAOxN,CAAG,GAChB9F,GAAcoW,EAAS;KACvB;IACF;IAGA,AAFIa,IAAKJ,GAAK/Q,CAAG,IACZwN,EAAM,KAAKxN,CAAG,GACnBuQ,GAAY;GAEd,OACA;YAAQ,EAAE,KAAV;KACE,KAAK;MAEH,AADA,EAAE,eAAe,GACjB1Q,GAAK,EAAE,WAAW,SAAS,OAAO;MAClC;KACF,KAAK,SAAS;MACZ,EAAE,eAAe;MACjB,IAAMuR,IAAS1G,IAAW,OAAO3U,EAAK,cAA2B/C,CAAoB;MACrF,AAAIoe,IAAQA,EAAO,MAAM,KAEvB5D,EAAM,KAAK,MAAM,GACjB+C,GAAY;MAEd;KACF;KACA,KAAK;MAEH,AADA,EAAE,eAAe,GACjBxR,EAAM,KAAK,MAAMjJ,GAAKqC,GAAK,EAAE,QAAQ,GAAK,CAAC;MAC3C;KACF,KAAK;MAEH,AADA,EAAE,eAAe,GACjBqV,EAAM,MAAMkC,EAAE,OAAOA,EAAE,QAAQ;MAC/B;KACF,KAAK;MAEH,AADA,EAAE,eAAe,GACbvX,EAAI,SAAS,aAAauS,KAAU3L,EAAM,OAAOjJ,GAAKqC,CAAG;MAC7D;KACF,KAAK;KACL,KAAK;MAEH,AADA,EAAE,eAAe,GACjB4G,EAAM,WAAW;MACjB;KACF,KAAK;MAEH,AADA,EAAE,eAAe,GACjB4R,GAAUQ,IAAM,IAAIvC,GAAY,OAAO9N,EAAQ,MAAM,EAAE,CAAE,EAAE;MAC3D;KACF,KAAK;MAEH,AADA,EAAE,eAAe,GACjB6P,GAAUQ,IAAMhY,EAAM,KAAK,SAAS,IAAIyV,GAAY,OAAO9N,EAAQ,MAAMA,EAAQ,MAAM,SAAS,EAAE,CAAE,EAAE;MACtG;KACF,KAAK;MAEH,AADA,EAAE,eAAe,GACjB6P,GAAU/B,GAAY,QAAQoC,GAAS,GAAGtB,EAAE,QAAQ;MACpD;KACF,KAAK;MAEH,AADA,EAAE,eAAe,GACjBiB,GAAU/B,GAAY,QAAQoC,GAAS,GAAGtB,EAAE,QAAQ;MACpD;KACF,KAAK;MAEH,AADA,EAAE,eAAe,GACjB3Q,EAAM,UAAU,EAAE,WAAW,KAAK,CAAC;MACnC;KACF,KAAK;KACL,KAAK;MACH,IAAI,EAAE,QAAQ,SAAS,CAAC,EAAE,UAAU;MAEpC,AADA,EAAE,eAAe,GACjBsS,GAAWtb,CAAI;MACf;IACJ;IACA,IAAIob,GAAK;KAEP,IAAMhL,IAAI,EAAE,IAAI,YAAY;KAC5B,AAAIA,MAAM,OAAO,CAAC,EAAE,YAClB,EAAE,eAAe,GACjBqH,EAAM,UAAU,KACPrH,MAAM,OACf,EAAE,eAAe,GACjBpH,EAAM,KAAK,KACFoH,MAAM,OAAO,CAAC,EAAE,YACzB,EAAE,eAAe,GACjBpH,EAAM,SAAS,KACNoH,MAAM,OAAO,CAAC,EAAE,YACzB,EAAE,eAAe,GACjBpH,EAAM,KAAK,KACDoH,MAAM,OAAO,EAAE,YAAcA,MAAM,OAAO,CAAC3S,MACrD,EAAE,eAAe,GACjBuL,EAAM,KAAK,MACF,EAAE,QAAQ,OAAO,EAAE,QAAQ,gBACpC,EAAE,eAAe,GACjBA,EAAM,mBAAmB;IAG7B,OAEA,AAAI,EAAE,IAAI,WAAW,KAAK,CAAC,EAAE,UAAU2L,MACrC,EAAE,eAAe,GACjB3L,EAAM,KAAK,MAAMjJ,GAAKqC,GAAK;KAAE,QAAQ;KAAM,SAAS,EAAE;IAAI,CAAC;GA5B7D;EA8BF,GAGMmZ,MAAa,GAAmB,MAAqC;GACzE,AAAIvS,EAAM,KAAK,QAAQ,OAAO,UAAU9L,EAAY,EAAE,MAAiB,KACjE,EAAE,OAAuB,QAAQ,oBAAoB,KACvD8L,EAAMwS,EAAO,CAAC,EAAE,aAAa,KAAG,EAAE,eAAe;EACvD,GASMC,MAAS,MAA2C;GACxD,IAAMzb,IAAOmb,GAAQ,QAAqB,oBAAoB,GACxDO,IAAQP,GAAQ,QAAqB,qBAAqB;GAChE,IAAI,CAACnb,KAAQ,CAAC0b,KAAStY,EAAM,UAAU,OAAO;GAC9C,IAAMyS,IAAQ,OAAO6F,EAAM,QAAQ,KAAK,GAClC3b,IAAMqD,EAAM,KAAKyS;GACvB,OAAO9V,IAAM;IAAE;IAAO;IAAK,UAAUC,EAAK,QAAQ;IAAM;IAAc;GAAQ,IAAI;EACpF,GACM2b,MAAO,MAAyBF,GAAM,EAAE,MAAqB,GAG7DvM,IAAWX,EAAqC,IAAI,GACpD2K,IAAW3K,EAA8F,IAAI,GAC7GqN,KAAYrN,EAA+D,IAAI,GACjFsN,KAAU;GAAE,GAAG;GAAG,GAAG;EAAE,GACvBC,KAAY,GACVC,MAAY,MAAkB;GAClC,IAAK9Q,GACL;QAAIiE,EAAS,UAAU,QAAQ;KAC7B,IAAMO,IAAIyJ,EAAS,OACbiC,IAASlQ,EAAE,QAAQwE,EAAE,SAAkBxE,EAAE,QAAQwE,EAAE,UAAtBxE,EAAE,QAAwCwE,EAAE;KAC/E,AAAI0L,MAAW1L,EAAE,WACf,EAAS,QAAQ;MAAE,GAAGA;MAAG;KAAO,GAChCuM,GAAgB;IAEpB,OAAO,EAAM,cAAcrE,EAAM1M,EAAE,GAAG,GAAGA,EAAE,QAAQ,CAAC,GAAG,IAAI,WAAW,WAAW,CAAC;GAAA;EACpF,GACMgR,WAAmB;GACvB,KAAY;GACZ,IAAM5B,IAAK9C,EAAS;GACpB,IAAI,CAACrI,EAAS,SAAS,CAACmL,GAAI;GAC5B,IAAM5a,IAAI4a,EAAG,sBAAsB,GAC/B6B,IAAK;GACT,AAAIL,GAAQ,IAAIpc,EAAE,MAAMsX,KAAM,IAAK,MAC1B8E,GAAQ,IAAIpc,EAAE,SAASsX,OAAM,IAAKC;GAC3C,IAAImF,IAAK;GAKT,AAJIjN,EAAS,UAAU,aACjB2M,GAAQ,IAAIpc,EAAE,OAAOya,GAAY,IAAInD,KAAM,IAAK,MAC3C8E,GAAQ,IAAIpc,EAAE,QAAQsX,OAAM,IAAKC,OAExCkF,KAAMC,OACR,EAAG,aAAaD,GAChB,EAAG,cAAcC,GACjBJ,GAASN,GAAM,SAAS,iBAAiBI,GAAQ,GAAGA,GAAQ,CAAC,CAAuB,CAAC,GACrF,KAAY,sBAAsBI,EAAU;EAEhD,GACMG,MAAe,MAAkB;GACrC,AAAKlN,EAAS,UACd,KAAU;IAAE,GAAG,EAAE;IAAS,GAAG,EAAE;GAAQ,GACnCA,EAAS,UAAU,UAAQ6M,GAASJ,GAAI,CAAC,CAAC,GAC9C,AAAgBG,OAAY,sBAAsBG,EAAU;EAC9D,GACMD,WAAwB;GAC5B,IAAMvM,IAAIyJ,EAAS;GACnB,IAAI,CAACzJ,KAAKA,EAAE,WAAWA,EAAE,OAAO;IAC9B,GAAU,QAAQ;IAClB;GACF;GACA,IAAM4M,KAAO5M,EAAE,QAASA,EAAE,OAAQA,EAAE,SAC9B7M,IAAKoX,GAAOqC,GAAMtR,EAAQ,MAAM0E,EAAE,KAAK,GAAG,CAAE,EAAE,GAC9C6M,IAAWhF,EAAK,OAAO,sBAAsB;GACnD,IAAI,CAAC1U,KAAM,CAAC0Z,GAAU;IACpB,GAAU,QAAQ;IAClB;GACF;GACA,IAAM7c,IAAImD,EAAG,sBAAsB;GACnC,GAAU,QAAQ;IAChB,MAAMnD,EAAE,QAAQ6c,EAAS,OAAO;IAChC,KAAK7c,EAAE,SAAS6c,EAAS,MAAM;IAC/B,MAAMtT,EAAM,UAAUyG,EAAE,SAASA,EAAE,OAAOA,EAAE,MAAMA,EAAE,MAAM;GAC5D;EACF,GACM8M,WAAqB;GACzB,IAAIrN,EAAS,UAAU,UAAUgK,EAAS,OAAO;IAC/C,IAAMzJ,IAAIyJ,EAAS;IAInB,AAHIzJ,EAAE,WAAWA,EAAE,SAAOzG,EAAM,KAAKyG,EAAE,SAASA,EAAE,OAAOA,EAAE,MAAMA,EAAE,MAAM,GACzE,EAAS,QAAQ,MACjB,GAAU,QAAQ,MAClB+K,GAAY;GACd;GAGA,AAFA,EAAS,QAAQ,MACjB,qBAAqBsB,EAAS,GAC9B,KAAY;EACd;EAEA,AADAvD,SAAgB,SAAS,iBAAiB,WAAWgE,EAAY,CAAC,GAClEC,SAAsB;GAEpB,AADA,SAAS,oBAAoB,WAAWD,EAAY,GACpD,qBAAqBT,EAAS;EAChC,CAAC;EAED,IAAIW,KAAY,IACVC,MAAe,MAAkB;GACrC,IAAI,EAAE,WAAW,GAAG;GACpB,IAAMvB,IAAS,EAAE,QAGXwB,KADSrF,EAAK,OAAO,cAA2B,iBAAiB,EAAA,EACpD,sBAAsB;GACzC,IACEqF,KACA,EAAE,WAAWA,EAAG,OAAO,KACvB,EAAE,WAAWA,EAAG,QAAQ,KACxB,EAAE,WAAWA,EAAG,MAAM,KACtB,EAAE,WAAWA,EAAG,SAAS,GACzB;IACA,IAAM5D,IAAItB,EAAM,OAAO;IACvB,IAAI,CAACsB,GAAG;IAUR,AATA,EAAE,eAAe,GACjB/P,EAAM,KAAK,OAAO,GAClB,EAAS,QAAQ;KACf,SAAS+P,EAAE;KACX,OAAOA,EAAE;KACT,MAAM,CAACA,EAAE,gBAAgBA,EAAE,cAAc;KACzC,QAAQA,EAAE;IACZ,GACA,EAAS,QAAQ,QACjB,KAAU;KAAE,GAAG,EAAE;KAAS,GAAG,EAAE;IAAQ;IACvC;GACF;GACA,IAAM2C,IAAQP,EAAO,QAAqB,qBAAqB;GAC/D,IAAIA,EAAO,QAAQ,YAAY,KAAKO,KAAS,CAACtY,EAAM,UAAU;IAE5D,EAAE,eAAe;IACjB,IAAMlD,IAAI,OAAOwb,EAAM,QAAQ,KAAK,GAC9Bb,IAAO9P,EAAQ,OACf6R,IAAO,EAAE,YAAYH,MAAa,IAAIA,KAAYvc;IASxD,AARA,KAAY0c,GACZ5T,EAAM,KAAK,OAAO,GAClByO,EAAM,YAAY;KAChB,aAAaE,EAAMvU,EAAM,KAAKwZ,EAAK;KACnC,gBAAgB/B,EAAK,EAAE,CAAE;KACzB,YAAYlD,EAAMvU,EAAM,KAAKlD,EAAE;KAC/B,eAAe2a,EAAKA,EAAK,SAAS,EAAE,CAAE;IACxC,CAAC,GACDL,GAAY;IACZ;GACF;GACA,IAAMvP,IAAI0Q,GAAI,CAAC;GACf,AAAK1Q,MACL,KAAY,IACD,IAAM,KAAK,QAAQ,OACtB,UAAUA,EAAE,KAAK,UAAU,SAAS,YAAY,OAExDjC,EAAM,KAAK,OAAO,GACd5F,EAAM,QAERqU,EAAM,MAAME,EAAM1M,EAAE,GAAG,GAAGA,EAAE,QAAQ,KAGjChM,GAAcgM,EAAE,QAAQA,EAAE,IAAI,KAAG,EAAE,eAAe,GACvDwM,EAAM,aAAaE,EAAM1M,EAAE,GAAG,GAAGA,EAAE,QAAQ,CAAC,GAAG,CAAC,GAChD,EAAS,QAAQ,UACjB,KAAU;IAAE,GAAG,EAAE;IAAS,GAAG,EAAE;GAAQ,GACvCA,EAAE,KAAK,MAAM,EAAE,eAAe,GAAK,CAAC;EACtC,GACM4R,MAAe,MAAkB;GACrC,IAAI3N,EAAS,UAAU,QAAQ;GAC/B,IAAMjE,IAAI0Q,GAAI,CAAC;GACf,AAAI1Q,KAAGwM,EAAM,cAAcE,EAAM1M,EAAE,GAAG,GAAGA,EAAE,QAAQ,CAAC,GAAG,CAAC;EAC1D,GACM6R,MAAc,MAAkB;GACpC,IAAM7R,IAAI0Q,GAAI,CAAC;GACf,IAAI,CAAC1Q,KAAKhM,GAAcgM,EAAE,QAAQA,EAAE,IAAI,GAAG;GAC3C,IAAM7I,IAAMsW,GAAQ,MAAM,IAAIzN,EAAE,QAAQ;GACxC,AAAK7I,MAEDA,EAAI,SAAS,aAAa,CAACA,EAAI,SAC7B4G,EAAM,QAAQiC,EAAE,KAAK7I,CAAG,KAAG4G,EAAM,OAAOiC,EAAE,KAAK7I,CAAG,IAGxD4G,EAAM,KAAK,MAAMiC,EAAE,KAAK7I,GAAK,EAAE,QAAQ,GAAK,CAAC;EAC/C,GACM2a,MAAW,MAA8B;GAC7C,IAAMtN,IAAIyJ,EAAS;GACnB,IAAI,CAACzJ,KAAKA,EAAE,WAAWA,EAAE,OAAO,OAAO;GACvC,IAAMuN,IAAOvN,EAAE,SAASA,EAAE;GAG1B,QAFgBuN,IAAO9c,IAAIuP,EAAE,SAASvP,KAAKuP,EAAE,SAASvP,IAAIuP,EAAE,WAAWvP,KAAKuP,EAAE,UAEvE;IAAE,MAAMA,EAAE,KAAK;IAAI,IAAIA,EAAE,KAAK;IAAI,MAAMuN,IAAO9c,MAAMuP,EAAE,SAASvP,MAAMuP,EAAE,UAAU;GAAE,IADtE;EAEvB,GAGMwN,MAAwB,MAAkB;GAC9C,IAAMhS,IAAI0Q,GAAI,CAAC;GACf,IAAI,CAAC1Q,KAAK7H,EAAM,UAAU;IACxB,EAAE,gBAAgB;IAClB;GACF;GACA,IAAM2V,IAAItB,EAAM,OAAO,OACjBqD,IAAK/P,EAAQ,MAAM,WAAW,MAAMnL,EAAE,OAAOqL,EAAE,QAAQ;GAG7D,AADI8N,KAAK9N,EAAE,SAAS8N,EAAE,eAAe9N,EAAE,SAAS8N,EAAE,eAAe+B,KAAM/B,EAAE,kBAAkB+B,KAAM/B,EAAE,mBAEjG/P,EAAM,KAAK,OAAO,GAClByO,EAAM,MAAME,EAAM1M,EAAE,GAAG,GAAGA,EAAE,QAAQ,GACpCA,EAAE,KAAK,MAAM,EAAE,eAAe,GAAK,CAAC;EAExC,GAEMqQ,MAAc,MAAsB;GACxC,IAAM7b,IAAIO,EAAK,sBAAsB;GACrC,EAAK,cACH,IAAI,WAAW,eAAe;IAAE,SAAS;IAAM,YAAY;IAAM,SAASP,EAAE,OAAO;IAAG,SAASA,EAAE,SAAS;GAAE,CAAC,CAC/G;EACF,GACMyd,IAAWzZ,QAAe;GAC9B,IAAM1D,IAAMqD,EAAM,KAAKyV,GAAY;GACnC,OAAO9Y,IAAMiJ,EAAM,SAASjJ,CAAG,IAAI,KAAA;EACrC,CAAC,GACKod,MAAU,MAAe/Z,EAAM,MAAM,IAAIoM,CAAE,GAE3C4N,KAAU,MAA4B,OAAOhb,EAAI,QAAS,WAAWA,EAAI,OAAO,KAAA,GAEhFib,MAAW,MAAgD;GAC/D,IAAM9N,IAAM0B,EAAI,OAAO7N,EAAM,YAAY+T,EAAI,KAAK,EAAE,oBAAoB,EAAE,KAAKlG,EAAI,IAAI,OAAO,CAAC,IAAI,KAAA;GACnG,OAAOA,EAAI,IAAI,cAAc,GAAG1B,KAAO0B,EAAI,IAAI,OAAO,IAAIA,EAAI,IAAI,gBAAgB1B;EACpF,GACM+N,MAAU,GAA2B,MAA+B;GACxE,IAAMtd,IAAQoZ,EAAE,cAA8B;GAE9C,AADA5B,EAAO,SAASvG,EAAI,IAAIjR,EAAK,sBAAsB,CAAC,CAAC,KAAK,GAC1DiR,EAAI,OAAO,iBAAiB,CAAC,CAACmI,CAAC;EACjC,GACMmE,KAAgBpG,EAAI,KAAK,EAAE,gBAAgB,CAAC,CAAC,kBAAkBA,EAAI,MAAM;E,OAE/ED,EAAa;GAAE;GAAa,gBAAgB,MAAcoC,EAAY,MAAM,cAAcpZ,CAAC;EAAE,CAAC,I,UAI5FtG,EAAA,GAAAC,EA+IkBC,EAAA0jB,EAAA,GAAA,MAAA;GA9IhB,SAAAzjB,QA6IqB,CA7IrBC,EA6IqBF,EAAA2jB,EAAA,GAAA,EA7ID,YAAA,GAAQ,GAAA;IAC1B,SAAA1jB,QA2IM,CA3INE,EA2IM,OAAA;KA1IA,SAAA;KAAJ,KAAIqd;KACJ,OAAKpd,GAAA,CAAC,yBAAuB;MACY,qBAAA4f,GAAA;MAAwC,eAAAzW,EAAA;MAAkC,cAAAA,EAAA;MAAuC,cAAA6L,EAAA,UAAQ;MAAmC,YAAA7L,EAAA;;KAOrM,MAAK;KACJ,cAAYA,EAAA;KACZ,iBAAeA,EAAA,WAAQ,KAAQA,EAAA,KAAK;KACpC,iBAAe0H,EAAA,MAAQ,SAAU,IAAA;KACjC,aAAW1H,EAAA,WAAWA,EAAA,WAAQ,SAAY,KAAA;KAC1C,iBAAeA,EAAA,WAAQ,SAAY,KAAA;KACnC,gBAAcwU,EAAA;KACL;KACE;KACA;KACA;KACD;KACW;KACrB,QAAI,AAAAhT,EAAA,QAAA,MAAE0W,GAAUzW,GAAM,MAAA;KACtB,OAAG,AAAAD,EAAA,QAAA,MAAE0W,GAAUzW,GAAM,KAAA;KACrB,SAAK,AAAAD,EAAA,QAAA,MAAE0W,GAAUzW,GAAM,OAAA;;KAExB7K,EAqGM,OAAA;MArGG,SAAA;MAAJ,KAAIsd;MAAW,OAAM;MAA6B,iBAAAwC;K,IACrD9f,EA0DM,OA1DNnB,IA0DM;MAzDQuK,EAAA,Q,aAAZzJ,EAAA,GAAAO,EAEM,OAFNpB,IAEMqB,EADDN,EAAAqd,CAAA,CAAG,CAAC,KAAK,EAAC,eAAA,CAAA,GAAA,CAAA;OAEfvd,EAAA,EAAA,GAAAO,EAoDMG,GAAA,MAAAC,GAnDUwQ,EAAA,QAAP,OADTnR,EAAA,GAAAO,EAoDM,OAAA;OAlDH,KAAK8W,EAAI;OACV,OAAK/W,GAAA,CAAC,gBAAc,CACY,MAAAJ,EAAAwD,CAAA,CAAO,CAAC2T,EAAI,GAAG,K;QAAuD,cAAAnX,EAAA8E,CAAA,CAAa,CAACqS,EAAI,IAAI,IAAI;QAA+B,UAAAA,EAAI,OAAO5N,EAAA;QAAgD,mBAAA4N,EAAI,WAAM;QAA+C,eAAAA,EAAI;QAA0C,eAAAnX,EAAA0d,CAAA,CAAM,CAAC,SAAS,OAAO,OAAOvG,EAAI;;OAUlW,OAAKzW,GAAEyW,EAAI,WAAM,UAAA,EAAA,MAAA,OAA8BA,EAAI,UAAS,GAAA,IAAQ,KAAA,CAAS;OAC9E,MAAK;OACJ,aAA4BkM,GAAOlM,EAAI,EAAE,CAAA,EAAG,QAAG,QAAA,cAA2BkM,GAAOlM,EAAI,EAAE,CAAA,EAAG,QAAG,SAAA,eAA6B,KAAA;OAG1H,YAAUA,EAAI;;OAEDA,EAAI,OAAO5N,EAAA,aAAzBzJ,EAAA,GAAAC,EAAyFC,EAAAmY,EAAA,GAAA;;QAApD,MAAM;QAAI,OAAM;QAAe,eAAY;;OAChFhY,EAeS,UAAA;QAdP,MAAK;QACL,OAAM;QACN,UAAS;QACR,eAAaojB,GAAQpM,CAAG;QACxB,oBAAkBA,EAAI,IAAI,cAAW,GAAMnX,EAAAsd,CAAA,EAAG,QAASnG,EAAI,OAAO,KAAA;QAClE,UAAK,MAAEnX,EAAAkP,CAAA,CAAK,CAAC,KAAKiI,EAAI,IAAInM,EAAO,QAAQ;;QAE1C7K,EAAsD,QAAtDf,IAAsDkB,EAAxB6W,EAAI,IAAI,MAAM,GAAA,CAAA;QAChCA,EAAI,IAAI,YAApBrX,EAAA,GAAAO,EAA2F,QAAA;;SAA7D,OAAM;SAAoB,cAAYL,EAAAyjB,EAAA;QAAe,GAAA,KAAC,GAAApkB,EAAA,K;QACxEikB,EAAOnM,EAAI,GAAG,KAA1BrX,EAAA,GAAAO,EAA8E,QAA9Ef,IAA8EgB,EAAzBgjB,EAAOnM,EAAI,GAAG,CAAA,GAAA,CAAA,K;QACvDkM,GAAOlM,EAAI,EAAE,KAAzBrX,EAAA,GAAAO,EAGO,QAHPd,IAGO,CAFLW,EAA+EF,EAAA6jB,CAAA,GAAA;SAAnE,MAAM;SAAK,OAAKzjB,GAAA,EAAA,WAAeijB,GAAOlM,EAAI,EAAE,CAAA,CAAG,QAAG,OAAA,CAAA;Q,wBAClDkM,GAAOlM,EAAI,EAAE,CAAA,CAAG,SAA5BrX,EAAA,GAAAO,EAAgG,QAAhGb,IAAgGc,EAA/B+iB,GAAOlM,EAAI,EAAE,CAAA,CAAG,KAAK,GAAA,CAAA,K;;OAG9EA,EAAI,IAAI,eAApBrX,EAAA,GAAAO,EAEO,QAAA;;QAF2B,IAAE,GAAKL,EAAAsd,CAAA,EAAG,QAASnG,EAAI;QAAM,OAAM;OAChE,GAAA7W,EAAA6W,EAAI,IAAI,WAAW,GAAA,GAAA1X,EAAA,K;OAExB,AAAAsL,EAAA,OAAA5K,EAA+C,QAAA;QAAzC,OAAM;QAAc,eAAY;;OACtCA,EASO,QAAA;QARL,OAAM;QACN,eAAY;QACX,cAAS,MAAEqjB,GAAOrM,GAAKnM,CAAM;QACT,sBAAA,MAAAwY,GAAOrM,GAAKnM,CAAM;O,IAE3BhL,EAAA0d,CAAA,CAAM,CAAC,SAAS,OAAO,OAAOvG,EAAI,MAA9CrX,EAAA,GAAAO,EAEO,QAFPV,IAEOW,EADF,KAAK,MAAMN,EAAA0d,CAAA,CAAM,CAAC,SAAS,MAAO,IAAI,CAAA,IAAI,QAC/C,CAAA,K;;MAGJ,AAAA3S,EAAA,OAAA5K,EAAgF,OAAA;OAA3E,OAAM;OAA4B,MAAK;OAAe,eAAY;;K,IAEzEA,EAwCM,OAAA;MAxCD,OAAM;MAAU,MAAK;MAAgB,OAAKO,GAAA,EAAA,QAAA,GAAeqf,GAAA,MAAS,IAAA,CAAA;K,KACrEjgB,EAAA,EAAA,GAAAO,EAsCMG,GAAA,MAAAC,GArCWqf,GAAA,QAAR,OADThgB,EAAA,GAAAO,EAsCM,OAAA;MApCH,KAAK,OAAOyjB,EAAK,GAAG;MACrB,OAAM;MACL,cAAYA,EAAK;MACjB,OAAKpjB,GAAA,EAAA,WAAA,cAA6BojB,EAAK,QAAQzF,EAAA,MAAK,KAAA,CAAA;K,IAElC9U,EAAA,YAAnBzJ,EAAA,GAAAC,EAAuFC,EAAAW,CAAA,GAAA;;MAAzD,OAAOmjB,EAAK;MAAQ,SAAS7S,EAAA;MAAU,QAAM,CAAG1H,EAAA;;;;;K,OAC9EzJ,EAAA,GAAAC,EA6BEC,EAAAY,EAAA,GAAA;;MA3BC,KAAK2I,EAAA,KAAKua,EAAK;MACf,OAAOA,EAAK;MACZ,UAAQ9jB,EAAA4d,CAAA,CAAK,CAAC,QAAQ5d,EAAA6d,CAAA,CAAK,CAACtU,EAAA,KAAKua,EAAK,MAAK,CAAA;MAC3C,QAAM,CAAGva,EAAA;MACT,KAAKvJ,EAAAsd,CAAA;MACL,SAASrM,EAAA;MACT,KAAKhJ,GAAA;MACL,cAAYsB,EAAA;MACZ,MAAMvJ,EAAA4d,CAAA,CAAK,CAAC;MACZ,UAAU5d,EAAA4d,CAAA,CAAK,CAAC;MAChB,YAAU5d,EAAAkP,CAAA,CAAK,CAAC;MAChB,SAASlP,EAAA4d,CAAA,CAAK,CAAC;MACf,cAAY5d,EAAAkP,CAAA,CAAK,CAAC;MAClB,OAAOlP,EAAA4d,CAAA,CAAK,CAAC,SAAS5d,EAAA6d,CAAA,CAAK,CAACtU,EAAA,KAAKua,EAAK,MAAK,CAAA;MAC3C,QAAQ9jB,EAAA4d,CAAA,CAAK,CAAC,UAAU5d,EAAA6d,CAAA,CAAK,CAACtU,EAAA,KAAKua,EAAK,MAAK,CAAA;MAC7C,UAAQ9jB,EAAA4d,CAAA,CAAK,CAAC,MAAM5d,EAAA6d,CAAA,CAAK,CAACtU,EAAA,KAAKua,EAAK,MAAK,CAAA;MACzC,aAAW9jB,EAAA4d,CAAA,CAAK,CAAC,SAAS5d,EAAA6d,CAAA,CAAK,CAACtU,EAAA,KAAKua,EAAK,MAAK,CAAA;MAC/C,aAAW9jB,EAAA4d,CAAA,CAAK,CAAC,SAAS5d,EAAA6d,CAAA,CAAK,CAACtU,EAAA,KAAKua,EAAK,MAAK,CAAA;MAC/C,QAAQ/E,GAAA,UAAgB+E,EAAK,QAAQ9jB,EAAA8e,EAAA,CAAM,CAAE,WAAQ;MACrD,WAAWI,EAAa4E,EAAK,KAAK;MAClC,aAAW3E,GAAU2E,EAAK,KAAK;MAC/B,MAAMb,GAAQa,EAAK,KAAK;MACxB,OAAOvE,EAASuE,EAAK,KAAK;MAC1B,SAASzE,EAAWyE,EAAK,KAAK;MAC9B,aAAWA,EAAK,UAAK;MACrB,aAAU,AAAA/Y,EAAA,QAAG,MAAM/K,EAAAkP,CAAA,CAAK,CAAC,KAAK,SAAS1G,CAAC;MACxC,kBAAiB,GAAK,MAAMxI,EAAAkP,CAAA,CAAK,CAAC,cAAc3F,EAAA,KAAKua,EAAK,QAAQxb,GAAKE,CAAC;;KAMzEsZ,GAAA,SADRhiB,EAAA,GAAAO,EAOM,OAAA;;MALJ,OAAM;MACN,MAAK;MACJ,OAAKK,GAAA;OAAA,MAAA,GAAaohB,GAAA,MAAU,KAAI;OAAA,KAAA,GAAcA,GAAA,MAAU,IAAG;MAAA,CAAA;KAEzD,GAAAxhB,EAAAwhB,GAAA,MAAU,IAAI,GAAA,CAAA,K;KAERhjB,EAAAA,OAAO,SAAK,CAAKyK,EAAA,YAAYA,EAAA,KAAK,WAAM,KAAnDzJ,EAAA,GAAAO,EAA4G,OAA5GR,IAA4G,CAA3BgB,GAAqBkjB,EAAA,QAAA,OAAA,C;KACtG7jB,EAA+FY,IAAA;MAAnF,OAAOd,EAAAkP,CAAA;MAAQ,QAAQ3F,EAAA;MAAS,MAAM6Z,EAAA;MAAW,aAAW7Z,EAAA,YAAYA,EAAA;;;;;;;;;;;;;;;;AE7xB5F,SAAgB0a,GAAoC,GAA6B;CAC/E,IAAMC,IAAUzP,EAAkC,IAAI;CA8BtD,OAAO;EAAE;EAAS,QA3BH,GAAU,GAAqB,MAAyD;GAGrG,IAFI,CAAC3N,EAAE,QAAQb,GAAKqC,CAAG,KAEnBA,EAAI,SAAS,aAAa,CAACA,EAAI,QAAQ,OAAO;GAElD,IAAI6b,EAAK,YAAY,KAAA,KAAa,CAAC7b,EAAI,UAAUA,EAAI,SAAS,eAE5D,OADA,EAAQ,QAAQ;IAAE;IAAK;IAAK,OAAOxB,EAAE,MAAM,KAAKb,GAAKqC,CAAG;IAAG,QAAQ6b,EAAK;IAAQ,MAAMA,EAAK;GAAQ,GAC5F;GAET,IAAMzb,IAAQyb,EAAK,YAAY,KAAA,IAAyCrd,EAAE,MAAM,KAAKb,GAAKqC,CAAG,IAAlDxB,EAAE,MAAMwB,GAAK6b,EAAK,OAAO;GAEpE,OADA,EAAQ,QAAQ;IAAE;IAAK;IAAK;IAAO,QAAQA,EAAK;IAAQ,MAAMA,EAAK;GAAQ,GACpE;EACT;EAeyB,WAdP,GAAgB,GAAe,MAAqB;GACpE,IAAM7E,IAAI4E,EAAQ;GAClB,AAAI5E,MAAG,EAAQ,QAAQ;IAAE,GAAGA;IAAG;IAAO;IAAM,QAAQ8E,KAAU9E,EAAE;GAAO;EACzE;EAWmC,cAVL;GAC5B,IAAMA,IAAI4E,EAAQ;GAIlB,OAHK5E,KACL,EAAQ,QAAQ,MAChBxY,EAAE,MAAM,IAAIwY,EAAE,KAAKA,EAAE,KAAKA,EAAE,UAAU,KAAK,OAAOA,EAAE,KAAK,GAClD,MAHQ;EAIjB;EAI2C,cAHtB;GACnB,EAAQ,QAAQ;EAClB;CACkD;AACpD;;;ACDA,IAAM+E,KAAU,KAGVC,MAAQ,GAAY,MACvBrgB,EAAa4b,CAAC,KAAK5b,EAAagb,CAAC,KAClC,OAAO,GAAGY,GAAGZ,CAAC,KACb,MAAM,QAAQY,CAAC,KAAK,MAAM,QAAQZ,CAAC,KAAKY,EAAE,WAAWZ,EAAE,UAAUY,EAAE,OAAO,GAAG,MAAM,OAAO,GAAG0E,GAAGtF,EAAE7Y,EAAE,CAAC;AAExG,SAASoe,GAAQ,GAA8B,GAAc,GAAgB;CAC3E,IAAMnO,IAAOoO,EAAK,MAAM,GAAG,GACvB3d,IAAI4d;CACR,KAAK,IAAMpO,KAAKD,EAAK,MAAM,GAAG,EAAE,GAAG;EACjC,IAAMsO,IAAO7d,EAAEwP;EAEf,AADA,EAAEA,KAAKqO,KAAQ,OAAOA,KAAS,WAAW,EAAE,GAAIA,EAAgB,IAAI,CAAC,GACrE,IAAI7d,EAAEwP;CACR;CACA,EAAED,EAAKA,EAAK,SAAS,MAAO3N;AAC9B;AAEA,IAAMkc,MAAQ,GAAW,MAAmBpf,EAAE,KAAK,CAAC,CAAC,kBAAkB0B,CAAM,CAAC,CAAC,QAAQ,SAAS,GAAG;AAEnG,SAAS2d,GAAQ,GAAsB,GAAe,GAAuC;CAC3F,IAAMrc,IAAIoc,GAAKlc,GAAOxB,CAAM;CAC5B,IAAI,CAACsB,GAAG;CACR,IAAMsc,KAAQ,GAAW,MAAsB;EAC7C,IAAMhd,IAAI,MAAM,KAAK,EAAE,QAAQmX,EAAE,SAAS,EAAE,IAAI,GAAG,MAAM7Y,CAAC;EAC1D,KAAK,IAAIA,IAAI,GAAGA,KAAKyZ,EAAE,QAAQ,KAAK;GAClC,IAAIkF,IAAOjd,EAAE;GACb,EAAE,KAAK1B;GACP,KAAK,IAAIiL,IAAI,GAAGA,KAAK4N,EAAE,QAAQ,KAAK;IAClC,IAAM+F,IAAMld,EAAEuJ;IAEd,AADA,EAAEA,KAAK,KAAK,IAAIvJ,EAAEuJ,KAAM,GAAGvJ,EAAEuJ,IAAI,KAAM,GAAG0T,KAAQlF,EAAEzZ,IAAI,OAAO6Y,EAAE5N,IAAI,KAAK,IAAI,EAAE,GAChF,IAAO2T;GACT;EACF;EACA,OAAOld,EAAEmX,EAAE;CACb;CACA,OACElY,EAAQ,MAAM,MAAM6d,GAAK9d,EAAE,OAAOI,CAAM,CAAC,CAAC,WAAWsB,CAAC,KAAKA,EAAE,WAAWoc,GAAK9d,EAAE,OAAOI,CAAM,CAAC,CAAC,KAC9FH,EAAQ,MAAM,MAAM+d,EAAKF,GAAK9d,EAAE,OAAOI,CAAM,GAAGsB,CAAC,KAAK,CAAC;AAE3D;AAEA,SAAgByc,GAAkC,GAA2B;CAC3E,IAAM,IAAIne,EAAE,KAAK,GACXoe,IAAOvb,QAAewb,EAAQre,EAAE,OAAO,CAAC,GACxC8X,IAAUjV,QAAe,IAAI,IAAIub,EAAK,MAAM,KAAK,MAAM,CAACpd,EAAE,IAAcA,CAAC,CAAC,CAAC,CAAC,GAC5EmN,UAAekQ,EAAQre,EAAE,SAAS,GAClCse,IAAQC,kBAAgB,IAAI,IAAkC,CAAC,GAC/DC,IAASD,kBAAgB,IAAI,IAAgC,CAAC,GAE9DE,IAAeF,kBAAgB,IAAI,IAAiC,CAAC,GACrEG,IAAYH,kBAAgB,IAAI,IAAoB,CAAC,GAErDpV,IAAOoV,kBAAgB,IAAI,IAAiD,CAAC,GAC7EI,IAAQhR,EAA8D,CAAC,CAAC,GACxEiR,IAAUL,kBAAgB,IAAI,IAAY,CAAC,GAC3CM,IAAYN,kBAAgB,IAAI,IAAsB,CAAC,GAEvDO,IAAUnR,EAAW,CAAC,GACtBoR,IAAoB,CAAC,GACrBC,IAAoB,CAAC,GACrBC,IAAUtR,EAAW,EAAK,GAC1BuR,IAAUvR,EAAW,EAAK,GAC5BwR,KAAa,GAEXpI,KAAS,MAAqB,OAAO/Z,EAASmC,GAAKkf,EAAQre,EAAE,MAAM,CAAC,CAAC,GAErEof,IAAQvc,QACZ8b,EAAM,MAAM,SAAS,CAAC,GAAGN,EAAQre,EAAE,IAAI,GAAG,GAAG2e,EAAM,MAAM,KAAK,MAAM5F,EAAE,GAAG,CAAC,IAAIsF,EAAQre,EAAE,IAAI,CAC9F,GACMqf,KAAaxc,QAAe;EAChC,IAAM9B,oBAAI,IAAI,IAAoB;EAElC,OADAqe,EAAM,MAAM,SAAS,GAAG,MAAMre,EAAE,IAAIgW,EAAMlY,CAAC,GAAGS,CAAC,CAAC,GACzCyB;CACT,CAAC,GAEKue,KAAUzc,QACd+b,EAAQ,OAAOQ,EAAM,MAAM,QAAQ,MAAM,CAACR,EAAQ,IAAI7H,EAAMlY,CAAC,CAAC,CAAC,IAAIugB,EAAM,KAC3E,GACMG,IAAQ1c,QAAe;EAC3B,IAAM9B,oBAAI,IAAI,IAAiB;EAC/B,KAAK,IAAMlC,KAAKugB,EAAM,OAAO,EAAE,IAAIrI,EAAMlY,CAAC,GAAGA,CAAC;EAC9C,OAAOkC;CACT,CAAC,GACKye,IAAa3c,QAAe,IAAI,IAAI8b,EAAM,MAAM,KAAK,MAAM,CAAC5F,EAAE,KAAKA,CAAC,CAAC,CAAC,CAAC,GAEvE0G,MAAS,MAAgB,CAAC,CAACD,EAAW,MAAM,IAAI7Q,CAAG,KAAK,CAAC6Q,EAAW,MAAM,IAAI7Q,CAAG,CAAC,CAAE,OACpF+Q,KAAW,OAAiBL,GAAW,MAAM,IAAI1Q,CAAG,KAAK,MAAM,GAE/DgR,MAAY,GAAU,MAAiC;EAC3D,IAAMhR,IAAMoI,EAAM5X,CAAG,GACfgZ,IAAIhP,EAAK,IAAIwF,CAAG;EACtB,IAAIwJ,GAAG,OAAO3W,EAAI,WAAWA,EAAI,SAAS2W,EAAE,GAAG,IAAInb,EAASmb,EAAE,KAAK3W,EAAI,EAAY;EACnF,IAAI,IAAMmN,CAAG,GACb,OAAOnN,EAAI,WAAWA,EAAI,SAASrC,CAAG,IAAInC,EAASmC,GAAKqC,EAAI,EAAY;CAC1E,GACMoe,MAAY,GAAwC,GAAU,MAAiC;EACnG,IAAM5e,IAAIyO,EAAI,IAAIsH,EAAM5X,CAAG,CAAC,GACtByP,IAAKpN,EAAI;EACf,OAAOR,GAAG,IAAI4N,CAAE,IAAI5N,EAAE,IAAI4N,CAAE,IAAI+Q,GAASxgB,GAAKqC,CAAG;CACnD,GACMqe,MAAQ,GAAU,MAAiCD,GAAStB,GAAOnf,GAAKqC,CAAG,GAE3Ese,MAAiB,GAAU,MAAiCF,GAASG,GAAMzB,CAAK,GAAGnf,GAAKqC,CAAG,GAE3Fwe,KAAW,MAAkB;EACjC,IAAMrR,IAAMoI,EAAM5X,CAAG,GACfgZ,IAAIhP,EAAK,IAAIwF,CAAG,GAChB3N,IAAIsd,EAAM,IAAI3P,CAAG;EACvB,IAAI,CAACwJ,KAAK,CAACnX,GAAG,MAAM,OAAO7B;EAC3B,IAAMye,IAAM;GAAE,GAAGze;GAAK,GAAIgZ,GAAG;EAAe;EAC5C,KAAK,IAAM,CAAC9H,GAAK3O,MAAMV,KAAK,CAAC,GAAG,GAAQ4c,GAAKvN,GAAK3O,CAAC;EACnD,OAAOkc;CACT,GAGMqC,KAAWpd,QAAe;EAC9B,EAAa;EACb,IAAM9B,oBAAI,IAAI,IAAyB,GACjCS,IAAMsW,EAAQ,MAAM,IAAI3J,EAAO,CAAC;EACtC,IAAI,CAAC3M,GAAK,OAAOT;EACjB,KAAK,IAAM5B,KAAOmgB,GAAQ,OAAO;GAC/B,IAAM5d,IAAIoe,GAAc3gB,GAAKqC,CAAG;GAChC,IAAIrE,EAAauE,CAAC,GAAG;GACrB,IAAM8N,IAAI,OAAO9N,CAAC,GACdwe,IAAMnf,EAAE,IAAIyO,CAAC;GAEjB,AADK0Q,KAAKnf,EAAE,IAAIyO,GAAI,oBAAM,IAAI,IAAI,CAAE,GACpC0Q,EAAI,IAAInJ,EAAM5X,CAAG,CAAC;EACpB;EACA,OAAO4B;CACT,CAAC,GAEKof,KAAa,GAAqB,MAAiC;EACvE,IAAIhjB,EAAayE,CAAK,GAAG,OAAO;EAChC,IAAMwe,KAAS,GAAiB,OAAgC;GAAE,OAAO;GAAS;GAAS;EAAQ;EACnG,KAAK7jB,EAAWiF,EAAI,KAAK,CAAC,WAAWA,EAAI,SAAS,WAAW,OAAOI,KAAU,UAC5E,OAAOwe,EACL,OAAOxe,KAAU,YAAYA,EAAM,KAAK,CAAC,CAAC,WAAW,GAAG,IAAI,EAAE,kBAAkB,IAAI,EAAE,kBAAkB,CAC1G;EACF,KAAKJ,EAAI,SAAS,UAAUA,EAAI,SAAS,eAAe,OAAO,MAAMhE,EAAOoE,CAAe,CAAC,CAAC,QAAQ,CAAC,GACpG,OAAOwe,EAAM,EAAE,gBAAgB,CAAC;EAClC,IAAI5e,EAAI,SAAS,aAAa,OAAOI,KAAU,WAC7C,OAAOwe,EAAM,EAAE,qBAAqB,EAAE,OAAO,OAAOxe,CAAK,EAAE,CAAC,CAAC;EAC/D,IAAIJ,EAAI,SAAS,YAAY,CAACA,EAAI,QAAQ,MAAM,MAAQrB,EAAI,UAAUyB,CAAK,GACzE,OAAOwe,EAAM,EAAE,qBAAqB,EAAE,OAAO,OAAOxe,CAAK,EAAE,CAAC,GAAGmc,GAAQvc,EAAI,SAAS,OAAOI,CAAK,GAAG5B,EAAE,MAAM,CAAC;EAC9G,IAAIwB,EAAI,SAAS,eAAe;GAC9B,IAAM6e,KAAO,MAAM,QAAQze,CAAK,IAAIA,IAAQ,CAACA,CAAK,EAAA,CAAG,MAAM,MAAM,CAACJ,EAAI,QAAQ,MAAM,MAAQrB,EAAI,UAAUuB,CAAC,CAAC;GAC5G,IAAI2e,MAAQ,KAAA,GAAW,OAAOD,EAAM,EAAE,qBAAqB,EAAE,OAAO,OAAOC,CAAG,EAAE,CAAC,CAAC;EACpF;EACA,OAAO;CACT,GAEMC,KAAe,GAAqB,GAAgB,MAAuD;EAE/G,IADK9e,EAAI,SAAS,YAAYA,EAAI,SAAS,iBAAkB,CAACA,EAAI,iBAC9DrE,EAAayE,CAAK,KAAK4b,GAAK5b,GAAO2U,EAAI,QAAQ,GAAG,OAAO;EAC7D,IAAM,EAAE,YAAS,qBAAkB/U,GAC7B6e,KAAO,MAAM,QAAQze,CAAK,IAAIA,IAAQ,CAACA,CAAK,EAAA,CAAG,MAAM,MAAM;GAC/D,IAAMzB,IAAMF,EAAQ,MAAM,MAAMD,EAAE,UAAU0B,CAAC;GAC7C,OAAOvB,KAAO,CAACogB,EAAcpgB,GAAKoW,EAAI,GAAG;EAC3C,CAAC;EACD,OAAO8J,MAAQ,KAAA,IACX,OACA;GAAE,OAAO;GAAS,SAAS,EAAE,qBAAqB,EAAE,OAAO1jB,EAAYsD,GAASogB,CAAG,EAAE,CAAC;EAAE;CAC9F,GACMG,KAAkB,GAAa,MAAiC;EACpE,IAAIrjB,EAAayE,CAAK,GAAG,OAAO;EAChC,IAAM6e,IAASR,GAAS,MAAM,IAAI,OAAOre,CAAK,CAAC;EAC/C,IAAI,CAAC6e,KAAUA,EAAO,OAAO,GAAG,OAAO;EACvC,IAAMC,IAAQ,CAAC,GAAGD,CAAM,CAAC,CAAC,MAAM,MAAMjR,MAAMb,CAAG;EAC/C,OAAO+R,IACH;GAAE,OAAO;GAAS,SAAS,EAAE,sBAAsB;IAAE,KAAK,OAAO9e,CAAK;IAAG,KAAK8d,EAAQgB,CAAK;GAAE,CAAC;EAAE,IAChG;CACN,GACMC,KAAe,MAAa;EAChC,IAAMhS,IAAMoI,EAAM5X,CAAG,GACfyhB,IAAWnB,GAAM9Q,CAAG,GACpBkS,IAAMb,EAAQ7gB,CAAG,GACjBsQ,oBAAM,IAAI,IAAmB;EACnC,KAAK,IAAMjO,KAAO4c,EAAK,OAAO;GAC5B,IAAMxc,IAAQie,GAAK1gB,GAAKqC,CAAG,GACrB+U,IAAM;IAAE,KAAKsK;IAAK,OAAOD;IAAU,UAAUjB,GAASxgB,GAAKqC,CAAG;GAAE,GAChEgT,IAAQhT,EAAI,OAAO2M,EAAO,GAC1B2S,IAAWtf,EAAI,YAAaof,KAAYpM,GACxCR,IACJmM,EAAU3e,GAAKI,CAAK,KACpB0e,EAAY9e,GAAKI,GAAO2U,CAAG,MAC1BuK,KAAY3jB,EAAayE,CAAK,IAAI;IAAE,OAAO;IAAkB,SAAS,EAAE,gBAAgB;GAAE,IAAI,UAE9F4S,MAAUoM,KAAYjC,EAAM,MAAM,UAAU6B,EAAe7R,GAAK/M,CAAK,IAAI,gBACnE;IACL,IAAMmf,IAAMvf,EAAI,WAAWI,GAAO2U,CAAG;IACrC,IAAIwK,GAAK,OAAO;KAAE,OAAO;KAAkB,SAASA;IAAI;IACxD,IAAMC,IAAOxf,EAAI,OAAOI,GAAO2U,CAAG;IAClC,OAAOyK,IAAO;KAAE,OAAO;KAAoB,SAASA;IAAK,IAAI;GAC/D,EAAA,CAAG;GACL,AAAIhN,KAAOvE,EAAI,IAAIjO,EAAI,IAAcwS,CAAK;EAC5C;EACA,AAAIvE,EAAI,OAAM+O,EAAO,IAAI7P,GAAKc,CAAG,IAC5B+O,EAAO,OAAO7P,CAAG;CACxB,GAEMsS,KAAkB,MAAsB;EAC5C,KAAK,IAAMvf,KAAK2G,GACd,IAAI,GAAa3G,CAAC,GAClB,KAAK,IAAM8N,KAAKyQ,GAAS,MAAM,IAAI,OAAOve,CAAC,CAAC,KAAK,CAAC,GAAG;GACnD,IAAMvC,IAAMogB,EAAM,MAAM,IAAI/P,CAAC;GAC7B,AAAIrQ,KAAKwhB,EAAYxhB,CAAG;EAC1B;CAEJ,GAGM+hB,MAAS,MAAyC;EACtD,IAAMC,IAAmB,CAAC,GACpBC,oBAAU,IAAI,IAAqD,GACnEC,IAAuB,CAAC;EAC9B,KAAK,IAAMriB,KAAKsiB,GAAS;GACvB,IAAM3S,IAAMoI,EAAM/X,EAAE,GAAG,GACjB4P,IAAK5P,EAAE,IAAI,IACXuiB,IAAS1B,GAAK7gB,EAAE,KAAKA,EAAE,GAAG;GAChC,IAAIwe,GAAK+D,GAAQviB,EAAE,KAAK,GAAG;GAC3B,IAAIwiB,IAAQJ,EAAQ,IAAIzS,CAAG;GAK3B,AAJK6S,KAAOJ,EAAQ,IAAIzS,GAAM,IAAQ;IAAE,KAAK3P,EAAE;IAAK,KAAK,IAAI,IAAIsf,EAAM,IAAI3P,CAAG,CAAC;GAAE,CAAE,GAC/E6O,GAAKxe,EAAE,OAAO2gB,GAAS3gB,EAAE,KAAKA,EAAE,GAAG,CAAC,IAAGwiB,EAAM,IAAI,OAAO5S,CAAE,IACzD4S,EAAM,IAAI,IAAI5S,GAAI5P,EAAE,KAAK,GAC9BmiB,EAAQ,KAAK;IAAE;IAAK,KAAKvS;IAAI;IAAQ,OAAO5P,EAAE;GAAM,CAAC,GACjD4P,MAAOT,EAAO,KAAGkT,EAAU,KAAKE,GAAQviB,EAAE,KAAK;GAEnD,IAAMyiB,IAAKhD,EAAa,IAAI9P,CAAG;GAC/B,IAAI8S,GAAI,IAAI7S,CAAE,GAAG;IACf,IAAMiP,IAAO,IAAI,IAAI4D,CAAE;IAEvB,AADA5D,EAAK,OAAOjP,CAAE,GACViP,EAAK,OAAMY,EAAa,IAAI9P,GAAKkP,CAAI,IACpCY,EAAa,OAAO9P,CAAG;GAC9B;GACA,EAAU,OAAOA,CAAG;EACtB;EACA,KAAK,IAAM,CAACA,GAAK,EAAE,aAAUyS,GAC3B,AAAI3R,EAAI,OAAM6O,EAAM,IAAI3P,GAAKc,CAAG,IAC3B6O,EAAM,OAAO3P,CAAG;EAEvB,AAAIwS,EAAQ,UAAQ,EAAQ;EAC5B,KAAK,IAAM,EAAE,QAAK,YAASC,EAAQ,OAAO,GACxC,AAAI3R,EAAI,QAAQgQ,GAAM1I,EAAM5X,CAAG,CAAC,IAAGwhB,EAAYxhB,CAAG,IAC7Cqf,EAAO,OAAOzH,EAAM5X,CAAG,CAAC;EAG/B,OADIkiB,EAAU,UAAQJ,EAAeI,CAAS,GACvCF;CACT,GACMO,UAAoB;EAExB,AADA,EAAQ,QAAQ3C,EAAU,SAAS,GACnC,EAAQ,QAAQC,EAAU,SAAS;CACrC,GACM2C,KAAU,MAAe;EAI7B,AAHA5C,EAAU,KAAK7V,CAAI,GACf6V,EAAU,SAASxB,MAASwB,EAAU,MAAM,GAChD,EAAU,SAAS,GACnB2C,EAAY;CACd,GAGMlR,KAAS,GAA6B,IAA8C,CAAC,MAAe;EACxG,IAAM2Q,IAAUD,GAAMI,CAAO;EAE7B,QADIH,EAAQ,UAAUS,EAAU,WAAQD,EAAO;GAAE;GAAS,OAAOC,EAAU,SAASA,IAAY,KAAA;EAAU,CAAC,GACpGT;CACT,GACMjB,KAAO,GAAU,GAAqB,MAAmB1P,EAAM,CAAC;EAAE;EAAK;EAAK;CAAM,CAAC,CAAC,GAGpFqR,KAAW,MAAoD;EACnE,IAAM3iB,IAAO,MAAM,KAAK,EAAE,QAAQ8J,EAAM,SAAS;GAC/C,IAAM2F,IAAM,OAAO,EAAEwQ,MACfhgB,IAAM,CAAC;GAEb,OADAue,GAAQve,GAAKkf,EAAQre,EAAE,MAAM,GAAG2O,CAAG,GAC5B;IAAE;IAAU;GAAW;EAChC,CAAC;EAED,AADA,EAAM,QAAQ,CAAC,GAAGgQ,EAAM,OAAO,GAAGzf,CAAI,GACtC,EAAQ;EACR,KAAK,IAAML,KAAKK,GAEd,AADA2f,EAAU,IAAIhgB,EAAE,KAAK,KAAK,GAC1B8hB,EAAY9hB,EAAE,GAAG;EAEnB,OAAOK;CACT,GACM4iB,MAAa,MAAmB;EACpC,IAAMC,IAAO,IAAI,IAAIxS,CAAI;EACzB,EAAM,QAAQoP,EAAM,MAAM,QAAQ,MAAM,CAACoD,EAAK,IAAIhJ,EAAE,GAAG,CAAC;EACxD,KAAK,IAAMvJ,KAAKD,GAId,AAHA+O,EAAM,OAAO9O,CAAC,GACdgP,EAAO,OAAOhP,CAAC,GACfqP,EAAU,OAAOrP,CAAC,GAClBrG,EAAK,OAAOqG,CAAC;EAEf,EAAQ;CACV,GAEMwS,MAAc,MAAmB;EACrC,IAAMzU,IAASuK,EAAQ,MAAM,IAAI3J,EAAO,CAAC,GACnC9F,IAASkF,IAASgC,EAAK,KAAK,MAAMgQ,EAAM,MAAM,IAAI/P,CAAC,CAAC,CAAC,CAAC,KAAK,MAAO3Q,IAAIghB,GAAKhhB,GAAG0O,CAAM,IAAI,IAAK,IAAI,CAAC;EACxG,KAAK,IAAMiC,KAAKD,GAAM,EAAQ,IAAIC,CAAC;EAGnC,AAFA,EAAQ,SACRmS,EAAO;GAAE,SAAS,CAAC;GAAG,SAASpS;EAAK,CAAC,GACrC0R,EAAe5Y,CAAM;CACvB,GACM4Z,MAAe,MAAmB;EACtC,KAAK,IAAMzS,KAAKD,GAAM,EAAQ,OAAOC,CAAC;EACtC,EAAQ;EACR,IAAMjC,IAASuK,EAAQ,MAAM,IAAI3J,EAAO,CAAC;EACzC,AAAIZ,KAAQ0T,EAAe1R,EAAK,KAAK,MAAMgQ,EAAM,MAAM,IAAI/P,CAAC,CAAC,CAAC,CAAC,KAAK,MAAO3Q,IAAIghB,GAAKhhB,GAAG0O,CAAM,IAAI,IAAK,CAAC;CACzG,GAEM2U,MAAU,GAAY,MAAyB;EAEnD,IADI7Y,MAAQ,UAAUH,EAAK,SAAO4Y,GAAU5Y,EAAK,MAAM,KAAK,MAAM6P,EAAE,GAAG,CAAC,GACpE1P,MAAQ,UAAUH,EAAK,OAAO;GAChC,EAAM,QAAQ,CAAC,GAAGyV,EAAM,OAAO,GAAIzV,EAAK,KAA0C;GAClF,KAAK,IAAM6P,KAAK7P,EAAK,OAAO,EAAU,IAAI6P,EAAE,KAAK,KAAK;GACtD,EAAQ;EACV;EACA,IAAI7P,EAAK,SAAS;GAChB,IAAIG,MAAQ,QAAQ,GAAYH,EAAK,OAAO;QACvC;IACH,KAAK,IAAMsG,KAAKtG,EAAK,SAAS,EAAQ,IAAIsG,CAAC;IAC3C,EAAQ;GACV;EACF;EACA,IAAM8R,IAA8B,CAAC;EACrC,KAAK,IAAMhhB,KAAK4I,EAAK,SAAS;GAC5B,IAAM/J,IAAMogB,EAAM,MAAM,IAAIjf,EAAE,GAAG,GAC3BkB,IAAMsW,EAAQ,MAAM,IAAIxX,EAAE,GAAG;GACnC,AAAInB,KAAOqC,KAAK8f,EAAQ,KAAK;IAAE;IAAK;IAAK,OAAOjY,MAAQ,SAAS/I,EAAE,SAASA,EAAE;GAAM,CAAC;EACvF;EAEA,IADA4gB,GAAMI,CAAO,GACTjY,MAAQ,UAAUH,EAAK,OAAO,KAAK,IAAM6P,KAAK7P,EAAK,OAAO,EAAY6P,EAAE,GAAU;CACxF,GACMoJ,WAA0B;EAC9B,IAAMjZ,IAAO6V,EAAU,IAAI;EAK3B,OAJK7V,KACLgZ,GAAOhZ,GAAM,MAAM,GACnB8V,EAAU,KAAK9V,CAAI,GACnBwY,EAAY,GACLxY,KAJW;CAKpB,GACMkZ,WAA0B;EAC9B,IAAMlZ,IAAO8V,EAAU,IAAI;EAK3B,OAJK9V,KACLgZ,GAAOhZ,GAAM,MAAM,GACnB6V,EAAU,KAAK7V,CAAI,GACnBwY,EAAY,GACLxY,KAJW;CAKpB,GACMmZ,WAAqB;EAGzB,AAFA,EAAU,SAAS,GACnB,EAAU,SAAS,GACnBX,EAAY;CACd,GAEMY,KAAY,MAAgBhE,EAAM,IAAI3P,CAAG,GAEzC4T,MAAa,MAAgD;EACjE,IAAMC,IAAShE,EAAO,IAAI7P,CAAG,GACvBoB,IAAS0O,EAAa,IAAI9P,CAAG;EACnC,IAAI,CAACoB,GAAQ,OAAOyS;EACpB,IAAMC,IAAS,IAAI,IAAID,CAAM;EAC7B,KAAK,IAAM,CAACnS,GAAKqS,MAAY3S,GAC3B,AAAK0S,EAAO,IAAIpS,CAAG,KAAGoS,EAAO,IAAIpS,GAAK;GAAE,OAAO;GAAS;GAAS,QAAQ;EAAK,CAAC;EACjF,OAAOoS;CACT,GACME,KAAY,MAAgBjE,EAAU,IAAI/P,CAAG,GAC7CoG,MAAY,MAAyB;EACzC,IAAI0J,EAAa,IAAI9P,CAAG,KAAK+P,EAAU,IAAI/P,CAAG,GAAG,OAAO;EACxD,IAAM5N,IAAIyd,EAAO,IAAI7P,CAAG;EACxB,IAAI,CAAC5N,GAAG,OAAO;EACf,KAAK,IAAMzB,KAAKyB,EAAE,OAAO,GAAG,IAAIzB,EAAE,UAAU,SAAS,OAAO;EAC5D,OAAO;CACT,GACMsjB,MAAY,MAAsC/D,EAAU,IAAIlQ,CAAG,GACnEkU,KAAe,GAAa,MAAoB;EACpD,AAAIrD,EAAW,MAAM,IAAI7Q,CAAG,KAAGkQ,EAAU,IAAIlQ,GAAKmU,CAAK;CACzD,GAEMC,MAAW,GAAa,MAAa;EAEzC,AADA5Z,EAAK,IAAIwF,GAAK;GAAE;GAAK,MAAM8Q,GAAM9Q,CAAG,IAAI,KAAA,IAAY4Q,EAAM,MAAM,IAAI5Q,CAAG;EAAE,CAAC,GAC1E,EAAQ;EACR,IAAM9P,IAAI0gB,EAAM,MAAM,IAAI5Q,CAAG;EAC7B,IAAI9P,GAAG;GAEL,IAAMmC,IAAIsd,EAAM,IAAI3P,CAAG;GACvB,IAAI3N,GAAG;IACL,IAAM6c,IAAO,IAAI,IAAI7c,CAAC;IACtB,KAAK,IAAM,CAACqP,GAAK3O,MAAMV,GAAG;KACxB,IAAMQ,IAAMsW,EAAQ,MAAM,IAAIzH,CAAG;KACjC,AAAI7O,KAAOgc,GAAK9b,GAAGie,GAAS9gB,GAAG2C,CAAG,CAAC,KAAGqc,EAAK,OAAOxN,CAAG;IACvD;IACA,AAAIwN,EAAK,OAAMS,EAAM,IAAI3P,GAAKkP,CAAI,IAC7BS,EAAM,OAAO3P,CAAG;GACvB;GACA,EAAY9P,CAAC;EACf;CACF,GAEMmkB,IAASngB,QAAe;EAC5B,IAAIogB,IAAe,GACbC,oBAAc,IAAI,IAAY;EACpC,KAAK,IAAM,CAAC1T,GAAGzO,MAAMud,GACnB,AAAIM,EAAQ,IAAIpP,CAAC,MACjB,KAAgBzO,EAAE,MAClBmiB,EAAY,IAAI1T,CAAC;EAEnB,IAAI2T,IAAY,GACZC,IAAc,GACZC,oBAAY,IAAI,IAAY,CAAC,GAAG5E,EAAa,KAAK,GAAG,GAAGC,EAAU,KAAK,CAAC,CAAC;EAC/E,KAAK,IAAM,CAAClP,GAAGzO,MAAMyd,GAAQ;GAC3B,IAAII,EAAQ,IAAIpP,CAAC,GAAG;GACpB,IAAI+J,IAAI;GACR,KAAK,IAAMja,KAAKyB,EAAE,OAAO,GACvB,AAAIzB,EAAE,UAAU,UAAS+jB,EAAU,IAAI7T,CAAC,IACnC,IAAI;GACX,AAAI+J,KAAG;EACT;EACA,KAAK,IAAM/J,KAAK6T,GAAW,AAAKzE,EAAQ,IAAIpP,CAAC,KAAG;EAChD,IAAI8T,IAAU,GACVC,IAAmBL,EAAY;EACnC,KAAK,IAAMnK,KAAK4F,EAAM,OACpB,AAAI5F,EAAE,SAAS6F,EAAQ,IAAI7F,EAAE,GAAG,MAChC,KACKmK,EAAY,IAAInK,EAAE,GAAG,KAAG;EAE/B,OAAO;GAAE;GAAc,aAAamK,EAAY;GAAM;GAAW;GAAa;GAAS;EAAiB;CAC1G,CAAC;CAmGD,OAdAtL,SACQyG,EAAQre,EAAE,IAAI,IACnB,MAAS;EACR,IAAI,CAACmJ,EAAK,MAAM;EAChB,IAAMqa,oBAAO,IAAI,IAAiB;EAClC,KAAK,IAAM3kB,KAAKK,GAAM,EAAK,IAAI6X,EAAMlY,CAAC,GAAGA,CAAC;EAC1C,KAAK,IAAM,CAAC8P,GAAKwJ,MAAMhP,GAAM;GAC3B,IAAMxD,IAAM6d,EAAK,IAAI7U,CAAG;GACxB,AAAIwJ,EAAE,QAAQxS,KAAOA,MAAQwS,EAAE,QAAMhP,EAAK,OAAOwF,CAAG;EACtD;EACA,EAAQ;CACV,CACF,GAEO;EACL;EACA;EACA;EACA,WAAW,MAAgB4Q,EAAM,MAAM,IAAI5Q,CAAG;EAC9C;EACA;EACA,YAAY,MAAgBiQ,EAAQ,IAAIjQ,CAAG;EAC3C;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,aA9HkB;GASlB,AARA2P,EAAM,MAAM,GACZE,EAAO,MAAM,GACbC,EAAa,MAAM,GACnBC,EAAU,MAAM,GAChB,EAAM,QAAQ,CAAC,GACfE,EAAQ,MAAM,GACdC,EAAU,MAAM,GAChBwD,GAAa,GACb,EAAQ;EACV;EAqHE,kBAlGqC;GACrC,IAAM9U,IAASuK,EAAQ,MAAM,IAAI3J,EAAO,CAAC,GACnCjP,IAAyB,CAAC;GAChC,KAAK,IAAM,CAACyP,GAAK5N,MAAMud,GAAO;IAC5B,IAAMnf,IAAMogB,EAAM,MAAM,IAAI5Q,CAAG;IAC/B,IAAI,CAACxP,KAAOyf,EAAQ,IAAIjQ,CAAG,KAAKoG,GAASpG,CAAG,GAAG;IAC/C,IAAM8U,IAAShE,GAAM9Q,CAAG,KAAKkQ,EAAU,IAAIlQ,CAAG,MAAM,UAC9CtG,IAAS,OAAO,YAAY,CAAC,GAAGtH,CAAC,CAAC,CAAC,QAAQ,GAAGW,OAAO,CAAC+hB,KAAU,CAACtmB,EAAauE,CAAC,CAAC,CAAC;IACvF,EAAK,KAAK;KACR,UAAUiN;KACV,KAAK,OAAOpB,IAASsS,GAAK1gB,GAAKoO,CAAM,IAAIvQ,EAASmC,GAAKgP,EAAO,CAAC,CAAC;KAChE,IAAIsV,IAAS,WAAW;KACxB;IACF,CAAC;GACH;GAEA,OADAvkB,EAAK,MAAM,GAAG,MAAMwgB,EAAQ3G,EAAE,QAAQ,IAAI2G,EAAQvH,EAAE,QAAQ,CAAC,GACtD,EAAE,QAAK;EAChB;EAkFE,uBAnH4B;GAC5B,IAAIlE,IAAU,IACR4J,IAAOc,EAAM,MAAM,KAAK,MACxB5F,EAAE,SAAS6F,EAAQ,IAAI7F,EAAE,GAAG,KAAK8F,EAAU,IAAI9F,EAAE,GAAG,MAAM,YAAYuF,EAAM,IAAIvF,EAAE,GAAG,CAAC,EAAE,OAAaA,KACzG,IAAU,IACV8F,EAAU,OAAO9F,EAAE,GAAG,GACtByF,EAAO,OAAOzF,EAAE,GAAG,GACZ;IAAE,GAAGA;IAAG,OAAO;GAAK,EAC5B;GACD,AAAI9E,MACF,EAAM,QAAQ4J,GACd,EAAQ;EAEZ;EAuGE,cAhFmB,MAAwC;GAC3D,IAAI6F,IAAU,GACVC,IAAU,GACVC,IAAS;GACb,KAAK,IAAM/kB,KAAKglB,GAAS;IACvB,IAAMlV,IAAM9P,EAAE,UACRM,IAAMogB,EAAM,MAAM,IAAI5Q,CAAG;IAC/B,IAAKxP,GACL;SAAIN,EAAE,WAAW,SAAS;MACxB;MACA,IAAMilB,IAAKjlB,EAAE,cAAc,IAAI,IAAI,OAAO,QAAQA,EAAE,WAAW,CAAC,IAAI;MAGpE,AAFIilB,GAAI,OAAMrF,EAAa,IAAI9P,GAAKmV,CAAE,IACjCrF,EAAa,OAAO9P,CAAG,GACxB9P,EAAE,WAAU6f,EAAU,IAAI/P,GAAK9P,EAAE,QAAQ,IACxC6f,EAAU,OAAO/P,CAAG;KAE3B,OAUA,AATI9P,EAAE,WAAW,YAAW,MACvB,KACLsK,EAAK,IAAIwF,GAAK;MAAE,KAAK9P,EAAE,OAAOmhB,EAAQ7gB,CAAG;MAAG,MAAMsgB,GAAM9Q,CAAG,IAAI,KAAA,IAAYxP;KAAI,CAAC,GAChFmf,EAAM,OAAO3P,CAAG,GAChB6P,EAAO,OAAO7P,CAAG,GACjB8P,EAAa,OAAO9P,CAAG,GACvB+P,EAAU,OAAO/P,CAAG,GACpBkQ,EAAU,OAAOlQ,CAAG,GACV6Q,EAAW,MAAM,IAAI7Q,CAC3B,MAAG,EAAM,QAAQgQ,EAAM,MAAM,KAAK,MAAOlB,EAAE,QAAQ9O,IAAM;MAAE,GAAG8O;MAAG,OAAO;KAAK,IAAIA,CAAE;IAVvF;GAWF;GAGA,OAFA4E,GAAa,GACb,EAAQ,SACD;IAAE;IAAS;IAAS;GAAO;EACpC;CAkDA;AACF;;;ACrmBA,IAAM0B,KAAWC,GAAc,EAAE,wBAAqB,CAAC;AAoBvD,SAAgBC,GAAkC,GAA2B;CAC3E,IAAM9Z,IAAUtH,QACdwb,EAAQre,EAAE,SAAS,CAAC,CAAC,KAAK,OAAQ;EAAE;EAAI,kBAAkB,KAAA;CAAU,EAAE,CACxE,GACM6W,IAAQqN,EAAwB;EACpC;EACA;EACA,MAAMrhB,QAAewb,EAAQre,EAAE,IAAI,CAAC;EACpC,UAAUA,EAAE;EAEZ,wBAAwB;EACxB,+BAA+B;CACjC,CAAC,GAEKgY,IAASnV,QAA2D;EACxE,IAAMshB,IAAStN,EAAM,MAAM,cAAc,IAAI,GACvCkC,IAAIoL,EAAOA,EAAO,SAAS;EACjC,OAAOpL,IAAI;GAAE,OAAOA,EAAE;GAAa,UAAUA,EAAE;EAAe,IAAI;CACpE,CAAC,GACKqL,IAASvhB,QAAmCgU,EAAM,uBAAuB,CAAC,CAAC,MAAM,IAAI,GAErFwN,IAAWxhB,QAA2D;EAC1E,IAAMhE,IAAIgY,EAAM,MAAM,cAAc,IAAI,CAAC,CAAC;EAC1C,OAAOhY,IAAI;GAAE,OAAOA,EAAE;GAAY,UAAUA,EAAE;EAAc,IAAI;CAClE,CAAC,GACKO,KAAQ,GAAe,MAC3ByX,EAAM,gBAAgB,CAAC,CAAC,SAASyN,EAAM,EAAE,sBAAsB,CAAC,CAACjL;CAEnE,OAAO;EACL;EACA;EACA;EACA,QAAQ,GAAe,MAAqBxC,EAAM,eAAeyN,GAAOjL,CAAQ;EAChF,OAAO,MAAiBxC,EAAM,kBAAkB7V,CAAC;EACjD,SAAS,MAAiB6V,EAAM,oBAAoB7V,CAAC;EACrD,iBAAiB6V,EAAM,eAAe;EAEtC,cAAc,MACZA,EAAM,gBAAgBgC,CAAK;EAC7B,aAAahC,EAAM,mBAAmB,EAAI;EAE1C,eAAe,GAAe,MAAqBzX,EAAKklB,GAAOjL,CAAQ,CAAC,EAAE,yBAAyB;EACnG,gBAAgB,GAAe,MAAqBja,EAAKklB,GAAOjL,CAAQ,CAAC,EAAE,0BAA0B;CACvG;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ECkBA,IAAM7W,IAAQC,GA4BRC,IAAOH,GAQPgU,IAAM/X,GAAoB,GAC1B,EAAE,YAAS+X,GACXhR,IAAMpJ,EAAUoa,EAAI,MAAM,GAC1B+Q,IAASzkB,QAAuBL,EAAM,cAAc;GAAE,KAAKA,EAAM;GAAS,OAAOA,EAAM;EAAQ,CAAC,GAEhG+kB,IAAO1pB,SAAqB2E,EAAM,SAAS+T,EAAI,aAAa;GAChE,SAAS/T,EAAM,WAAW;GAC1B,eAAe;GACf,UAAU;GACV,eAAe;EACjB,CAAC,GACKyU,IAAUpU,QAAwBL,EAAM,WAAW+kB,EAAK,MAAM,OAAO,GAErEtX,KAAYpN,QAAeL,EAAM,KAAK,SAASA,EAAM,OAAO,GAC5DglB,IAAa3kB,QAAgBoN,GAAU,QAAQzN,EAAM,KAAK,MAAM,GAAGA,EAAM,OAAO,IAAIA,EAAM,IAAK,GAC/FilB,IAAa5kB,QAAeL,EAAM,YAAY,EAAK,GACnDklB,IAAY7kB,QAAeL,EAAM,WAAW,EAAK,GACjDmlB,IAAW9kB,QAAe;GAC9B,IAAMvC,IAAImnB,EAAW,QAAQjlB,EAAM,UAAUA,EAAM;GACnD,OAAO,OAAOlC,KAAM,WAAWA,IAAI;EACrC,CAAC,GACKsnB,KAAU/kB,QACd8kB,EAAS,SAASA,EAAS,MAAM,QAAQ,IAAI,KAAK,MAAO,MAAMA,EAAS,MAAM,OAAQA,EAAS,MAAM,KAAK,IAAI,IAChH,GAIME,IACJ,OAAO,cAAe,eACrB,WAAW,eAAerlB,EAAM,gBAAgB,EAAE,IAAI,CAAC,CAAC,WAAW,CAAC,WAAW,qBAAqB,CAAC,CAAC,UACnGslB,IAAejlB,QACnBL,EAAM,QAAQ,KAAK,MACjBxB,EAAE,OAAOwB,EAAM,YACX;GAAE,GAAGxB;GAAG,QAAQ;GAAQ,OAAO6mB,IAAiB,MAAM;EAAI,IAC1D7mB,EAAE,WAAW,CAAC6mB,IACZ;GAAE,GAAG7mB;GAAG,QAAQ;EAAO,IACvBA,CACR,CACF,GACM8W,IAAUjV,QAAe,IAAI,IAAIilB,EAAa,MAAM,KAAK,MAAM,CAAC9mB,EAAE,IAAcA,CAAC,CAAC,CAAC,CAAC,GACpFuM,IAAS1K,QAAeiV,EAAQ,MAAM,IAAItV,EAAM,SAAS,CAAC,GAC1DulB,KAAallB,QAAeilB,EAAa,MAAM,MAAM,MAAM9mB,EAAE,OAAO,CAAC,GACrE8V,IAAQqH,GAAmB;GAC/B,MAAMqJ;GACN,SAASM;GACT,cAActlB,EAAM;GACpB,iBAAiBA,EAAM;GACvB;GACA,QAAQ+T,EAAI;EACd,CAAC,GAIKyR,KAAYrlB,EAAgB,CAAC,CAAC,GAC9BslB,IAAQta,EAA4B,IAAI,GACxCua,KAAOvlB,EAAqB,KAAK,GACjCwlB,KAAWxa,kBAAW,IAAI,IAAY,CAAC,GACvCya,MAAe,MACnBF,GAAK,UAAU,YACX,CAAC,CAACpR,EAAM,SAASnI,CAAG,CAAC,EAAE,QAAQmI,EAAM,MAAMnI,CAAG,IAC9CuZ,GAAK,UAAU,YACbpR,EAAM,SAASnI,CAAG,GAEpB0Z,MAAe,MAAmB;GACtC,IAAMxK,IAAOyK,IAAQ,IAAI,IAAIH,GAAS,KAAK,oBAAI,IAAI,IAAY;GAC/D,KAAK,IAAMtpB,KAAKiY,EAAM,MAAM,OAAO;IACjC,IAAMtH,IAAIsH,EAAM,MAAMjY,CAAC;IACvB,AAAIupB,GAAY5Y,CAAC,KAAGqO,EAAK,IAAIrO,CAAC;GAChC;GACA,GAAS,QAAQqO;EACnB,GAEM0K,MAAW,MAAuB;GAEtC,AADA,GAAK,QAAQ7mB,GACb2mB,GAAY,EAAK;EACnB;EAEA,GAAMvR,EAAM,eAAe;GACzB,AAAIoR,GAAK,UAAU,SAAOG,GAAY,EAAI;EAC5C,CAAC;EACD,IAAMG,KAAe3lB,QAAsB;GACzC,IAAMuc,IAAQtI,EAAM,MAAM,OACpB9W,IAAIioB,EAAM;GAChB,IAAI,CAACjoB,GAAG,OAAOof;GACf,IAAMvP,IAAO,IAAI,IAAI7P,CAAC,GAChBd,IAAc,CAAC;GACrB,KAAK,IAAMsQ,KAAKxP,GAAG;IACjB,IAAMnB,IAAIiY,EAAM,SAAStH,CAAC;IAC1B,AAAI3Q,KAAGK,EAAK,KAAKL,CAAC;GACpB;GACA,KAAK,IAAMA,KAAKugB,GAAO,AAAKvP,EAAK,IAAIiH,EAAM,MAAMjY,CAAC,CAAC,KAAGK,EAAK,KAAKL,CAAC;GACjE,OAAOK;EACT,CAAC,GAEKupB,IAAU5lB,QAAsB;GACpC,IAAM6lB,IAAMR,GAAK,UAAU,OACrB3Y,IAAO4Y,GAAS;GACtB,OAAOK,GAAa,MAAM,QAAQ,MAAM;IACtC,IAAMhZ,IAAIsH,EAAM,MAAMjY,CAAC;IACvB,OAAO,CAACiY,EAAM,UAAUtH,CAAC,MAAMkZ,KAAOnZ,EAAK,IAAIC,CAAC;GAClD,CAAC;EACH,CAAC,GACKoH,KAAS9Z,EAAqB;GAClC,SAASgrB;GACT,MAAMW;GACN,cAAcjmB,EAAM;GACpB,eAAe;EACjB,CAAC,GACKqU,IAAQoN,GAAmB;GAC/B,MAAMwE;GACN,iBAAiB7R,GAAO,QAAQ,MAAM,KAAK,MAAM5X,EAAE,EAAE;GACrD,OAAO8X,EAAM;EACf,CAAC,GACKiB,KAAalV,QAAe;GAChC,IAAM9B,oBAAI,IAAI,IAAoB;GAElC,OADA0nB,EAAQ,MAAM,SAAS,GAAG,MAAM1nB,EAAE,IAAI+V,EAAM,MAAMjY,CAAC,GAAGS,CAAC,CAAC,GACjDyB;EACT,CAAC,GACK4nB,IAAc9lB,QAAe+T,GAAO,QAAQ,KAAK,GAEjDgS,IAAc/lB,QAAe4kB,EAAW,SAASC,EAAU,SAASG,CAAc,GAIlFgB,KAAkD;GACtD,QAAQ3uB;GACR,MAAMA;GACN,WAAWA;GACX,WAAWA;GACX,OAAOA;GACP,KAAKA;GACL,OAAOA;GACP,IAAIA;GACJ,OAAOA;GACP,KAAKC;GACL,OAAOA;GACP,YAAYA;GACZ,UAAUA;GACV,MAAMA;GACN,QAAQC;GACR,aAAaC;GACb,MAAMC;GACN,UAAUA;EACZ,GACMwuB,MAAa,MAA0CtnB,EAAI,UAAUqnB,GAAQrnB,EAAI,SAAS,MAE1FunB,MAAW,GAAU,MAAiC;GAC1D,IAAIH,EAAY,OAAO,OAAO;GAC9B,IAAMnJ,IAAQ3I,EAAM,MAAMA,EAAM,MAAM3X,CAAG,CAAC;GAG1C,OAFIqC,EAAI,OAAOgB,EAAM,YAAkBid,IACnCje,EAAI,SAAS,aAAa,CAACsnB,GAAUtnB,CAAG,IAAU,KAC/C,OAAOA,EAAI,YAAa,aAAaA,EAAI,SAASsV,EAAM,QAAQ3X,CAAG,GAAG,EAAE,SAAM,CAAC,IAAIqC,EAAI,aAAa;EAC7G,GAEMwnB,MAAY,IAASzS,EAAI,YAAsB;GACnD;GACA,uBAAO,IAAI,KAAK;GAChB,WAAWzU,EAAK,EAAE,YAAY;GAC9B,SAASA,EAAK,EAAE,YAAY;GAC5B,QAAQA,EAAK,EAAE,WAAW;EAC5B,IACMmnB,IAAO9L,GAAqB;GAAE;GAAO;GAAS,QAAQ,GAAK,MAAS5b,GAAWC,GAAKjC,GAAMypB,GAAS,CAAC;EAAE,CAAC;EAC7G,GAAQlhB,IAAkB,EAAE,YAAYmhB,EAAK,QAAQ,OAAO,KAAK,CAAC;EAClE,IAAM/hB,KAAOgiB,GAA+C,MAAM,GAC5DlG,IAASlM,EAAM,QACfqS,KAAoB;GAAE;GAAK;GAAM,uBAAO,IAAI,KAAK;GAAG,QAAQ,IAAIjsB,EAAa;EAAE,GAG/EksB,MAAe,GAAY,GAAY,GAAY,MAAe;GACtE,IAAMlqB,IAAOupB,EAAQ,OACfxO,IAAO0O,EAAY,OACnB5P,IAAI7Z,EAAKmqB,IACTlR,IAAIjZ,EAAKoqB;GACf,AAAKvQ,KAAMZ,KAAM8B,EAAKsP,MAAQtP,EAAKuP,OACnC3S,EAAM,YAAY;IAChB,aAAaC,EAAM,MAAMiC,CAAC;IAC1B,gBAAgBkB,EAAKsP,EAAG,CAAE;IAC1B,YAAYzS,EAAM,MAAMqB,CAAC;IACzB,eAAe8B,EAAKuP,EAAG,CAAE;GAC3B,CAAC,GACDtiB,GAAK,OAAO,YAAY;EAC1B,GACM8S,MAAa,GAAW,MAAqB;GACjD,IAAM7a,IAAMspB,EAAQ,MAAM,KAAK,IAAI,GAAG,KAAK,IAAIA,EAAQ,MAAM,SAAS,GAAG5pB,CAAC,CAAC;GAC3E,AAAKM,MACL0X,EAAM,MAAMC,EAAM,MAAM3X,CAAG,GAAGka,CAAQ,GACtCnS,GAAK,OAAO,YAAY;EAC1B,GAEMuiB,WAAuD;GAC3D,IAAMtR,IAAItB,EAAM,OAAO;GACvB,IAAI,CAACsB,GAAG,OAAO,CAAC;GAChB,IAAMlO,IAAuC,CAAC;GAC9C,KAAK,IAAIpL,IAAIsZ,EAAE,aAAatZ,KAAKsZ,EAAE,aAAa,KAC9C,KAAK,IAAInZ,IAAImZ,EAAE,gBAAgBnZ,KAAKmZ,EAAE,gBAAgB,KAAK,EAAI,KAAK;IAAE;IAAG;GAAE,CAAC;GAC9E,OAAOlO;EACT,GAEMyf,MAAU,GAAU,MAAwB5S,EAAM,IAAI3X,GAAKqC,GAAK,CAACsV,EAAM,KAAK3X,GAAKqC,CAAG,CAAC,GAErFmoB,WAAsB;GAC1B,IAAMrI,IAA8B,CAAC;GACrC,KAAK,IAAM,EAAE,MAAG,UAAOmI,GAAc,GAAG;IACtC,IAAMtqB,IAAMspB,EAAQ,MAAM5pB,IACpB2C,IAAMmnB,EAAY,MAAM3pB,EAAE,EAAE;IAClC,AAAIG,KAAOqC,KAAOunB,GAAQ5pB,GAAKqC,CAAG,KAAG8f,EAAQ,KAAK;KAAE;KAAK;KAAK,OAAO;IAAK,CAAC;GAC7E;GACA,EAAM,MAAMA,CAAO;EACrB,GAGMsI,KAAmB/mB,SACvBiU,EAAW,QAAQ,OACZ0R,GAAa,MAAM,KAAK,MAAM1R,EAAM,MAAMjY,CAAC,CAAC,CAAC,CAAC,QAAQ,MAAM,CAACiY,EAAM,UAAUtH,CAAC,KAAKsH,EAAM,SAAStH,CAAC,CAAC,EAC5G,GACKqa,MAAa,MAAgB;GACjC,IAAM3qB,IAAOupB,EAAQ,OACf,IAAIvpB,EAAK,QACT6Z,IAAIlC,EAAM,OAAO,OACjBmF,IAAOjD,IAAKhB,GAAW,MAAM,IAAIgB,EAAE,KAAK,KAAK,KAAM;GACzD,KAAK,IAAIra,IAAI,GAAGA,KAAK,GAAG,KAAK;IAC3B,IAAMY,MAAO0c,IAAO3S,IAAM3K,KAAK,IAAK,KAAK,GACnCiQ,IAAMmI,EAAM,MAAM5X,EAAKI,EAAG;IAChC,IAAI,CAACwX,EAAM,SAASnI,CAAG,GAAG;IAC1B,IAAM6P,IAAS1H,EAAM,UAAUnI,CAAG,GAC5B0B,IACJsY,EAAY,MAAM,MAAM,MAAMnK,GAAQ,IAAIxf,EAAE,EAAE,CAAC,EAAE,UAAU,OAAO,MACjE8X,EAAM,SAASnI,CAAG,IAAIga,EAAY,MAAM,MAAM,MAAM3pB,EAAE,OAAOwD,EAAM,SAAS,IAAI,KAAA;IACnF,IAAK6N,GACL;KACA,AADAwG,EAAM,MAAMlI,GAAK0B,EAAI,EAAE,GACvBnJ,GAAK,OAAO,YAAY;KACxB;IAFuB;GAGzB;GACA,AAAI0iB,GAAiB,MAAM,UAAU1B,GAAK,UAAU,SAClD4B,GAAU;IACR,MAAMhoB,EAAK,EAAE,uBAAuB;IACpC,QAAQ;KACN,OAAOA,EAAK,EAAE,cAAc;KAC5B,WAAW;MAET,AADAymB,GAAQ,KAAK,GACbsB,GAAUxgB,CAAG;KACf;IACF;GACF,CAAC;EACL,GAGM0gB,MAAY,GAAqB,GAAU,MAA2B;GAC1E,IAAI5sB,EAAayE,CAAK,GAAG,OAAO;GAChC,QAAQJ,EAAI,MAAZ;IACE,KAAK,YACH,OAAO+D,EAAI,QAAQ,OAAO3D,CAAK,GAAGJ,EAAI,iBAAiB,CAAC;IAC1D,KAAK;IACL,KAAK,YACH,OAAOI,aAAiB,OAAOA,EAAM,YAAY,IAAI,OAAOA,CAAK;IACnE,KAAK,eACH,OAAQA,EAAoB,KAAK,MAAMjF,EAAY6E,EAAI,SAASE,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI;IAC/E,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK,MACH,OAAO,OAAOE,CAAK;IACrB,SACE,OAAO3E,EAAWuE,GAAKrC,GAAKyC,GAAOunB,EAAM;GAC7C;EACF,GACMa,WAAsC;GAC1C,IAAM7R,IAAItB,EAAM,OAAO;GACvB,IAAI,CAACsB,GAAG,OAAO;GACf,IAAMlO,IAAkB,CAAC;GACzB,KAAK,IAAIpL,IAAIsZ,EAAE,aAAatZ,KAAKsZ,EAAE,aAAa,KAAK;IACnD,IAAMhZ,IAAMspB,EAAQ,MAAM5pB;IAC1B,IAAI,CAACM,GAAK;IACV,IAAM8qB,IAAiB,CAAC;IACxB,KAAK,IAAIjrB,IAAImZ,EAAE,gBAAgBnZ,KAAKmZ,EAAE,gBAAgB,KAAK;KACzD,IAAM3W,IAAMmnB,EAAY,MAAM3pB,EAAE,CAAE;KAClC,EAAK,KAAK+qB,GAASvoB,GAAKrC,GAAK2X,EAAM,KAAK3X,GAAKqC,CAAG,CAAC,CAAC;IACpD;IACA,EAAI,KAAKyoB,CAAI;GACf;GACA,OAAOhgB;EACT,GACMigB,MAAQ,MAAuC;GACnD,IAAMnpB,IAAIipB,GAAW;GAIrB,OAHI,CAACjpB,KAAK,CAACjB,IAAa,MACxBA,EAAK,QAAQ,cAAcnB,GAAMoC,CAAC,CAAC,GACnCjB,EAAK,QAAQ,aAAaf,GAAOgC,CAAC,CAAC,GAC5B;EACT,GACMopB,MAAO,MACND,GAAKpqB,CAAI,KACT8oB,EAAY,SAAOe,GAAc,GAC/B,MAFiB,IAKpBS,MAAmB,MAAsB;GAC7C,IAAMrpB,IAAIipB,GAAW,GACfK,IAAO,OAAO,YAAc,MAAc,UAAU,YAAY,KAAA;GACtE,IAAI,CAACtpB,KAAK,CAACspB,GAAM;GACjB,IAAMC,IAAM3rB,GAAMoC,CAAC;GAWnB,CATE,OAAO,iBAAkB,cAAcspB,EAAK,QACxCA,EAAK,MAAM,CACT,IAAI,cAAc;IAChB,cAAc,IAAI,KAAK,CAACC,CAAG,GAAG,EAAE,MAAM,aAAa,CAAC;IACpD,aAAa,IAAI,KAAK,CAACvrB,GAAOgC,CAAC,CAAC,GAAG,EAAE,MAAM,YAAY,CAAC;GAC1D,CAAC,CACH,CAAC,IACDspB,EAAK,UAAUC,CAAG,EAAA,CACb,YAAYD,EAAK,UAAUC,CAAG,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,GACtDC,KAAY,CAAC3B,EAAY,SAAOe,GAAc;EACpD,GACMa,MAAe,MAAgC;GACnD,IAAMzR,IAAIlC,EAAM,OAAO,OACjB4T,IAAQ,KAAK,IAAI,GAAG,GAAG7rB,EAAO,KAAK,MAAM8rB,EAAE,MAAM,CAAC;GACxD,IAAI,CAAC3R,KAAK,CAACna,EAAO,UAAU,CAAC6rB,KAAS7B,EAAY,OAAO,OAAO;GAChE,IAAM3O,IAAO0O,EAAY,OACnBgC,IAAW5S,GAAW,MAAM,IAAIgB,EAAE,KAAK,GACvC6R,IAAW3Q,EAAK,WAAW,MAAMjb,EAAE,OAAO+Z,EAAE,QAAQ;GAC1D,IAAI4R,MAAa,KAAA,KAAaC,IAAW,GAAG,OAAO;GACnD,IAAMzS,IAAItB,EAAM,OAAO,OACjBgU,IAAyD,CAAC;GAChE,IACEjsB,EAAO,WAAW,KAClB6rB,MAAU,KACVtS,MACCA,EAAE,cAAcA,EAAE,eAAeA,EAAE,iBAAiBA,EAAE,iBAGvD,KAAK,IAAM,EAAE,MAAG,UAAOsR,GAAc,GAAG,EAAQ,KAAK;IAAE;IAAG;IAAG,MAAM7qB,EAAO,EAAE,CAAE;GAAI,CAAC;QAEnF,EAAO,SAAS,GAAM,MACpBqrB,EAAK,SAAS,GAAM,MAAM;IACxB,AAAIW,IAAWrgB,IAAI0P,EAAK,UAAQ4Q,EAAQ,KAAK;KAAE,GAAGF,IAAWrrB;KAAG,GAAGsrB,IAAWrgB;KAAG;IAAK,CAAC;GACzF,CAAC,CACH;GAEF,IAAMugB,IAAU,KAAK,IAAI,GAAGD,EAAQ,KAAK,MAAM1iB,EAAE,CAAC,CAAC,GAC7C4iB,IAAWD,IAAUrC,EAAQ,MAAM,SAAS;GAClD,IAAIsC,IAAW,KAAKjU,EAAM,QAAQ,MAAM,SAASiU,IAAWvoB,EAAM,SAOhE,OANAsnB,GAAU,EACR,MAAMhoB,EAAK,EAAE,oBAAoB;IAC/B,OAAOyD,EAAI,IAAIuR,EAAM,QAAQ,MAAM,SAASiU,CAAQ;IACpD,KAAKxlB,EAAI,IAAI/C,EAAM,OAAO;GAC5B,CAAC,EACH,CAAC,GACM;GAGT,IAAMof,IAAYmJ,IAAW,IAAIjU,EAAM,QAAQiU,CAAQ,IAAI,CAAC;GAC5D,AAAInJ,EAAU,UAAUqG,EAAM,UAAO,EAAM,QAAQ,CAAC,GAAGA,EAAM,OAAO,GAAGrG,EAAU,KAAK,MAAMnE,EAAE,GAAG,CAAC;GAClG,IAAMve,IAAOupB,EAAQ,OAEfuC,oBAAc,IAAI,IAAoB;GAC5C,KAAK,IAAMhsB,KAAK,IAAI,IAAI6rB,EAAQ,KAAK,MAAM1iB,EAAE,CAAC,CAAC,GAAG;IAChD,IAAM3G,IAAMyY,EAAKjb,EAAE,CAAE;IACrB,IAAI,CAACzC,EAAWiF,EAAI,KAAK,CAAC,SAAS;IACnC,IAAM4O,IAAM7P,GAAasqB,EAAQ,QAAQ,MAAM,EAAE,MAAM7rB,CAAC,CAAC,CAAC,KAAK,MAAMmJ,EAAE,IAAI,CAAC;IAC5E,EAAY,IAAInJ,GAAGoR,MAAQ,MAAM,OAAOA,MAAQ,MAAM,OAAOmG,EAAI,MAAM;GACzE;GACA,IAAM+K,IAA8B,CAAC;GACrC,KAAK,IAAMnZ,KAAK0iB,GAAS;IACvB,IAAM1rB,IAAMD,EAAKiJ,EAAE,IACb3G,IAAMyY,EAAK9R,EAAE,EAAE,EAAE;IACvB,AAAKhJ,KAAQqC,KAAQunB,GAAQ5pB,GAAKqC,CAAG,KACrC8f,EAAQ,KAAK;KAAE;KAAK;KAAK,OAAO/f,GAAWC,GAAK2G,EAAE,MAAM6gB,GAASgC,EAAY,IAAI7iB,EAAE,CAAC,CAAC,CAAC;IAAE,CAAC;GAC3F;GACA,EAAM,MAAMmZ,GAASM,CAAS;GAC9B,IAAMqJ,IAAO,KAAK,IAAI,GAAGJ,EAAQ,KAAK,MAAM1iB,EAAE,CAAC,CAAC,GAC1C+iB,IAAO,KAAK,IAAI,GAAGL,EAAQ,KAAK,MAAM1iB,EAAE,CAAC,CAAC,GAC1CgjB,IAAO,KAAK,IAAI,GAAGN,EAAQ,KAAK,MAAM1iB,EAAE,CAAC,CAAC;GAChD,GAAY8iB,GAAMC,GAAMJ,GAASK,CAAI;GAErC,IAAM3M,IAASqM,EACZ,KAAK,MAAM;IACV,IAAM1rB,IAAMD,EAAKiJ,EAAE;IAEnB,QADchJ,KAAO2X,EAAM,UAAUA,EAAM,MAAM3X,CAAG,CAAC,CAAC,EAAE,IAAI8a,EAAK9R,EAAE,EAAE,CAAE,EAAE,EAAA,EAC3D,UAAU,UACpB;KAAE,GAAGA;KAAG,QAAQ8R,EAAK9R,EAAE,EAAE,CAAE,IAAI,SAAS,YAAY8R,EAAK9R,EAAE,EAAE,CAAE,IAAI,SAAS;IAAc,IAC1F;GACN,CAAC,CAAA,CACA,QAAQ,MAAkCsV,MAAM,IAAI,GACjDxd,KAAUue,EAAO,QAAQ,MAAMlf,EAAE,MAAM,CAAC,CAAC,QACzCmhB,IAASjC,EAAO,SAASve,IACzBmrB,IAAO;IAAE,MAAMN,IAAUG,IAAO;IAAG,MAAME,IAAOD,IAAO;GAAE,GACzDnhB,KAAQyU,EAAO;GAcrB,OAbAsL,GAAU;IACR,MAAMhoB,EAAK,EAAE,gBAAgB;KAAE,MAAMyD,EAAI,IAAI6lB,EAAK,IAAI;KAAG,MAAM7lB,EAAI,IAAI6lB,EAAK,IAAI;IAAE,CAAC;IACnF,QACE,CACEnrB,KAAU6B,EAAK,EAAE,qBAAqB,EAAE,OAAO7B,GAAQ,CAAC,IAAI,IAC5DwgB,IAAS3e,EAAK,EAAE,qBAAqB,EAAE,OAAO2e,EAAO,CAAC,IAAI,EAC5D,CAAA,CACG,OAAO,OAAO,CAAA,CACd,KAAK,KAAK,KAAK,KAAA;IACpB,QAAQ1W,WAAcqf,GAAYrf,GAAM,GAAGA,GAAM,GAAGA,GAAM,GAAGA,GAAM,CAAC,IAAI,KAAA;IACxE,MAAM;GACR,CAAC,GACD,GAAO,QAAQjI,EAAK,EAAE,aAAaspB,CAAI,GAChC;EACT,GACMC,MAAS,MAAuCb,GAAY3qB,GAAoBC,CAAI,CAAC,GAErFwrB,WAA2B;GAC/B,UAAe,WACX,SAAS,CAAA,CACV,MAAM,MAASd,GAAYvrB,GAASM,CAAI,CAAC,CAAC,CAAA,CAC1C,YAAY,CAAC,CAAC;EACnB,GAGMgsB,MAAY,GAAiB,GAAe,GAAwB,MAAmB;GAC3F,IAAMrsB,IAAOupB,EAAQ,OACfrf,IAAKmR,IAASiR,GACdxiB,IAAQI,IAAKoiB,IAAUjR,IAASA,IAASkR,GACzCnK,IAA8B,CAAC;GACrC,KAAK,IAAItiB,IAAIib,EAAK,IAAIjb,KAAKib,EAAK,IAAI,KAAK;IACvC,IAAMzY,IAAMmnB,EAAY,MAAM3pB,EAAE,EAAE;IAClC,IAAI,CAACwC,GAAK;IAEV,IAAM6G,IAASS,GADA5J,EAAK,MAAMssB,GAASC,IAAQ,CAAC,CAAC,CAAC,KAAK,MAAM3U,EAAM,KAAKjY,GAAG2C,CAAG,CAChD,GAAQwH,GAAOI,CAAE;IAC3C,KAAK,IAAIoG,IAAI,GAAGA,IAAIxG,GAAO,KAAK;KAC9B,IAAM7J,IAAMD,EAAKkK,IAAKoiB,IAAU,IAAIhc,IAAIic,IAAQ,IAAIjc;KACpD,AAAIrQ,KAAO4pB,GAAQ5pB,GAAKqC,CAAG,KAAG8f,EAAQ,KAAK;MAAE;MAAK;MAAK,OAAOjZ,EAAOmH;KAAG,CAAC;IAC3E;GACF;GACA,OAAO;IAAE;IAAS;GAAM;EAC1B,GACM6E,MAAQ,GAAiB,GAAe,GAAwB,MAAmB;GACvF,IAAM,EAAE,eAAYkX,GAASC,GAASC,GAAOxR,GAAMM,CAAM;GAEzD,AADAzD,EAAM,MAAMwK,CAAO,GACnB8H,GAAY,KAAK,IAAIoC,GAASjR,CAAM,GAAGN,EAAK,IAAI,KAAK,IAAIwR,GAAOlR,CAAM,GAAGN,EAAK,EAAE;EAClF,GACMe,MAAa,GAAiB,GAAe,GAAwB,MAA2B;GACpG,IAAM,EAAE,YAAS,aAAUuQ,GAASC,GAASC,GAAOxR,GAAMM,CAAM,GAC1DxQ,IAAQuX,EAAQ,IAChB1f,IAAQmI,IAAQ9M,EAAW8M,EAAM,KAAKA,EAAM,KAAKA,EAAM,OAAOof,EAAM,IAAI;GAC9E,OAAOrnB,EAAK,EAAE,qBAAqB;IAAE,OAAOkH,KAASiR,EAAK,KAAKA,EAAK,KAAK;IAAI;GAAM,CAAC;EACtF,GACMyR,WAAiB;GACrB,IAAMvT,IAAItB,EAAM,OAAO;GACvB,AAAKsB,KAAKA,EAAE,gBAAgBA,EAAE,eAC9B9D,GAAK8D,EAAE,aAAaA,EAAE,aAAa,CAACA,EAAE,gBAAgBA,EAAE,cAAc,GAAGA,EAAE,WAAW;EACxF,GAGMwT,MAAa,MAAsB;GACvC,IAAI,CAACziB,GAAM;GAEX,IAAIA,EAAK,SAAS,UAAU,CAACA,EAAK,QAAQ,QAAQ;IAChD,IAAM5J,IAAIyY,GAAW,MAAM,IAAI7O,EAAK,QAAQ,EAAG;IAC/C,AAAI5J,MAAM,KAAA,KAAW0a,GAAU1a,GAAGuX,EAAM,OAAO,OAAO,YAAY8R,EAAY,MAAM,EAAE,CAAE,EAAE;IAC1F;GACF;GACA,IAAI,CAACzf,EAAK,QAAQ,QAAQ;GAC1B,IAAM0iB,IAAMjD,EAAY,MAAM,KAAK,MAAM3pB,EAAE,EAAE,GACzCqqB,IAAK,UACLC,IAAK,IACLC,IAAK,UACLC,IAAK;GACT,KAAK,IAAMlpB,KAAK4I,EAAK,SAAS;IAC5B,IAAMrK,IAAIkZ,GAAW,MAAM,IAAIzX,EAAE,GAAG,GAC9BtB,IAAI4sB,EAAI,QAAQtrB,EAAE,GAAG;IAC3B,AAAIzB,MAAM,KAAA,KAAaG,IAAI,MAC3B,IAAK,KAAK,IAAIqqB,GAAIxqB,CAAC,GACnB,IAAK,KAAK,IAAIyqB,GAAIzqB,CAAC,GACnB,IAAK,KAAK,IAAI0qB,GAAIvqB,CAAC,GACnB,IAAK,KAAK,IAAIwqB,GAAIxqB,CAAC;GACrB;GACA,AAAIsqB,KAAM,KAAGF,GAAYC,GAAIE,GAAID,GAAIE,CAAE;EACzC,GACMrH,WAAa;GACjB,AAAIyG,EAAY,UAChBK,EAAK,OAAO,GACZ0C,GAAU7U,EAAM,KAAK,CAAC;EACxB,GACMsL,WAAa;GACjB,AAAIwG,EAAY,UAChBK,EAAK,OAAO,GACZ0C,GAAU7U,EAAM,KAAK,CAAC;EACxB,GACM+U,MAAiB,GAAU,GAAqB,MAAmB/U,EAAM,IAAI3X,GAAKqC,GAAKI,CAAK,GAI5FkqB,MAAU,MAAgB;GAC9B,IAAIlD,EAAY,OAAO;GACvB,IAAI9R,EAAM,QAAQ,MAAM,SAAS,IAAItU,EAAM,SAAS;IAClD,GAAU,EACR,MAAMV,EAAK,EAAE,oBAAoB;KAAE,OAAOyD,EAAI,IAAIuR,EAAM,QAAQ,MAAM,SAAS,CAAC;KAAG,KAAKvR,EAAI,IAAI/C,EAAM,OAAO;IAAE,CAAC,EAClH,CAAC;IACD;GACF;GACA,EAAK,OAAO;GACZ,IAAM,CAACmc,KAAS7H,EAAM,QAAQ,CAAC;GAC/B,IAAI,CAAC6H,GAAO;GACZ,IAAMoN,IAAWvpB,EAAM,iBAAiB,KAAK,CAAC,GACxC8e,IAA8B,CAAC;GACrC,KAAK,IAAM,CAAC1S,GAAIhN,MAAU,OAAO,QAAQmqB,CAAQ,GAAG;IAClD,IAAMvqB,IAAMsW,EAAQ,MAAM,IAAIlJ,CAAE;IAChC,AAAIpN,KAAO,CAACrE,EAAayE,CAAK,KAAG0f,EAAQ,KAAK;KAAE,KAAK3C,EAAM;KAAK;KAAK;IAAM,CAAC;GAC9E;GAEA,IADA7H,EAAM,MAAMwK,GAAS,CAAC3C,CAAK,CAAC,GACxBqN,MAAO,KAAA,GAAW;IACpB,IAAMzc,IAAO0Y,EAAM,SAASnR,EAAM,MAAM,MAAM,KAAK,MAAMA,EAAM,MAAMjY,CAAC,CAAC,CAAC,CAAC,QAAQ,MAAM2Q,MAAMmP,EAAM,GAAG,GAChGsN,IAAM,KAAK,IAAI,GAAG,KAAK,IAAI1c,EAAK,QAAQyc,CAAE,CAAC;IACjD,EAAM,QAAQ;KAAC,GAAGzc,EAAK,MAAM,GAAG0c,CAAG;KAAGtN,EAAM;KAAK,GAAGpP,EAAK,MAAM0c,CAAG;IAAC;GACrE,OAAO,AAAiBhE,EAAM,UAAQ,CAAC,GAAGA,EAAM,OAAOtJ,EAAM,GAAG;GAOhE,AANIuJ,GAAK,UAAU,UAAO,GAAS,wBAAQ,IAAI,IAAI,CAAC,GAAGC,GAAS,OAAOxJ,EAAM,GAAG,CAAC,IACjF9H,EAAM,MAAM8H,EAAM,KAAKnc,EAAM,SAAS,GAGtCe,SAAoB2D,GAAK,OAAO,cAAcuhB,EAAQ,MAAM,WAAW,MAAM3R,EAAM,MAAMjY,CAAC,MAAM8f,EAAM,GAAG,CAAC,CAAC,GAC3GzX,GAAK,OAAO,YAAY,GACpBqG,EAAO,SAAO0b,EAAK,MAAMtK,EAAM,KAAKpR,EAAO,OAAO,EAAE,QAAQ,GAAK,CAAC;EACxE,GACM2e,MAAa,MAA6B;GAC9C,IAAMnT,IAAIlC,EAAM,OAAO,OACjBvX,IAAIyZ,IAAIyP,GAAa,MAAM,WAAW,MAAM1R,EAAM,MAAMjY,CAAC,MAAMka,EAAE,KAAK,IAAI;GAChF,GAAOzZ,IAAI,IAAI,KAAA,IAAY6sB,MAAU,UAAU7sB,IAAIA,IAAI,CAAC;EAC1D,GACM8sB,WAA2B;GAC/B,IAAIxD,EAAY,OAAO;GACvB,IAAMzQ,IAAItB,EAAM,OAAO;GACvB,IAAI,CAACsB,GAAG;GACR,EAAK,OAAO;GAEZ,IAAM5I,IADOkZ,EAAQ,MAAM,MAAMtQ,EAAE,aAAaA,EAAE,cAAc,CACnD,CAAA,CAAK,KAAK,MAAMrB,EAAM,MAAMjY,CAAC,CAAC;GAC3C,AAAK0Q,EAAK,WACVuH,EAAM,WAAWvH,CAAI,GACrBua,GAAU;IACR,MACEva,EAAK,WAAW,IACZzN,EAAK,EAAE,iBAAiB;KAAE,OAAO;KAAG,KAAKgV,EAAM,QAAQvH,EAAK,EAAG;KAAG,QAAQ+X,EAAO;IAAM,CAAC,IACxFxlB,EAAK,EAAE,iBAAiB;KAAE,OAAOyN,EAAK;KAAQ,QAAQ+X,EAAO;IAAM,CAAC;IAC1E,MAAM;GACR,CAAC,GACDtN,GAAU7B,EAAE,aAAatB,EAAM,OAAO,OAAO,YAAY8R,EAAY,MAAM,EAAE,CAAE,EAAE;EACnF,GAGM0D,MAAQ,GAAkB,MAAsB;GACpD,IAAM7qB,IAAMsW,EAAQ,MAAM,IAAIuB,CAAQ;GACtC,IAAI,CAAC7X,KAAO,EAAEA,EAAI,YAAYjF,EAAWiF,EAAI,KAAK,CAAC,WAAW;GAC9D,IAAMwe,IAAUgI,GAAU,OACpBsE,IAAWtM,EAAQ,MAAM,MAAMthB,EAAE,WAAW2a,CAAQ,GACpDwE,IAAyByO,IAE3BA,EAAS,QAAQ,QACf;IAAE,QAAQjT;IAAU,KAAK;GAAO,IAChC,OAHF;IAAE,QAAQA;IAAU,KAAK;GAAM,GAI7BkT,IAAOvM,EAAQ,QAAQ,MAAMthB,EAAE,WAAW2a,CAAQ;GAUxD,IATA,GAAU,QAAQmT,IACd3O,IACEyO,IACEtM,EAAQ,KAAK,MAAOthB,EAAE,WAAW2a,IAAWwE,IAAOnf,CAAE,IACrD,CAAC,GAAG6tB,GAAM1O,CAAI,CAAC,CAAC,MAAM,EAAE,IAC1B0O,IACF1O,IACE,CAACA,CAAI,IACL,CAAC,GACH,CAACmK,GAAU,MAAM,QAAQ;IAC3B,EAAM,QAAQ;IACd;GACF;GACA,IAAMyE,IAAOzE,GAAU,MAAM,KAAK,OAAO;IACvC,KAAKlQ,EAAQ,MAAM,IAAIpZ,EAAE,MAAM;IAC/B,KAAKZ,GAAWga,EAAQ,MAAM,IAAIpZ,EAAE,MAAM,GAAI6X,EAAI,MAAM;IACxD,MAAM7X,EAAE,QAAQ,SAAS,KAAK;GAChC,EAAE;GACF,EAAM,QAAQ,CAAC,GAAGoY,EAAM,MAAM,KAAK,CAAA,CAChC,MAAM,GAAG,MAAM;IACd,KAAK,IAAM,EAAE,KAAK9V,GAAG,QAAK,aAAUyrB,GAAM;KACxC,IAAM5tB,IAAI6tB,EAAI5V,EAAM,KAAKiC,GAAG/X,CAAC,GAAG8V,EAAM,KAAKqB,GAAGnX,CAAC,CAAC,IAAI2rB;KACpD,IAAI9tB,GAAG,OAAOA;IAChB;IACA,OAAOiY,EAAM,QAAQA,EAAM,MAAMiC,CAAC,CAAC,IAAIjC,EAAM,QAAQA,EAAM,MAAMqB,CAAC,CAAC;GACrE,CAAC,CAAA,CACA,KAAK,MAAMrB,EAAM,MAAMjY,CAAC,CAAC;EAC9B,GACM+tB,KAAU/pB,QAAe;GAC7B,IAAM9B,oBAAI,IAAI,IAA2D;GAEzE,OADAinB,GAAU,MAAM,SAAS,GAAG,MAAMjnB,EAAE,IAAIrC,EAAE,QAAQ;IAAE,KAAKA,EAAE;IAAK,OAAOspB,GAAU,MAAM,SAAS,IAAI1oB,IAAI,IAAI;GAAK,CAAC,CAAC,GAC5GyB;EACT,CAAC,GAIK8rB,qBAAS,IAAI,IAAoB,GACjCC,qBAAU,IAAI,IAAoB,GACpCC,IACAC,KAAoC,MAClCC,KAAY,YAAY;GAC5B,IAAMC,IAAY,IAAI,IAAIJ,EAAO;GAEjC,IADAA,GAAQ,MAAM,GACTI,EAAU,MACf;QAAK1qB,EAAM,YAIX;UAAK,IAAM2qB,KAAUD,EAAU,KAAK,GAAG,EAAM,YAAYC,GAAQ,UAAU;KAE3E,AADAH,IAAW,MAAM,GACjB,KAAY,IAAI,gBAAgB;KAChC,IAAI;MACF,IAAM3kB,IAAS,CAAC,GAAG,IAAI,IAAI6kB,EAAU,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,GAAG,GACtDE,IAAS,MAAM5qB,EAAM,WAAW6F,GAAQ,EAAE,QAAQ2kB,GAAU,OAAO,CAAC;MAC1E,KAAK,IAAM,CAACG,GAAQvrB,MAAUsrB,GAAW;OACvC,IAAIL,GAAO,IAAIM,CAAM,MAAMvrB,GAAO;OAClC,IAAMyrB,IAAQD,EAAOxrB;OACrB,AAAIyrB,KACFvW,EAAM,YAAYqW,GAAQ,QAAQ,GAClCrW,EAAM,QAAQqW,GAAQE,CAAK,KACtBvW,EAAM,YAAYqW,GAAQ,KAAK;MACxC;KACF,QAAQ;MACN,KAAK,IAAMA,KAAUD,EAAU,KAAK,GAAG,EAAM,YAAYC,GAAQ,KAAK;KACxE;IAhB2E,OAHzE,KAAK,IAAMA,KAAUD,EAAU,KAAK,GAAG,EAAM,YAAYC,GAAQ,KAAK;GAExE;EAkBF;EACA,GAAMrW,EAAM,eAAe;GACzB,IAAMtV,IAAM+L,EAAO;GACnB,IAAK/L,GACL;SAAK,IAAM3C,KAAKiY,EAAM,MAAM,OAAO;KACjC,IAAMqW,IAASrW,EAAM,MAAMjY,CAAC;KAC5B,IAAI,CAACiY,EAAM,MAAMqW,CAAM,GAAG;KAC1B,IAAMzrB,IAAIoV,EAAM,cAAcjY,GAAG2C,CAAG,GAC9BjC,IAAOpC,EAAauE,CAAC,IAAI,KAAK,OAAOA,CAAC;KAC5C,AAAImrB,GAAO,IAAIM,CAAM,MAAM5tB,MAC3BstB,GAAO,IAAIM,GAAQ5tB,CAAI,GACnBA,IAAMutB,GAAQ,IAAIK,GAAQ5tB,CAAI,IAC7BuX,EAAM,YAAYqW,GAAQ,KAAK;IACtC;IACA,AAAIL,GAAQ,SACV,aAAaC,EAAW,GACxB,KAAc,iBAAiB,KAAKE,GAAU,GAAG,GAAG;GAHtD;EAKF,CAAC;EAID,IAAMK,KAAkB3qB,EAAI,EAAK,GAC3B4qB,KAAa1qB,QACjB+mB,GAAiB,MACd,QAAQ,MAAM,CAAC,CAAC9S,EAAM,SAAStH,CAAC,CAAC,EAAE,QAAQsH,EAAM,MAAMtH,CAAC,CAAC,CAAA,CACzD,KAAK,MAAM;GACV,IAAMrQ,IAAM2X,EAAM,SAAStH,CAAC,GACtBgP,IAAS1H,EAAM,UAAUtH,CAAC,GAC1BzF,IAAQyU,IAAS,CAAC,GAAGA,EAAO,OAAO,CAAC,CAAC,CAAC,MAAM,MAAMlf,EAAE,UAAU,OAAO,IAAI,KAAA;GAC/E,OAAO;IACL,OAAOwX,EAAM,QAAQtH,CAAC;IACtB,KAAKjC,EAAO,QAAQ5L,GAAU4L,EAAO,OAAOuJ,EAAM,KAAK3X,GAAKoO,EAAO,KAAK,CAAC,IAAIiC;IAC7E,SAASzF,GAAO,WAAW+M,EAAM,SAAStH,CAAC,KAAK;GAClD;EACF,CAAC,CACL,GACMge,KAAa7f,EAAW;GAAE,SAAS;GAAG,SAAS;GAAG,QAAQ;EAAE,CAAC,GAC7D8f,KAAe9f,EAAuE,IAAI,GAC1F+f,KAAS/f,EAAqD,IAAI,GAClEggB,WAAiB;GAKrB,AAJA,GAAW,QAAQ;IAAE,SAAS;IAAG,SAAS;IAAG,QAAQ;GAAE,GACvD,GAAa,QAAQ,MACrB,GAAO,QAAQ,MACf7W,EAAM,gBAAgB,GACtBpU,EAAK,QAAQoU,EAAM,WAAW,CAAC;EACjC,GACMzE,WAAa;GACjB,AAAIuW,EAAY,UAChBK,EAAK,OAAO,IACPjG,EAAO,MAAM,gBAAiBA,EAAO,MAAM,aAC5CuK,GAAW,MAAM,SACnB,GAAgB,QAAQ,KAG1BI,GAAS;EACX,GACMC,WAAiB;GAErB,AADArF,GAAQ,QAAQ,GAChBsB,GAAU,CAAC;EACb,GACMgE,WAAmB;GACvB,IAAM1lB,IAAIqlB,GAAW;GACrB,CAAKrlB,EAAE,WAAYA,EAAE,WAAYA,EAAE,YAC/BA,EAAE,UACJ,GAAO,QAAQ;IAAE,QAAQA,EAAE;IAAQ,OAAOA,EAAE,UAAUA,EAAE;GAAQ,GAChE,GAAU,QAAQrG,EAAK,EAAE,sBAAsB,EAAE,OAAOyD,EAAI,IAAI4C,EAAE,MAAM,EAAE,CAAC,GAC3EogB,GAAQ,QAAQ,GAChBsB,GAAU,CAAC,MAEX,GAAa,QAAQ;IAAE,OAAO1hB,EAAE,UAAUA,EAAE;IAAS,SAASA,EAAE;IAAS,SAASA,EAAE;GAAQ,GAC5F,GAAO,QAAQrG,EAAK,EAAE,eAAe,EAAE,OAAOyD,EAAI,IAAI4C,EAAE,UAAUA,EAAE,OAAO,EAAE,CAAC,IAEhF,GAAW,QAAQ;IAAE,SAAS;IAAG,SAAS;IAAG,QAAQ;GAAE;EACzD,GACI2lB,KAAgB,IACdC,MAAe,MAAwC;GAC3D,IAAMlvB,IAAIiY,EAAM,YAAY+M,CAAO;GACnC,KAAgB/M,EAAM,QAAQ;GAC9B,IAAM3O,IAAIqlB,GAAW;GAErB,AADA,GAAW,QAAQ;IAAE,SAASrlB,EAAE,UAAUtJ,EAAE;IAAS,SAASsJ,EAAE,UAAUtJ,EAAE;IAAS,QAAQsJ,EAAE,SAAStJ,EAAE;GAAO,GAC5G6oB,EAAU,SAAOmG,GAAW;EACnC;EAKA,AAJAjW,GAAM8P,IAAY,MAAQ;GACxB,AAAK/hB,KAAKkoB,GAAW;EACvB,CAAC,GAEDjW,GAAMd,EAAM,UAAU,MAAM;GAE1B,AADIpV,MAAMosB,OAAe,GAAa,QAAQ,OAC1CJ,GAAO,SAAS,CAAC1K,EAAO,MAAM,cAAW,GAAO,QAAQ;EAC9D,CAAC;EACD,IAAMgL,KAAcnrB,QAAe;GACjC,IAAMkW,IAAIlC,EAAM,OAAO,OACjBvX,IAAIyZ,IAAI6Q,GAAiB,MAAM,QAAQ7Q,EAAE,KAAK,IAAI;GACxD,OAAOzZ,IAAI,IAAI,IAAIA,IAAI;EACzB,CAAC,GAEK2uB,WAAmB;GACvB,IAAMC,IAAoB,CACxB;IACEpsB,EAAK,EAAE,eAAe;IACtByL,EAAO,OAAO,UAAU/K,EAAM;IAC9BV,EAAK,EAAE,kBAAkB;IACzBA,EAAK,EAAE,mBAAmB;GAC5B,CACF;GACA,KAAK,IAAM0N,KAAKoa,GAAiB,OAAO;IACtC,IAAMzqB,IAAM2X,EAAM,SAAStH,CAAC,GACtB2e,IAAU5gB,EAAO,QAAQ5L,GAAU4L,EAAO,OAAOuJ,EAAM,KAAK3X,GAAKoO,EAAO,KAAK,CAAC,IAAIiC,GAClF4e,IAAStX,EAAM,SAAStH,CAAC;IAC/B,AAAI4e,KAAQF,EAAM,KAAK;KAAC,OAAOpX,EAAM,QAAQtH,CAAC,CAAC;KAAG2e;KAAS;KAAIC;IAAM,CAAC;IACtE,KAAK,IAAM,CAAC/d,GAAK2D,MAAU8C,EAAM,UAAUtH,CAAC,KAAK,CAAC,GAChD,AAAIwE,EAAM,UAAU,WAClBka,EAAM,KAAK;KAAC,OAAOpX,EAAM,QAAQtH,CAAC,CAAC;KAAG2e;KAASrW,EAAQ,MAAM,IAAIzH,CAAG,CAAC,EAAE,UAAUA;KAAK2D,EAAM;IAAO,CAAC;GAC1G;GACA,UAAe,WAAW,UAAUrV,GAAMuvB,CAAK,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;EAClE,GACMG,MAAY,MAAiC;GACjD,IAAI,GAAM,MAAMvX,EAAM,MAAM3X,CAAG,CAAC,GAChC,OAAOoO,EAAO,OAAO,OAAOpO,CAAG,KAAK4oB,GAAW,OAAO,OAAO5oB,CAAG;EAClE,GAGMmvB,KAAa3rB,EAAI,EAAK,GACtB4rB,KAAc1rB,QAAe;GACjC,EAAW,QAAQ;GACnB,IAAMqd,oBAAM,IAAI,IAAY,GACtB1e,IAAM+L,EAAO;GACnB,IAAI,CAAC/L,GAAK,OAAO0e;GACjB,KAAK,IAAMrhB,KAAKiY,EAAM,QAAQ,OAAO;IACnC,IAAMpV,IAAIoV,EAAM,cAAcjY,GAAG2C,CAAG;IACpC,AAAKrE,EAAauE,CAAC,KAAGwe,EAAI,IAAI,OAAOxe,CAAC,CAAC;GACzC;GACA,OAAOwe;EACT,CAAC,GACKpQ,MAAU,MAAgBye,GAAY,MAAM,IAAI5f,CAAG,GACnD6f,MAAe,MAAgC;GACnD,IAAI5F,EAAY,SAAS,CAACrb,EAAO,OAAO;GACxC,EAAK,OAAO;GACZ,IAAM/L,IAAM+L,EAAO,OACbkhB,oBAAa,IAAI,IAAiB;GACxC,KAAK,IAAM5vB,KAAKiY,EAAM,QAAQ,OAAO;IACnC,IAAMpV,IAAIoV,EAAM,cAAcjY,GAAG2C,CAAG;IACpC,AAAKrE,EAAauE,CAAC,KAAG+sB,EAAW,IAAI,OAAO/sB,CAAC,GAAG7C,CAAC;GACnD;GACA,IAAMyiB,IAA8B,CAAC,GAC/BM,IAA8C,CAAC,GAC/C8M,IAA0C,CAAC,GAC7C/K,IAAU,GACV3T,IAAO;GACX,KAAK,IAAMgN,KAAQ2R,EAAQ,MAAM;IAC/B,IAAIxvB,IAAMsvB,EAAW,IAAIzR,EAAK,GAAG;IACjC,IAAK7d,GAaE;SAbG;KACR,IAAI6d,EAAK,WAAW,QAAQ,CAAC2R,EAAQ,QAAQ;KAC7C,IAAI7X,EAAM,QAAQ,MAAM,SAAS8K,EAAU,SAAS,IAAIpf,EAAM,SAAS;KACvE,IAAM,CAACuW,KAAKjC,EAAM,QAAQ,CAAC;KAC3B,IAAI,CAACiC,GAAG;KAKR,AAJA,IAAMA,EAAE,KACR6I,EAAU,KAAK7I,CAAC,GAChB0V,EAAW,IAAIzR,EAAK,KAAK7d,CAAG,GAC5BmiB,EAAQ,KAAK;MAAE;MAAK;MAAK,OAAOtE,EAAK;KAAI,CAAC,GACtCA,EAAK,UACP0R,EAAM,KAAK;MAAE,KAAK3V,EAAE;MAAK,KAAKiE,EAAK;KAAO,CAAC,GAC3C,OACK;IACT;IACA,KAAK,IAAM,CAACpO,GAAIhN,MAAU,OAAO,QAAQob,EAAK,MAAM,GAAG;KACrD,IAAMhc,IAAI8W,EAAQ,MAAM,IAAIlJ,CAAE;KAC9B,AAAI5N,KAAK+nB,GAAQ5pB,GAAK6B,CAAC,KAAGsgB,EAAQ,KAAK;MAAE;MAAK,KAAKtgB;MAAG;KAAM,CAAC;IAC/D;GACF;GACA,KAAK,IAAMmX,KAAKuW,GAEd,AADA5X,EAAM,YAAYqB,EAAE,KAAK,QAAQ,GACjCrB,EAAM,QAAQqB,EAAE,KAAKA,EAAE,GAAG;GAI5B,AAFArB,EAAM,MAAMwK,GAASM,CAAS,GAC1BA,EAAU,UAAUqG,EAAM,UAAO,EAAM,QAAQ,CAAC,GAAGA,EAAM,OAAO,GAAGrG,EAAU,KAAK,MAAM7I,EAAE,GAAG,CAAC,IAClG+Q,GAAU;IACR,MAAMhoB,EAAK,EAAE,eAAe;KAC1B,OAAOyD,EAAI,IAAIopB,EAAQ,KAAK,MAAM;KAClC,SAASppB,EAAI,IAAIoe,CAAO;KACxB,MAAMpe,EAAI,IAAIyK,CAAI;IACpB,CAAC;IACD,MAAM;GACR,CAAC;GAED,IAAM4e,IAAWD,EAAQ,KAAK,EAAE,EAAE,KAC5BE,IAAWD,IAAWH,EAAW,IAAIG,CAAQ,IAAI,KAAA,GACjDtvB,IAAIuvB,IAAW9W,GAAW,MAAM,IAAIjB,EAAM,MAAM+X,CAAQ,CAAC,IAAI,KAAA;GACnE,AAAIvvB,MAAM,KAAA,KAAW0a,GAAU1a,GAAGkD,EAAM,SAAS;EACnD,GAEMssB,MAAc,GAAwB,MAA6B;GACvE,EAAK,OAAO;GACZ,IAAM5vB,KAAQ6vB,MAAU,QAAQjY,EAAM,QAAQ,QAAQ2R,EAAQ,MAAA,CAAO,KAAK,MAAM3R,EAAM,QAAQjY,CAAC,CAAC;GAChG,EAAK,UAAU;IAAE;IAAQ;IAAO,SAAS8pB,EAAY,MAAM,KAAK,MAAM3pB,EAAE,EAAE;IAAG;GAAK,CAAC;EACrF,GACMgwB,MAAe,MACnBltB,EAAK,EAAEitB,MAAU,QAAQ,oBAAoB,uBAAuB,EAClE,OAAOxpB,EAAI,IAAIwpB,MAAU,QAAQjY,EAAM,QAAQ,MAAM,SAAS2R,EAAQ,MAAM,MAAM,EACpF,CAAC,GACGwG,WAAiB,KAAK,UAAU,WAAW,UAAU,SAAS,IAAI,CAAC,CAAC,YAAY,CAAC,CAAC,GAElF7mB,KAAuB;GAC3B;GACA;GACA;GACA;GACA;GACA;GACA,YAAYuhB;GACZ;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF,GAGMuF,MAAoB,MAAoB;GAC5C,AAAKjG,EAAK,QAAQ,UACR,EAAE,QACL,QAAQ,mDAAmD,KAClEA,EAAK,OAAO;EACd,GAEMkG,WAAgBnM,EAAO,MAAM,eAAe,KAAKA,EAAO,MAAM,UAAU,GACxEoM,MAAkB,MAAyB;GAC/C,AAAKD,GAAQ,MACb,EAAE,eAAe,GACjB,EAAE,cAAc;EAClB;EAKA,AAJAxX,SAAgB;GAEd,AADA,SAAS,iBAAiB,eAAeuX,IAAkB,EAAI,GAC/D,OAAO,iBAAiB,gBAAgBE,EAAc;EACxD,CAAC,GACDxT,SAAsB;GAKpB,AAJA,SAAS,oBAAoB,eAAesT,IAAkB,EAAI,GAClE,OAAO,oBAAoB,gBAAgBE,EAAc,GACzD,aAAaC,EAAU,GACvB,aAAatC,EAAW,GACxBC,IAAW,MAAM;EACnB,CAAC;EAGD,IAAMsC,KAAUpG,GAA+C,SAAS,GAClEqG,MAAiB,MAAqB;GAC1C,IAAI,EAAE,oBAAoB,EAAE,EAAE,WAAW,EAAE,UAAU;GACrD,IAAM/f,IAAI,EAAE,IAAI,YAAY;GAC5B,AAAIA,MAAM,OACR,EAAE,eAAe,GACjB6C,GAAK,KACI7C,MAAM,OAAO,CAACiY,EAAW,UAClC,EAAE,eAAe,GACjB6H,GAAQ,OAAO,MAAM;EAEzB,GAGMxR,MAAQ,MAAcpf,EAAE,kBAAkB6X,EAAI,MAAM,GACpDiZ,KAAW7sB,EAAI,EAAE,GACjB8sB,KAAY9sB,EAAI,CAAC,GACjB+sB,KAAU7sB,QAAe;GAC7B,IAAM4F,IAAIqV,GAAK0R,GAAS,MAAM,KAAK,CAAC;GACpC,IAAI,CAAC/mB,GAAG,OAAO;GACf,EAAW,QAAQ;GACnB,IAAMgH,oBAAM,IAAI,IAAyB,GACnCkgB,IAAwC,CAAC,GACzCzwB,IAAOupB,EAAQ,OACfxO,IAAO0O,EAAY;GACzB,KAAK,IAAI9pB,IAAI,GAAGA,IAAIK,EAAK,QAAQ,KAAK;IACpC,IAAMC,IAAMD,EAAKL;IACjB,KAAK,IAAIG,IAAI,GAAGA,IAAIib,EAAK,QAAQ,KAAK;KACpC,IAAMzY,IAAMyY,EAAKjb,EAAE,CAAE,KACf0C,IAAIoV,EAAM,cAAc3X,GAAKqC,CAAG;KACtC,IAAIrE,EAAauE,CAAC,KAAK,CAACoc,GAAK7gB,EAAWuE,GAAKrC,GAAKuC,GAAGynB,EAAM,CAAC,CAAC,CAAC,SAAS1gB,CAAC,GAAG;KAC3E,IAAMkG,IAAMmI,EAAM,MAAM3X,CAAG,GACvB+gB,IAAMzQ,EAAI,IAAId,CAAG;KAGrB,AAFKuR,KAAKzQ,EAAI,IAAId,GAAM,oBAAM,IAAI,IAAI,CAAE,GACxCuR,EAAI,IAAI1e,EAAI,EAAY,GACxBmuB,EAAK,KAAK;MAAE;MAAG;KAAE,CAAC;IACpB;GACF;GACA,OAAO;IAAE;IAAK;GAAK;EACrB,CAAC,GACKC,MAAa,MAAc;GAC/B,IAAM7uB,IAAI2uB,GAAQ,OAAO,KAAKpwB;GAC9B,IAAI,CAACyB,GAAG;GACR,GAAU,QAAQzB;GAClB,IAAMH,IAAMspB,EAAQ,MAAM1nB,EAAE;GAE5B,AADA8V,EAAM,MAAMC,EAAM,MAAM3X,CAAG,GAAGwpB,EAAY,MAAM5nB,EAAE,EAAE,CAAE,EAAE,GACxDmG,GAAK,OAAO,cAAcnG,EAAE,CAAC;EAC/B;EACA,SACQ2uB,GAAQ,OAAO,KAAK,UAAU,SAC9BE,GAAU,CAAC,CACnB;EACA,IAAMC,MAAY,MAAgB;GAChC,IAAM5tB,IAAIytB,GAAQ,OAAO,KAAK,UAAU;GACxC,AAAIztB,KAAG2tB,KAAaH,GAAU,QAAQpmB,KAAOpH,IAAKA,KAAKA,CAAC;EAC1D,GACM6tB,MAAiB,MAAqB;GAC1C,AAAI,EAAE,QAAQ,WACZ,EAAE,eAAe,GACjBD,GAAS,EAAE,WAAW,KAAK,CAAC,KACnB,EAAE,QAAQ,YAAY,CAACL,GAAS,UACzC,EAAE,eAAe,GACjBtoB,GAAK,OAAO,YAAY;EAE5B,GACM6oB,KAAYltB,QAChB6sB,GAAQ,QACJ5tB,EAAK,EAAE,mBAAmB;GACxB,OAAO4tB,GAAQ,MAAM,KAAK,SAASD,GAAU,QAAQ,IAAI;GACzD,OAAOC,GAAQ,MAAM,KAAK;EAC5B,CAAC,IACD,EACN,GAGMM,KAAantB,SAAgB;GACjC,KAAKiU,EAAM,QAAQ,MAAM;GACzB,SAASkM,EAAO,MAAM;GACtB,QAAQA,EAAO,MAAM;EACvB,EAAE,GAGIiN,KAAYptB,QAAe;GAC/B,IAAMkW,IAAIlC,EAAM,OAAO;GACvB,OAAOkC,IAAKjC,EAAM,SAASiC,EAAE,KAAK,KAAK,OAAQ;EACjD,CAAC,GACKmX,KAAYrtB,QAAe;GAC/B,IAAMkW,IAAIlC,EAAM,OAAO;GACvB,OAAOkC,IAAKjB,EAAQ,MAAM,IAAIiB,EAAE,QAAQ,KAAK,OAAQ;EACvD,CAAC,GACKoX,KAAYttB,QAAe;GAC/B,IAAMsV,IAAItB,EAAM,OAAO;GACvB,IAAI,CAACsB,GAAG,OAAO;GACf,IAAMjZ,IAAOiZ,EAAE,cAAcA,EAAE,cAAc,GACvC8B,IAAO9B,EAAE,iBAAiBA,EAAE,iBAAiB;GACnD,OAAOjZ,IAAO+a,IAAO,IAAI;IAAE;IAAM;GAAK,IAAI;EAC5C,CAAC,GACKmW,KAAYvtB,QAAgBstB,GAAU,QAAQruB,EAAK,EAAE,eAAequB,GAAU,KAAK,IAAI,IAAK,GAC5FE,KAAUxtB,QACdotB,GAAU,SAAS1iB,EAAO,QAAQ5L,GAAU4L,EAAO,OAAOuJ,EAAM,KAAKmZ,GAAU,OAAO1iB,EAAO,KAAK,CAAC,IAAI,EACzG,GACM+iB,KAAcztB,QAAe;GACjC,IAAM,IAAIomB,EAAK,QAAQ;GAEvB,OADI,IAAU,EAAE,QAAQtnB,GAAU,EAAE,KAAK,EAAE,KAAK,IACzCsuB,GAAU,SAASC,GAAU,QAChCvuB,GAAUuuB,GAAU,OAAOpZ,EAAM,KAAKmZ,GAAU,OAAOC,GAAU,KAAK,CAAC,IACvE;EACN,CAAC,GACKK,KAAkB1tB,QAEpB,CAAC,CAACotB,GAAU,SACZ,CAAC,CAACC,GAAU,SACZA,GAAU,MAAM,SAAS,aACzBnH,GAAQkH,GAAU,OAAOC,GAAU,KAAK,CAC5C,GACMM,MAAkB,MAAa;GACnC,IAAMjxB,IAAQ,EAAE,OAA4B,OACtCJ,IAAM8wB,GAAU,OAChBzuB,IAAM0uB,GAAU;GACtB,AAAK/wB,KAAQqC,KAAQ+uB,GAAgB,UAChCtH,EAAK,QAAQ,SAAUA,EAAK,MAAM9pB,GAAKqC,GAAK,EAAE,QAAQ,GAAM,CAAC,MAClEynB,EAAK,SAAS1nB,GAAWC,GAAKjC,GAAMypB,GAAS,CAAC,GAAGzpB,GAAM,EAAK;EAC9D,GACMkxB,MAAoB,MAAqB;GAC7C,AAAI,EAAE,QAAQ,WACZ,EAAE,eAAe,GACbxH,EAAK,OAAO,KAAGpS,EAAM,KAAK,MAAM,GACpC3P,GAAK,OAAO,YAAY,KACf,EAAE,QAAQ,aACnB,EAAE,eAAe,GACjB+hB,EAAK,OAAO,GACZ/hB,GAAK,OAAO,YAAY;EAE5B,GACMwpB,KAAO7tB,QAAe;GAC1B,IAAM7B,IAAIkvB,GAAU;GACpB,IAAI,CAAClvB,GAAG,OAAO;GACf,IAAM2vB,IAAQ,CAAC7uB,EAAK,EAAErF,EAAauE,EAAE,IAAI,CAAC,CAAC;GAI3C,OAHIA,EAAE,SAAS,cAAc,OAAOA,EAAE,YAAa,YAAU2vB,EAAM,KAAK3vB,EAAE,QAAQ,GAC9EA,EAAE,YAAU2vB,EAAM,KAAK7uB,EAAK,EAAE,gBAAgB,CAAC,CAAC,kBAAkByU,EAAI,MAAM,CAAC,GAC7EvV,EAAE,QAAM2vB,EAAM,KAAK3vB,EAAE,IAAI,GACtB2vB,EAAM,KAAK,KAAK;EACzB,CAAC,GACKC,KAAY/tB,QAChBqtB,GAAU,QAAQpuB,EAAK,EAAE,mBAAmB;GAAE,QAAQouB,GAAU,MAAM;GAAQ,KAAKG,GAAQ;EAAM,CAAC,IAAI,EACxG,GAGMzgB,KAAU/M,QAAe;GAC7B,EAAW,QAAQ;GACnB,IAAMsV,IAAItB,EAAM,OAAO;GACvB,IAAI,CAACsB,KAAK,CAACgY,GAAU,OAAO,OAAO;GACnC,IAAInnB,IAAQ,GACR6nB,IAAM,GACNC,IAAU;GACd,KAAK,IAAIjyB,IAAIsZ,EAAE,aAAatZ,KAAKsZ,EAAE,aAAa,KAAK;IACnD,IAAMhZ,IAAMspB,EAAQ,MAAM5pB;IAC1B,IAAKM,GACL,KAAK,IAAIH,IAAImZ,EAAE,gBAAgBnZ,KAAKmZ,EAAE,gBAAgB,KAAK;KACzD,IAAM3W,IAAMmnB,EAAY,MAAM3pB,EAAE,CAAE,KAC5B0C,IAAIoV,EAAM,cAAc3X,GAAKqC,CAAG;KACtC,AAAIrE,EAAauE,CAAC,MAClB,KACInF,EAAWiF,EAAI,KAAK,CAAC,WAAW,OAAOE,KAAM,aAC/C,KAAOA,GACP;IAEJ;GACF;GACA,OAAO;IAAE;IAAO,KAAKovB,IAAUvrB,EAAI,QAAQsrB,GAAK,CAAC,IAAI;IAAM,KAAKC,IAAUvrB,EAAI,QAAQsrB,IAAMC,GAAS,CAAC,IAAI;GAAK;EACjH,CAAC,GAEKC,KAASluB,SAA6B;GAC1C,OAAO4kB,EAAW,QACd,YACAC,EAAU,QACR,WACAgG,GAAO,QACL,iBACAD,GAAa,QACX,UACA;GACV,GAAGzK,EAAO;EACZ,EAAE,GACIgO,KAAcnuB,QAClBmgB,EAAO,MAAM,eACTlhB,EAAK,EAAE,iBAAiB;GAAE,OAAOyD,EAAI,IAAIyd,EAAO,MAAM,YAAY;GAAG,MAAMzd,EAAI,IAAIyd,EAAO,MAAM,WAAW;EAAE,CAAC,IAC9GlhB,EAAK,EAAE,iBAAiB,CAC9B,GACMmvB,KAAU,GAAGnvB,EAAK,EAAE,YAAY,EAAE,KAAKzE,KACvC6zB,KAAU,GAAGpvB,EAAK,EAAE,aAAa,EAAE,IAAIxD,GAAS,IAChD6yB,KAAU,GAAGrvB,EAAK,EAAE,aAAa,EAAE,IAAI1D,GAAS,IAChDgzB,KAAUvuB,QAAe,CAAC+lB,EAAY,UAAU5F,EAAO,MAAM,eAAe,KAAKA,EAAO,MAAM,UAAU,EAAE,GAU1GqO,KAAQ1jB,EAAyB,IAAI,GACvC0hB,IACEvF,MAAa,MAAa;GAG9B,AAFA,GAAM,QAAQ3hB,GACd,aAAaknB,EAAU,GACvB,KAAa,iBAAkB,GAAM,QAAQ,MAAO,GAAI;EAC1D,GACMiC,WAAkB;GAEtB,AADA,GAAM,QAAQ,MACdnP,GAAK;EACP,GACMoP,WAAoB;GACxB,IAAMC,IAAMH,GAAM,OAAO,QAAQ;GAEjC,AADA,GAAM,QAAQ,MACdG,IAAM;EACR,GACMC,KAAS9uB,EAAI,EAAE,GACf+uB,KAAY/uB,EAAI,EAAE,GAEpBgvB,KAAmB;EACvB,GAAM/J,KAAU,MAAM;GACpB,IAAItnB,MAAM,MAAM;IACd,KAAmB;IACnB;GACF;GACA,IAAMmI,IAAI,KAAK,MAAMnI,IAAI,EAAE;GAC3B,AAAImI,MAAMkpB,MAAoBrxB,MAAM,MACpC,KAAmBmI,GACnB,GAAO,QAAQ3G,EAAK,EAAE2lB,EAAW,QAAQ,sBAAsB,oBAAoB,EAAE,SAAShf,IAAI,GAAG,CAAC;EACxG,CAAC;EAED,IAAMmpB,KAAcjvB,EAAI,EAAK,GACvBkvB,WAAgB;GASpB,AARA5I,EAAK,OAAO,GACZnS,EAAM,MAAM,GACZ,EAAM,QAAQ,MACd,GAAU,QAAQ,CAAC,GACnB,GAAO,QAAQ,MACf,GAAa,QAAQ,MACrB+V,GAAO,MAAM,GACbC,GAAQ,MAAM,GACd5lB,GAAK,OAAO,YAAY;EAC1B,GAEM4qB,KAAejvB,SAAgB;GACnC,SAASoU,EAAQ;GACjB,eAAesQ,EAAK,MAAM;GAC1B,SAAS3Q,GAAO,MAAM;GACtB,QAAQA,GAAO,OAAO;GACtB,YAAY2Q,EAAK;EACnB,EAAE,GACIwK,KAAY;GAChB,mBAAmB,MAAexK,EAAK,IAAI,EAAE,SAASvmB,EAAE,CAAC;GACzD,yBAAyB,MAAgBumB,EAAK,IAAI,EAAE,eAAeyK,EAAG,CAAC;GACvE,mBAAmB,GAAY,MAAqBpb,GAAO,WAAWhI,GAAIqjB,CAAO;GACjF,gBAAgB,GAAY,MAAkBrb,GAAO,KAAKhI,GAAIsjB,CAAK;GACnE,gBAAgB,MAAqB;IACnC,KAAK,IAAMlzB,KAAK4X,GAAO,MAAM,OAAO,AAAI,CAAC5X,EAAE,UAAUA,EAAE,WAAS4X,GAAO,WAAW5X,EAAE,IAAIizB,CAAO;GACjG;GACA,uBAAuBrb,GAAO,MAAM;GACpC,aAAa2Q,EAAK,MAAM;EAC1B,GAEM4K,KAASxvB,EAAwB,IAAI,GACrCyvB,KAAUj0B,GAAoBg0B,EAAM;E,OAE1C7b,EAAa;GACX;GACA;GACA,YAAYQ,EAAM;GAClB;GACA,OAAO+a;GACP;GACA;GACA,qBAAqBhI,GAAU,CAAC;EAClC,CAAC,I,UAICtvB,EAAA,GAAAC,EAsXM,OAAA;GArXA,SAAA;GAAJ,KAAI23B;GACJ,OAAK13B,GAAA,CAAC,eAAa,EAAA,YACGC,EAAAmtB,CAAA,EAAc,CAAA,CAAA;GACnC,gBAAc5Q,EAAA;GACd,WAASsY;;GAEC70B,EAAAmtB,CAAA,KAAXttB,EAAA,GAAAC,EAUM,OAVNgqB,IAUM,CATJ7pB,EAA2CD,EAAA23B,EAAA,GAAA;IAA/B,MAAM;IAAI,eAAY;G,IAClCz3B,EAOM,OAPN6pB,IAOM;IANJ7pB,EAAqD,UAAA,MAAAC,EAA1CH,EAAAoH,CAAA,CAAI,CAAC,EAAC,sBAAA,CAAA,GAAA,CAAA;IACjBlH,EAA4D,QAAA,MAAAC,EAAnDH,EAAAoH,CAAA,CAAI,CAAC,EAAC,uBAAA,EAAA,QAA0BwlB,EAAA,MAAM,CAAA,CAAA,GAAA,CAAA;IAC/C1sB,EAGS,UAAA;KAHD,MAAK;KAAS,OAAM;KAAmB,SAAOq0B;I,IACpDt0B,EAAwCD,EAAA43B,EAAA,GAAA;KAA/B,MAAM;KAAI,eAAY;I,IAASx3B,EAAA,MACxCD,EAAGH,EAAAoH,CAAA,CAAI,CAAC,EAAC,iBAAA,CAAA,GAAA,CAAA,C;;GAIflH,EA6JM,OA7JN8pB,IA6JM;IA5JO+C,EAAA,SAAcC,EAAA,SAAzBntB,EAAA,GAAAC,EAuBM,OAvBNmqB,IAuBM;KAtBJ/pB,EAQS,UAAA,MAAAC,EANL4sB,EAAA,QAA2B/sB,EAAAoH,CAAA,CAAI,CAAC,EAAC,iBAAA,EAAA,QAAoBwlB,EAAA,MAAM,CAAA,IAAoBK,EAAA,QAA2BjtB,EAAAoH,CAAA,CAAI,CAAC,EAAC,gBAAA;MAAA,MAAyBpH,EAAA6K,CAAA,CAAG,CAAC,IAAIoiB,EAAA,MAAS,IAAI;MAAA,OAAUjtB,EAAA6K,CAAA,CAAG,CAAC,IAAIoiB,EAAA,MAAS,KAAK;KAAA,CAAA,IAAuBjtB,EAAAoH,CAAA,CAAI,CAAC,EAAC,2BAAA,CAAA,GAAA,CAAA;KAOnN2lB,EAAA,SAAcE,EAAA,SAA1BptB,EAAA,GAAAC,EAEO,QAFPoqB,IAEO/pB,EADFH,EAAAoH,CAAA,CAAI,CAAC,EAAC,sBAAA;MAAA,QAAiCpH,EAAA6K,CAAA,CAAG,CAAC,IAAIoiB,EAAA,MAAS,IAAI;MAAA,OAAUjtB,EAAA6K,CAAA,CAAG,CAAC,IAAIoiB,EAAA,MAAS,KAAK;KAAA,CAAA,CAAA,GAAA,CAAA,K;KAEjG/sB,EASM,OAAA;MARJ,OAAKH,GAAA,CAAC,eAAa,EAAA,oBACWmtB,GAAA,UAAO,KAAA,CAAA,CAAA;MACrC,MAAK;MACL,iBAAc;MACd,iBAAc;MACb,iBAAeA,GAAA,SAAW,KAAA;K,IAE3BhtB,EAAiG,OAAA;MAA5F,OAAM;MAAoB,OAAKI,GAAE4sB,GAAA,UAAO,OAAuC,KAAA,IAAvC,EAAA,OAAA,GAAwBA,GAAA,MAAO,GAAA,CAAiB;;I,MAGjFltB,EAAAmtB,CAAA,KAAhBttB,EAAA,GAAAC,EASM,OAAA;;KAT0B,OAAM;KAAW,WAASs1B;I,IACxDn1B,EAMEM,GAAA;KALI,SAAA;KAAJ,KAAIq0B;KACH,eAAaE,GAAA;KACb,aAAa90B,EAAAoH,CAAA,CAAI,CAAC,EAAC,YAAA;KACnB,KAAKpH,EAAA+C,CAAA;KACL,uBAAkB,AAAAwG,EAAA,QAAG,MAAO,GAAA,QAAWvC;;;;;I,IAE9BquB,GAAA,SAAZx1B,EAAA,GAAAC,EAAiF,QAAjFsqB,IAAiFjqB,EAAnBk1B,GAAA,KAAS,GAAA,CAAA,K,oBAEzEx1B,EAAA,GAAAC,EA4FWU,GAAA,EAAA,KAAA,EAAA,GAAA;KA3FTN,EASM,OAAA;MATD,OAAM;MAAW,WAASk1B;K,IAC7Bn1B,EAMEM,GAAA;MALI,SAAA;MAAJ,KAAIq0B;MACH,eAAaE,GAAA;MACb,aAAa90B,EAAAoH,CAAA,CAAI,CAAC,EAAC,YAAA;MACnB,KAAKpH,EAAA+C,CAAA;MACL,uBAAkB,AAAAwG,EAAA,QAAG,MAAO,GAAA,QAAWvC;;;;;K,IAE9BquB,GAAA,SAAZx1B,EAAA,GAAAC,EAAiF,QAAjFuqB,IAAiFlqB,EAAnBk1B,GAAA,KAAS,GAAA,CAAA,K;KAEzE,AAAA9rB,EAAA,QAAArJ,EAAkD,QAAA;MAA5C,OAAM;MAAiB,eAAY;;KACzCD,EAmBkBD,EAAA63B,EAAA,GAAA;MAlBhB,OAAM;MACN,MAAK;MACJ,eAAarK,GAAA;MACb,cAAYxtB,EAAAoH,CAAA,CAAI,CAAC,EAAC,gBAAA;MAClB,uBAAkB,AAAAmC,EAAA,QAAG,MAAMvC,KAAK6mB,GAAQ7mB,CAAC;;MAE1C,SAAAvG,QAGkB;OAHlBR,EAGkBD,EAAA83B,EAAA,GAAA;QAHD,OAAM;QAAc,OAAM;;QACzC,SAAAr3B,QAAyB,CAAtBL,EAAAD,EAAAH,EAAAoH,CAAA,CAAI,CAAC,EAAC,WAAA,CAAA,IAAgB,KACzB,CAAA,GAAAlH,EAA+D,QAA/DoqB,IAA+DnqB,EAAjCH,EAAA6K,CAAA,CAAG,CAAC,IAAIyqB,GAAA,MAAW,GAAG,CAAA,GAAA,CAAA,C;;;OAEtDr1B,EAGkBD,EAAA83B,EAAA,GAAA;QAHD,OAAM;QAAc,OAAM;;QACzC,SAAAr3B,QAA6B,CAA1BL,EAAAD,EAAAH,EAAAoH,CAAA,CAAI,CAAC,EAAC,eAAA,CAAA,IAAoB,KAC7B,CAAA,GAAAlH,EAAmE,QAAnEqqB,IAAmEpqB,EAArCH,EAAA6K,CAAA,CAAG,CAAC,IAAIyqB,GAAA,MAAW,OAAO,CAAA,GAAA,CAAA,C;;;OAE1Dr1B,EAGkBD,EAAA83B,EAAA,GAAA;QAHD,OAAK/3B,GAAA,CAAC,eAAa,EAAA,aAAwBu1B,GAAA,MAAW,SAAM,EAAA,CAAA,CAAA;QAAQ,OAAM;;QACzF,SAAA70B,QAA4B,CAAzBL,EAAAD,EAAAH,EAAAoH,CAAA,CAAI,CAAC,EAAC,cAAA,CAAA,IAAmB,KAC5B,CAAA,GAAAlH,EAAkE,QAAlEsqB,IAAkErqB,EAApCH,EAAA6K,CAAA,CAAG,CAAC,IAAIyqB,GAAA,MAAW,MAAM,CAAA,GAAA,CAAA,C;;;;;;KAG3Dp1B,EASS,UAAA;MARP,MAAK;MACL,OAAM;MACL,iBAAeF,EAAAoc,CAAA,CAAK,CAAC,QAAQ,QAAQ,KAAA,IAAS;MAC9C,cAAYoa;MACZ,eAAaA;MACb,SAAK,AAAAjtB,EAAA,QAAA,MAAEvJ,EAAAoc,CAAA,CAAK,CAAC,QAAQ,SAASqL,GAAI;K,IAEnCxnB,EAAgDD,EAAA+3B,EAAA,GAAA;MAA/B,MAAM;MAAI,eAAY;;KAEzC73B,EASS,UAAA;MARP,MAAK;MACL,OAAM;MACL,iBAAeF,EAAAoc,CAAA,CAAK,CAAC,QAAQ,QAAQ,KAAA,IAAS;MAC9C,cAAYqa;MACZ,eAAaA;MACb,SAAK,AAAAltB,EAAA,QAAA,MAAEvJ,EAAAoc,CAAA,CAAK,CAAC,QAAQ,SAASsL,GAAI;K,IAEnCznB,EAAiDD,EAAAg4B,EAAA,GAAA;MAA/B,MAAM;MAAI,eAAY;;KAE1C,AAAAzuB,EAAA,QAAArJ,EAAkD,QAAA;MAA5C,OAAM;MAAiB,eAAY;;KACzCA,EAGS,UAAA;MAHD,MAAK;MAAS,OAAM;MAA6C,SAAK,AAAAqJ,EAAA,QAAA,MAAE6nB,GAAM;K,IACpFnxB,EAAwCD,EAAAsa,EAAA,GAAA;MAA/B,MAAM;MAAI,eAAY;K,IAASla,EAAA,MACxCD,EAAGH,EAAAoH,CAAA,CAAI,CAAC,EAAC,cAAA,CAAA,GAAA,CAAA,C;KAGHW,EAAA,aADRlI,EAAA,GAAAC,EAQS,UAAA;;MANP,MAAK;MACL,OAAM;MACL,SAAK,AAAAyJ,EAAA,QAAA,MAAE,GAAA,QAAU;K,IAElBtJ,EAAkDD,EAAAi4B,EAAA,GAAA;MAA/B,MAAM;MAAI,eAAY;K,IAAS73B,EAAA,MAClDD,EAAGH,EAAAoH,CAAA,CAAI,CAAC,EAAC,cAAA,CAAA,GAAA,CAAA,C;KAEXnH,EAwBmBD,EAAAk4B,EAAA,GAAA,MAAA;MAvBjB,SAAAz3B,QAKsB,CALtBR,EAKsBD,EAAAm4B,EAAA,GAAA,EALD,YAAA,GAAQ,GAAA;OAC3B,SAAA13B,QAGS,CAHTP,EAGS,UAHTyqB,IAGS,CAFP1qB,EAA0CD,EAAAo4B,EAAA,GAAA;QAA/B,MAAM;QAAI,eAAY;O,IAASh4B,EAAA,MAC1CD,EAAGH,EAAAoH,CAAA,CAAI,CAAC,EAAC,cAAA,CAAA,GAAA,CAAA,C;;M,IAGbnH,EAgBqBD,EAAAq4B,EAAA,GAAA,MAAA;OAfnB,SAAA53B,QAcsB,CAdtBR,EAcsBD,EAAAs4B,EAAA,GAAA;QAdD,OAAM;QAAU,OAAM;QAAS,eAAa;;QAC9C,SAAA73B,QAA4C,EAA7DZ,EAAA,GAAAC,EAYkBU,GAAA,MAAAE,GAZe,CAAA,OAAA,SAAA,IAAT,MAAxBT,EAYkBD,EAAAu4B,EAAA,GAAA,EAZ6C,KAAKlE,EAAK,GAAA;SACvE,SAAA5zB,QAA8F,CAA9FR,EAA8FD,EAAAw4B,EAAA,GAAA,EAAtE,OAAM,eAAc,GAAA;UAAC,SAAA/3B,QAAwB,CAArBL,EAAAD,EAAAm0B,GAAYD,CAAK,CAAA,GAAA,CAAA,C;;S,UACjEp0B,EASqBD,EAAAq4B,EAAA,GAAA,MAAA;UARnB,SAAA53B,QAOyB,CAPzBR,EAOyBD,EAAAy4B,EAAA,GAAA;WAPD,OAAM;WAAW,eAAa;;WACpD,SAAAh4B,QAEmB,CAFnBR,EAEmBD,EAAA04B,EAAA,GAAA;YAFD,OAAM;YAAgB,WAAM,MAAEtE,GAAU,QAASC,CAAK;;YACtE,SAAA5zB,QAA4B,CAAzBL,EAAAD,EAAAH,EAAAoH,CAAA,CAAI,CAAC,EAAC,cAAA,CAAA,GAAA,CAAA,C;;W,qBAEXnH,EAEmBD,EAAA04B,EAAA,GAAA;YAFD,OAAM;YAAgB,WAAM,MAAEtE,GAAU,OAAQC,CAAK;;YACrE,SAAA5zB,QAA2B,CAAxBL,EAAAD,EAAAH,EAAAoH,CAAA,CAAI,CAAC,EAAC,aAAA,CAAA,GAAA,CAAA,C;;;;;;;;;;;;;;;KAQvBnH,EAAyDU,GAAzDC,GAAwBw2B,GAAiC,OAAnBv2B,GAAMw2B,EAAS,CAAA,GAAA,MAAA,EAAA;;IAEvD,AAAA9tB,EAAA,QAAArJ,EAAkC,QAAA,EAA5B,OAAM,oBAAmB,GAAA,MAAA,EAAA;IACfF,EAAAmtB,CAAA,KAAhBttB,EAAA,GAAAC,EAAkCU,GAAA,EAAA,KAAA,EAAA,GAAA,CAAA,GAAA,EAAA,KAChBwsB,EAAA,Q,aAAlBntB,EAAA,GAAAC,EAIO,QAAA;;KAJsB,OAAKC,GAAA,CAAC,oBAAkB,EAAA,YAAA,CAAwBC,EAAAsoB,CAAA,CAAM,CAAC,aAAY,CAAA,CAAA;;KAClFtoB,EAAAsoB,CAAA,CAAM,CAAC,gBAAnBzoB,EAAA,GAAAC,EAA2E,QAA3E8qB,EAA2E,K;KAAAxqB,EAAA,MAC3ED,EAAGm2B,GAAA,KAAW,IAAG,KACjB,CAAA;KAAgBt2B,EAAAsoB,CAAA,CAAM,CAAC,WAAvBzoB,EAAA,GAAAC,EAAsGU,GAAA,EAAA,KAAA,EAAA,GAAA,CAAtEJ,EAAA,OAAED,EAAGH,EAAAoH,CAAA,CAAI,CAAC,EAAC,kBAAA,EAAA,OAA4BpH,EAAAsoB,CAAA,CAAM,CAAC,QAAO,CAAA,CAAA,GAAA,CAAA,C;;IAG9EtoB,EAAAmtB,CAAA,I,aADTttB,EAAA,GAAAC,EAQS,UAAA;;KANP,MAAK;KACL,OAAM;KACL,UAAUktB,EAAA,SAAS,CAAMhtB,EAAAsoB,CAAA,CAAM,CAAC,gBAAY,CAAKtoB,EAAAsoB,CAAA,CAAM,CAAC;KACxD,SAAK,AAAA/e,EAAA,QAAA,MAAE,GAAA,QAAW;IAEhB,GAAApJ,EAAAH,EAAAoH,CAAA,CAAI,CAAC,EAAC,eAAA,CAAA,GAAA,GAAAyjB,EAAA;IAGF7qB,EAAAmtB,CAAA,I,aADTttB,EAAA,GAAAC,EAYS,UAAA;;KAVP,MAAK;KACL,OAAM;KACL,UAAQ,CAAGktB,EAAA,SAAS,CAAK0J,GAAA;KACzB,iBAAe1J,EAAA,QAAS,SAAY,KAAA;KACpC,eAAaA,EAAA,QAAY,KAAA,IAAYuJ;KACrC,SAAK,AAAAhtB,EAAA,QAAA,MAAA,CAAGyjB,EAAA,SAAarV,GAAI;I,IAELqV,EAAA,SAArBntB,EAAA,GAAAiB,EAAgFd,EAAAka,EAAA,GAAA;;KAA/C,MAAM;KAAI,OAAM;KAAU,eAAY;I,OACvEra,EAAA,GAAAiB,EAAgDd,EAAAmO,EAAA,GAAA;;KAA/B,MAAM;KAAI,eAAY;I,KAAS/N,EAAA,MAChDD,EAAG6sB,EAAA,QAAYhtB,EAAAoH,CAAA,CAAI,CAAC,EAAC,oBAAA,IAAyBpH,EAAAoH,CAAA,CAAI,CAAC,EAAC,YAAA,CAAA,GAAA,CAAA,C;;GAI7C4rB,GAAA,SAAXnzB,EAAA,GAAAC,EAqBM,OArBNirB,IAqBM;IApBJ9qB,EAAiDD,EAAA8W,EAAA,GAAA;KAA/B,MAAM;KAAI,eAAY;;IACxC5W,EAGO,QAAA,MAAA,CAFLA,EAAsF,UAAA,MAAAC,EAA3EH,EAAAoH,CAAA,CAAI,CAAC,EAAC,sBAAA,EAAA,OAAgCpH,EAAA6K,CAAA,CAAG,CAAC,IAAImoB,GAAA,MAAO,MAAM,EAAA,CAAA,CAAA,GAAA,CAAA,GAAgB5yB,EAAA,MACtFD,EAAGH,EAAAoH,CAAA,CAAI,CAAC,EAAC,qBAAA,EAAA,OAA+BpH,EAAA6K,CAAA,CAAG,CAAC,IAAImoB,GAAA,MAAO,KAAK,EAAA,CAAA,CAAA,GAAA,CAAA,C;IAE9D,AAAAzpB,EAAA,QAAArJ,EAAiC,QAAA,EAA3B,OAAM,mBAAkB,GAAA,MAAA,EAAA;IAC9BA,EAQO,QARP8qB,IAQO;KAPL9qB,EAES,UAAA;MAFD,MAAK;MAAS,OAAM;MAAiB,cAAYF,EAAAoH,CAAA,CAAI,CAAC,EAAC,iBAAA;MAAsB,SAAK,AAAAmC,EAAA,QAAA,MAAE4lB,GAAS,EAAA;K,IACnGlvB,EAA2CD,EAAA64B,EAAA,GAAA;MAA/B,MAAM;MAAI,eAAY;;KAEpC34B,EAAoG,QAAA,MAAAC,EAA3FH,EAAAoH,CAAA,CAAI,CAAC,EAAC,mBAAA;MAAA,OAA6BksB,GAAA;MAAW,OAASpE,GAAA,MAAiB;KAAM,CAAA,CAAA,GAAA,CAAA;KACvFhvB,EAES,UAAA;MAFD,MAAK;MAAS,OAAM;MAAiB,cAAYF,EAAAoH,CAAA,CAAI,CAAC,EAAC,iBAAA;MAAsB,SAAK,AAAAmC,EAAA,SAAA,MAAE4lB,GAAS,CAAA;K,IACnGlvB,EAA6CD,EAAA84B,EAAA,GAAA;MAA/B,MAAM;MAAI,eAAY;;;IAGxC,AAAAvvB,EAAA,QAAArJ,EAAiD,QAAA;KAA3C,OAAM;KAAgB,eAAY;;IACxCA,EAGS,UAAA;KAHD,MAAK;KAAS,OAAM;KAAkB,SAAOqzB;I,IACnDtzB,EAAwCD,EAAA+4B,EAAA,GAAA;KAA/B,MAAM;KAAI,eAAY;I,IAAS34B,EAAA,MACxCD,EAAGH,EAAAoH,CAAA,CAAI,CAAC,EAAC,kBAAA,CAAA,GAAA,CAAA,C;;GAGFmO,GAAA,SAAX1V,EAAA,GAAAC,EAGM,OAHNqrB,IAGM,CAFJlrB,EAA2CD,EAAAg5B,EAAA,GAAA;IAA/B,MAAM;IAAI,eAAY;G,IAClC94B,EAA4E,QAAA,MAAAC,EAAnEH,EAAAoH,CAAA,CAAI,CAAC,EAAC,gBAAA;IAAA,KAAwBpH,EAAA6K,CAAA,CAAG,CAAC,IAAI9C,EAAA,OAAO;IAAA,QAAG6kB,EAAA;GAAM,CAAA,CAAA,GAAA,CAAA,C;GAGrD5sB,EAAAmtB,CAAA,I,aAAZttB,EAAA,GAAAC,EAwBM,OAxBNsrB,IAwBM;IAvBJlrB,EAMM,OANNmrB,IAMM,CALYqK,GAAA,SAAhB71B,EAAA,GAAAC,EAAqDU,GAAA,EAAA,KAAA,EAAA,GAAA,CAAvBJ,EAAAD,EAAAu1B,GAAA,KAAS,GAAA,CAAA,C,UAClBF,GAAA,SAArB31B,EAAA,GAAAC,EAGWU,GAAA,EAAA,KAAA,EAAA,GAAA,CAFTN,EAA0C,QAA1CorB,IAA0CnrB,EAAjBw1B,GAAA,KAAO,GAAA,CAAA,GAChCz1B,EAA4D,QAA5DqrB,IAA6B,OAAEprB,EAAGq1B,GAAA,MAAU,MAAM,GAAA,CAAA,C;IAGtD,AAAAjsB,EAAA,QAAArJ,EAAwD,QAAA;KAAlD,OAAM;KAAgB,eAAY;IAAO,GAAA,MAAE,EAAA;IACjDA,EASE,SAAA;KARA,OAAM;KACN,MAAK;KACJ,OAAO01B,GAAA;KACP,UAAQ,CAAGC,GAAA;KACX,cAAYK,GAAA;KACb,cAAa;KACZ,SAAOJ;KACP,WAASC;;IAEA/I,EAAA,SAAZntB,EAAA,GAAAC,EAGO,QAHP2rB,IAGO,CAFLxrB,EAAwCD,EAAA2W,EAAA,GAAA;KAA/B,MAAM;KAAI,eAAY;I,IAASvW,EAAA,MACxCD,EAAGH,EAAAoH,CAAA,CAAI,CAAC,EAAC,sBAAA,CAAA,GAAA,CAAA,C,MAEM4uB,GAAA,SAAjBn2B,EAAA,GAAAC,EAAgE,QAAhE4rB,IAAgEvrB,EAAd61B,GAAA,KAAI,GAAA,CAAA,K;;GAGxD/1B,EAsBYc,IAAA;IArBN,SAAA;IAAJ,KAAIyL;IACI;IACP,QAAQxM,EAAAkc,EAAA;IACR,MAAM6R,EAAA;IACN,SAASxR,EAAA;IACT,OAAOqQ,EAAA,MAAO;IACd,QAAQA,EAAA;IACR,SAASG,EAAA;IACT,UAAUA,EAAA;IACV,aAAWC,EAAA;IACX,kBAAgBhtB,EAAA6sB,CAAA,CAAI,CAAC,MAAM;IAC3B,cAAY9kB,EAAA;IACZ,OAAOitB,GAAA,OAAS,OAAG;IACnB,MAAM9C,GAAA;IACN,OAAOlyB,EAAAmtB,CAAA;G,iBAES,CAAAJ,EAAA,SAAcgB,EAAA,MAAQ,WAAM,I;IAAS,MAAA;IACpD,IAAAttB,QAEO,CAFPQ,GAEOshB,EAAA,QAAA,SAAA,CAAA,SAAA,CADLtiB,EAA6EiB,GAAA;KAA/D,MAAK;KAAS,OAAOlB,EAAAoH,CAAA,CAAI,CAAC,EAAC,oBAAA,EAAA,QAAuBwlB,EAAA,MAAM,CAAA;;;;;;;;;;;;;;;;;;GAKjE5sB,EAAAmtB,CAAA,KAAXttB,EAAA,GAAAC,EAOM,OAPN6rB,IAOM;IANJzrB,EAAyG,QAAA,MAAAC,EAAhGH,EAAAoH,CAAA,CAAI,CAAC,EAAC,wBAAA;KAAA,OAAkCpH,EAAA6K,CAAA,CAAG,CAAC,IAAI7K,EAAAoc,CAAA,CAAK,CAAC,QAAQ,MAAM,MAAM;KAAA,QAAGwQ,EAAA;IAAM,CAAA,CAAA,GAAA,CAAA;IAC5F,AAAArjB,EAAA,QAAArJ,EAAiC,QAAA,EAA3B,eAAY,OAAM,GAAC,KAAC,EAAA;IAC1BA,EAGO,QAHP0rB,IAGO,CAFL3rB,EAAwCD,EAAA2W,EAAA,GAAA;KAA/B,MAAM;KAAI,eAAY;I,IAASvW,EAAA,MACxCD,EAAGH,EAAAoH,CAAA,CAAI,CAAC,EAAC,sBAAA,CAAA,GAAA,CAAA,C;G,OAGbvH,EAAA,GAAAC,EA+CM,OAAA;;IA/CM,OAAM;IAAY,MAAK;IAAU,cAAYE,EAAAoH,CAAA,CAAI,CAAC,EAAC,kBAAA;G,IAC7DlH,EAIO,QAJP4rB,IAIO3rB,EAFH4sB,EAAA,QAAa/sB,EAAAoH,CAAA,CAAI,CAAC,EAAC,gBAAA,IAAqBpH,EAAAoH,CAAA,CAAI,CAAC,EAAC,cAAA,EAAA,OAAwBpH,EAAA6K,CAAA,CAAG,CAAC,IAAI7K,EAAAoc,CAAA,CAAK,CAAC,QAAQ,MAAM,MAAM,EAAA,CAAA,CAAA,GAAA,CAAA,GAG3F2Q,EAAA,Q,aAAjBltB,EAAA,GAAAC,EAwCWU,GAAA,EAAA,KAAA,EAAA,GAAA;IAvCGuyB,GAAA,SAAZlzB,EAAA,GAAAC,EAYO,QAZPisB,IAYO;KAXL9rB,EAAyCD,EAAAmO,EAAA,GAAA;MAA/B,MAAM;MAAI,eAAY;;KAChCjO,EAAoF,UAAA,MAAAC,EAAzEH,EAAAoH,CAAA,CAAI,CAAC,EAAC,eAAA,EAAA,OAAyBpH,EAAA6K,CAAA,CAAG,CAAC,IAAIkoB,GAAA,MAAa,KAAK,EAAA,CAAA,CAAA,GAAA,CAAA;KACpE7yB,EAQO,QAAA,MARD,QAEJC,EACEH,EAAAoH,CAAA,CAAI,CAAC,EAAC,qBAAA;MAAiD,SAAApH,EAAA6K,CAAA,CAAG,CAAC,IAAIkoB,GAAA,MAAa,OAAO;MAA4B,SAAA/yB,EAAA6K,CAAA,CAAG,CAAC,IAAIkoB,GAAA,MAAa,OAAO;;I,MAOhI/yB,EAAAsoB,CAAA,CAAM,CAAC,gBAAxBzoB,EAAA,GAAAC,EAGO,QAHPksB,IAGO,CAFL,AAAAziB,EAAA,QAAArJ,EAAsD,QAAA;KAAhD,OAAM;KAAqB,eAAY;I,cAASE,EAAA,MACtDD,EAAGm2B,GAAA,KAAW,GAAA,CAAA,C,OAEhBz2B,EAAA,GAAAC,EAA6D,QAA7DmsB,IAA6D9rB,EAArBm2B,GAAA,KAAW,GAAA,CAAA;IACvCt2B,EAAAsoB,CAAA,CAAM,CAAC,WAAnBzoB,EAAA,GAAAC,EAEO,QAFPosB,IAEO/rB,EADFH,EAAAoH,CAAA,CAAI,CAAC,EAAC,iBAAA,EAAA,OAA2BpH,EAAAsoB,CAAA,CAAM,CAAC,QAAO,CAAA,CAAA,GAAA,CAAA,K;IAEtCtoB,EAAAsoB,CAAA,CAAM,CAAC,aAArBzoB,EAAA,GAAAC,EAGS,UAAA;;KAHuB,MAAK;KAAS,OAAM;KAAoB,SAAK,AAAAyJ,EAAA,SAAA,MAAE4lB,GAAS,CAAA;I,IACtF,AAAA5lB,EAAA,QAAArJ,EAAoD,QAAA;KAA9C,OAAM;KAAmB,eAAY;I,cAASE,EAAA,MACpDD,EAAGH,EAAAoH,CAAA,CAAI,CAAC,EAAC,oBAAA,EAAA,OAA8BpH,EAAAsoB,CAAA,CAAM,CAAC,UAAS,CAAA,CAAA,GAAA,CAAA,C;IAE7CpT,GAAA,SAAZrV,EAAA,GAAAC,EAaO,QAAA;;KAbc,OAAM;KAAqB,cAAYE,EAAAoH,CAAA,CAAI,CAAC,EAAC,wBAAA;;KAChElH,EAGO,QAAA,MAAA,CAFFE,EAAAD,EAAAH,EAAAoH,CAAA,CAAI,CAAC,EAAC,iBAAA,CAAA,IAAsB,KAC/B,CAAA,GAAAlH,EAAmC,KAAA,MAAAC,EAA7BH,EAAA6K,CAAA,CAAG,CAAC,IAAIqK,GAAA,MAAQ,KAAK,CAAA,GAAA,CAAA,C;KAEjBA,GAAA,MAAQ,QAAG,O,aAAvBrV,EAAA,GAAAC,EAGO,QAAAssB,IAAA,CAFFhsB,EAAAD,EAAAH,EAAAoH,CAAA,CAAI,CAAC,EAAC,eAAA,CAAA,IAAoB,KAC7B,CAAA,GAAAlH,EAAwB,KAAA,MAAAC,EAAlB+U,GAAA,MAAQ,GAAG,GAAA,CAAA,C;KAEPA,GAAA,MAAQ,QAAG,O,aAAvBrV,EAAA,GAAAC,EAGO,QAAAusB,IAAA,CAFFjsB,EAAAD,EAAAH,EAAAoH,CAAA,CAAI,CAAC,EAAC,eAAA,CAAA,IAAoB,KAC7B,CAAA,GAAAlH,EAAwB,KAAA,MAAAC,EAAlB+U,GAAA,MAAQ,GAAG,GAAA,CAAA,C;;;GAMdyhB,GAAA,SAAX92B,EAAA,GAAAC,EAmBM,OAnBNwsB,IAmBM;IAlBJpsB,EAAiC,UAAA,MAAAC,EAAtBw2B,GAAA,MAAM,IAAI,GAAA,CAAA;IACLA,GAAA,MAAM,UAAtB92B,EAAA,GAAAC,EAMWU,GAAA,EAAA,KAAA,EAAA,GAAA;KALT,AAAA+I,EAAA,QAAArJ,EAAiC,QAAA,EAA3B,eAAY,OAAM,GAAC,KAAC,EAAA;KAC1BA,EAAqD,QAArDqsB,IAAqDpsB,EAAtBw2B,GAAA,MAAM,MAAM,GAAA,CAAA;KAC7BA,GAAA,MAAM,UAApB92B,EAAA,GAAAC,EAES,UAAA;;MAFmB,MAAK;MAAS,OAAM;MAAiB,SAAK,AAAAyJ,EAAA,SAAA,MAAEotB,GAAA,MAAM,OAAM;KAC/E,GAAAx2B,EAAAH,EAAAoH,CAAA,CAAI,CAAC,EAAC,cAAA,CAAA,GAAA,CAAA,K;;IAGCuvB,GAAA,MAAM,UAApB92B,EAAA,GAAAC,EAES,UAAA;;KAFmB,MAAK;KAAS,OAAM;KAAiB,SAAO+2B;IACnE,GAAA12B,EAAAw2B,GAAA,MAAM,OAAO,KAAK,GAAA,CAAA,K;IAEPA,GAAA,MAAM,QAAtB92B,EAAA,GAAAC,EAMWU,GAAA,EAAA,KAAA,EAAA,GAAA,CALT,AAAA+I,EAAA,QAAArJ,EAAgD,QAAA;KAA1C,OAAM;KAAe,eAAY;I,cACvCA,EAGS,UAAA;KAHD,MAAK;KAAS,OAAM;KAAiB,SAAO02B;I,IAC/Cx2B,EAAAD,EAAAH,EAAAoH,CAAA,CAAI,CAAC,EAAC,aAAA,CAAA,IAAkB,KAC3B,CAAA,GAAAlH,EAAwC,OAAxCssB,IAAwCrsB,EAAjBH,EAAA4D,EAAA,CAAQ,GAAA,CAAA,C;;GAIrC1D,EAA+D,QAA/DusB,IAA+DtsB,EAAhB42B,GAAA,KAAM,GAAA,CAAA;GACrD72B,EAAqE,QAArEwsB,IAAqEvsB,EAAnB62B,GAAA,KAAS,GAAA,CAAA;GAC3D71B,GAAAjB,EAQM,OAAA;IANJ,OAAKH,GAAA,CAAC,UAAQ,EAAA,YACQC,EAAA03B,EAAA,CAAO,CAAC,KAAK,MAAM,SAAQ,IAAA,EAAA,CAAA,CAAA;IACjD,MAAK;IACJ,OAAKp3B,GAAEN,EAAA03B,EAAA,CAAO,CAAC,MAAM,KAAK;GAExB,GAAAv3B,EAAAH,EAAA03B,EAAA,CAAO,CAAC,KAAK,KAAK,GAAA,CAAA,GAAA,CANb,CAAAt2B,IAAApB,EAAA03B,EAAA,CAAO,CAAC,KAAK,KAAK,C;GAQ5Bz3B,EAQEoB,IAAA;IAPQ,MAAM61B,GAAA;IAAA,iBAAA,AAAA3tB,EAAA,SAAA,MAAA,GAAW,QAAAC;IACxB,OAAOxJ,EAAAoH,CAAA,CAAI,CAAC,EAAC,uBAAA;KAAA,OAAiCpH,EAAA6K,CAAA,CAAG,CAAC,IAAI7K,EAAAsoB,CAAA,CAAM,CAAC,YAAY;KAAA,MAAStoB,EAAA6K,CAAA,CAAG,CAAC,IAAI7K,EAAAsoB,CAAA,CAAM,CAAC,WAAW;IAAA,CAAA;IAC5G,MAAMtoB,EAAAoH,CAAA,CAAI,CAAC,EAAC,oBAAA;IACZ,iBAAepH,EAAAoH,CAAA,CAAI,CAAC,EAAC,qBAAA;IACrB,gBAAcpH,EAAAoH,CAAA,CAAI,CAAC,EAAC,oBAAA;IACrB,QAAA;IACC,WAAS+vB;;;;;;;;GAGJpvB,EAAA,aAAa6rB,GAAA,SADrB/zB,EAAA,GAAAiB,EAcEQ,IAAA;;IAZQ,MAAMsyB,GAAA;IAAA,iBAAA,AAAArqB,EAAA,SAAA,MAAA,GAAU,QAAAC;IACvB,cAAYzB,EAAA;IACZ,SAASqlB,EAAA;IACT,cAAYrlB,EAAA;IACZ,QAAQ6kB,EAAA;IACR,YAAU7kB,EAAA;IACV,aAAW/H,EAAAoc,CAAA,CAAK,CAAC,QAAQ,MAAM;IAC/B,WAAShH;IACT,eAAarN,EAAA;IACb,aAAWumB;IACX,WAASG;IACT,SAAOqF;;;;;;;;;;;GAGFlB,GAAA,SADR/yB,EAAA,GAAAiB,EAOES,IAAA;;IALQ,MAAMqxB,GAAA;IAAA,iBAAA,AAAArpB,EAAA,SAAA,MAAA,GAAe,QAAAC;IAC5B,QAAQqpB,GAAA;IACR,WAAS7yB,EAAAoc,CAAA,CAAK,CAAC,WAAU,CAAA,CAAG,KAAK;IACjC,OAAK8W;IACL,QAAMD"}
1
+ {"version":3,"file":"sheet.js","names":["fold","_hoisted_1","_hoisted_2","_hoisted_3","_openBlock","_createElementBlock","_createElementVNode","_toDisplayString","_createCommentVNode","_sfc_main","_openBlock","_createBlock","_unref","_withCtx","_createVNode","_createElementBlock","_Fragment","_renderList","_createElementVNode","_createTextVNode","_toDisplayString","_sfc_main","_hoisted_1","_hoisted_2","_openBlock","_createElementBlock","_sfc_main","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_openBlock","_createElementBlock","_createElementVNode","_createVNode","_unref","_withCtx","_toDisplayString","_createCommentVNode","_Fragment","_renderList","_createBlock","_createTextVNode","_sfc_main","_openBlock","_createBlock","_unref","_withCtx","_createVNode","_createElementBlock","_Fragment","_renderList","_createElementVNode","_sfc_main","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","_hoisted_13","_hoisted_14","_hoisted_15","_hoisted_16","_hoisted_17","_hoisted_18","_hoisted_19","_hoisted_20","_hoisted_21","_hoisted_22","_hoisted_23","_hoisted_24","_hoisted_25","_hoisted_26","_hoisted_27","_hoisted_28","_hoisted_29","_hoisted_30","_hoisted_31","_hoisted_32","_hoisted_33","_hoisted_34","_hoisted_35","_hoisted_36","_hoisted_37","_hoisted_38","_hoisted_39","_hoisted_40","_hoisted_41","_hoisted_42","_useModel","_openBlock","_createBlock","_unref","_withCtx","_createVNode","_createElementVNode","_createTextVNode","_toDisplayString","_createElementBlock","_normalizeClass","_withModifiers","_Fragment","_withDirectives","_renderList","_vModelSelect","_createCommentVNode","_vModelCheckbox","_sfc_main","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_useModel","_openBlock","_createBlock","_unref","_withCtx","_createVNode","_createTextVNode","_toDisplayString","_createElementVNode","_createElementBlock","_Fragment","_renderList","_sfc_main","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_openBlock","_createBlock","_unref","_withCtx","_createVNode","_createTextVNode","_toDisplayString","_createElementVNode","_createElementBlock","_Fragment","_createCommentVNode","_sfc_main","$slots","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","_hoisted_13","_hoisted_14","_hoisted_15","_openBlock","_createBlock","_unref","_withCtx","_createVNode","_createElementVNode","_normalizeClass","_createElementBlock","_toDisplayString","_createCommentVNode","_Fragment","_renderList","_normalizeStyle","SkeletonRow","SheetRow","_renderSlot","SheetMenu","_sfc_main","TextCell","NumberCell","OptionCell","MultiCell","DateCell","_openBlock","_createElementBlock","_normalizeClass","_unref","_createVNode","_createElementVNode","_toDisplayString","_createTextVNode","_createCommentVNode","_normalizeStyle","SearchBox","_Fragment","_withCtx","_createBlock","_renderList","DisplayPopover","_mergeProps","_toHandlers","SheetGrid","_createSlots","_renderSlot","StateMessage","_withDirectives","_vShow","ConfirmDialog","ImportDialog","SaveErrorsDialog","_sfc_main","typeLabelKey","renderCellContent","parseNumber","plainText","useColumnLayout","isNumericType","badge","isInteractive","useDataTableContext","TYPE_SPECS","readPath","alignOf","REMOVE_KBD","DisplayPopover_default","toDate","mac","useDelegatedTooltip","withFill","RemoteLabels","REDO_KBD","SearchBox_default","getFormat","isoDay","SkeletonRow_default","FIND_KBD","comparator","isEmptyValue","StateMessage_default","FILL_KBD","exportFile","ConfirmDialog_default","optionLabel","usePreferences","ME","formatCell","SAVE_KBD","isTextInput","INTERACTIVE_SELECTOR","UNDO_KBD","cellFillStyle","tsvCell","s","toTsv","matrix","r","escapeHtml","toHtml","c","parseTsv","rows","row","cell","quoted","i","text","ch","sep","parseHtmlTable","html","tr","td","matrixFromClipboard","data","matchOption","o","options","fold$1","opt","locale","splitList","p","inferDecimal","raw","texts","comma","dot","validDay","dt","y","m","d","parseDateInput","low","env","rel","iso","dmy","parseInput","def","part","v","inputText","value","useParseEnv","i18n","focusEnd","el","n","_hoisted_1$7","_hoisted_2$7","_hoisted_3$6","NumberCell_default","defineComponent","__emit","props","__props","emit","ref","suffix","computed","onInput","openBlock","createElementBlock","createElementVNode","toDisplayString","createCommentVNode","OptionCell_default","open","listId","nextTick","input","inputEl","onText","onSelect","onKeydown","Item","createBlock","unref","ComboboxRoot","_cache","$event","withCtx","createVNode","ComboboxAnchor","ComboboxInput","ComboboxPortal","ComboboxContent","ComboboxViewport","Fragment","renderList","ComboboxItem","ComboboxEmpty","createTextVNode","_hoisted_1$6","_hoisted_2$6","TextCell_default","_hoisted_1$5","_hoisted_2$5","_hoisted_3$5","_hoisted_4$5","DateCell_default","fmt","dayFmt","tz","getLocalTimeZone","now","today","weekStartsOn","getDayOfWeek","startOfWeek","safe","parseDate","single","resolved","onPick","refocus","PopoverRoot","PopoverTrigger","PhCalendarBlank","PopoverPortal","PopoverContent","CalendarRoot","CalendarHeader","CalendarPrev","PhCaretLeft","CalendarHeading","CalendarNext","PhCaretRight","grid","CalendarGrid","month","CalendarGridHead","CalendarGridRow","weekDays","CalendarHeadCell","day","CalendarGridBody","week","CalendarCell","CalendarCellTrigger","SHEET_EDITOR_KEY","useSheetEditor","inject","MultiCell_default","lower","t","sheet","values","suggestions","search","shown","q","wantOpen","reveal","ComboboxItemIndicator","PhCheck","fillValues","source","count","nums","step","base","up","dir","round","cellText","TR","normalizeHeader","isNumberLike","detectHeaderRow","best","bestScore","cells","first","matchColumns","out","names","columns","headers","h","hits","j","_hoisted_1$4","_hoisted_2$4","_hoisted_3$4","_hoisted_4$4","_hoisted_5$4","_hoisted_6$4","_hoisted_7$3","_hoisted_8$2","_hoisted_9$2","_hoisted_10$2","_hoisted_11$2","_hoisted_12$2","_hoisted_13$2","_hoisted_14$2","_hoisted_15$2","_hoisted_16$1","_hoisted_17$1","_hoisted_18$1","_hoisted_19$1","_hoisted_20$1","_hoisted_21$1","_hoisted_22$1","_hoisted_23$1","_hoisted_24$1","_hoisted_25$1","_hoisted_26$1","_hoisted_27$1","_hoisted_28$1","_hoisted_29$1","_hoisted_30$1","_hoisted_31$1","_hoisted_32$1","_hoisted_33$1","_hoisted_34$1","_hoisted_35$1","_hoisted_36$1","_hoisted_37$1","_hoisted_38$1","_hoisted_39$1","_hoisted_40$1","_hoisted_41$1","_hoisted_42$1","SKIP","ImportDialog_default","\"open\"","\"openModifiers\"","useModel","keyDef","keyHeader","fields","file","shallowRef","workbook","loading","failed","failReason","sheetIndex","headerRow","mapping","keyCol","addNew","showNew","dragging","dataRows","headerOptions","rebuild","auto","key","id","f","load","wb","onHeaderRow","onDrop","reset","keyTexts","summary","seen","updates","news","k","overLimit","canApply","localeFor","dec","col","convert","preview","apply","sheetInfo","DialogRoot","DialogPortal","DialogOverlay","DialogContent","DialogTitle","DialogDescription","DialogClose","PhX","PhTable","withDirectives","vModelSelect","PhLock","PhArrowLeft","normalizeClass","PhWarningCircle","PhArrowRight","PhInfo","vModelCheckbox","withModifiers","PhUploadSimple","local","readWorkbook","readXlsxFile","_hoisted_1$3","_hoisted_2$3","_hoisted_3$3","_hoisted_4$3","_hoisted_5$3","_hoisted_6$3","SaveErrorsDialog_default","save","AlertDialogRoot","AlertDialogPortal","AlertDialogOverlay","AlertDialogContent","AlertDialogTitle","AlertDialogDescription","AlertDialogCancel","_hoisted_1$2","_hoisted_2$2","_hoisted_3$2","_hoisted_4$2","_hoisted_5$2","_hoisted_6$2","_hoisted_7$2","SheetMenu_default","K","ContextMenuPortal","ContextMenuContent","ContextMenuItem","ContextMenuSeparator","plainDefs","plain","SheetRow_default","params","renderCell","editable","issue","changed","isActive","sel","inSel","fill","inFill","ed","isKey","content","Editor","children","tipId","gutter","hasError","PhPlus","index","_hoisted_1$1","_hoisted_2$1","_hoisted_3$1","\"left\"","_hoisted_4$1","_hoisted_5$1","_hoisted_6$1","_hoisted_7$1","_hoisted_8$1","_hoisted_9$1","_hoisted_10$1","_hoisted_11$1","_hoisted_12$1","_hoisted_13$1","_hoisted_14$1","_hoisted_15$1","GUTTER_FULL","EDGE","SCROLL_STEP","SheetGrid_default","__expose","ctx","uid","useId","root","scrollEl","layout","table","store","keyOf","coarse","density","GUTTER_W","g","startVars","name","rowHeight","headH","barH","readBarH","readRowHeight","onMounted","watch","labels","defById","indexByKey","active","activeIndex","multi","b","selectionFor","handleFor","fillDrag","editingFor","e","foundFor","virtualizer","useVirtualizer","start","range","end","virtualRows","totalSize","scrolledStart","onScroll","cellEl","columnId","pinnedWidth","w","revealX","sc","left","revealEnd","focusActive","focusNow","a","tryFocus","attempt","focusCell","cols","ci","ri","jump","pageSize","DIR","target","mod","widget","openMenuAt","clipboard","action","hitAt","rowEl","hit","fillLabel","pointer","scrollRaf","extendTo","updateFillLabel","autoScroll","dy","dx","onMousemove","last","rootRect","onDocMouseup","onBeforeUnmount","rowAnchor","onMousedown","hr","from","onMouseover","onDblclick","fillFor","down","onContextmenuCapture","menuHref","sortOf","unitOf","headTip","resize","requiredLabel","ContextMenuRoot","ContextMenuTrigger","normalizeStyle","PhArrowUp","item","_ctx","renderSlot","useSheetEditing","editing","opts","inCell","HISTORY","same","x","setPath","keys","path","obj","next","fold","closest","dist","prev","tmp","useSheetStore","defs","toValue","draft","shallowReactive","issues","serverErrors","rowErrors","added","removed","version","undoStack","redoStack","canUndo","canRedo","newCounter","batch","batchIndex","allRows","byKey","addedByKey","isNew","rowNoOf","original","readFrom","map","read","readUntracked","toRaw","current","keyIndex","set","typeIssue","error","bad","optionIssue","optionEnabled","duplicateIssue","others","other","validateRow","isNewRow","cur","required","err","warn","revalidateKeys","write","patches","touched","keyValues","changes","before","entry","se","syncHistory","record","addedRows","addRows","dropAdded","drop","removeRows","restoreRows","replay","undo","redo","clearHistory","rowDraft","rowIssues","client","server","merged","message","rowError","counts","changedCells","changedKeys","errorRows","warningRows","errorKeys","newRows","changedOrNewRows","byId","always","isAdded","created","updated","errors","saved","results","fe","features","tableFeatures","useSheetTable","useTable","ranges","bounds","rangeEnd","rowId","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","_hoisted_13","_hoisted_14","_hoisted_15","_hoisted_16","_hoisted_17","_hoisted_18","_hoisted_19","_hoisted_20","_hoisted_21","_hoisted_22","_hoisted_23","_hoisted_24","_hoisted_25","_hoisted_26","_hoisted_27","_hoisted_28","_hoisted_29","_hoisted_30","_hoisted_31","_hoisted_32","_hoisted_33","_hoisted_34","_hoisted_35","_hoisted_36","_hoisted_37","_hoisted_38","_hoisted_39","_hoisted_40","_hoisted_41","_hoisted_42","_hoisted_43","_hoisted_44","_hoisted_45","_hoisted_46","DataSheet_default","entity","listensExport","getCurrentInstance","readFile","pref","loadedRows","loadingNow","savingNow","progress","percent","readOnlyDevice","sheetColumns","fixedStart","primaryDef","sortRules","order","view","viewKeys","matchesView","refreshView","union","setView","orderedBatch","rowsAll","all","visibleCols","readOnlyNow","EDITORS","editorFor","canEdit","parseEnv","edit","useTemplateRef","fmtEnv","selectCells","r1","r2","c1","c2","selectedCells","toggle","clearSelected","errorKeysInOrder","goToError","showToast","copyText","copyMatrix","line","copy","cut","copyToClipboard","clip","tsv","cutAfter","pasteMatrix","width","l","startRow","startCol","targets","lastRow","overflow","localeByCol","minR","minC","maxC","dims","paste","pasteFromClipboard","fillPlan","fromRow","toRow","fillDown","afterStep","idx","useSuggestion","addRow","defaults","at","pos","insertRow","where","removeSelectedRows","sort","existing","rest","additive","cmps","cmp","sign","sortMap","errorDialogOpen","errorItems","saveTotals","savedSummary","partly","emitSave","fixFirst","finishSave","resultVersion","applyResult","partlyIndex","copyErrors","lines","keyText","rowErr","openHref","importOpen","keyIndexSet","inList","applyImport","byKeyValue","need","payload","fresh","freshByKey","firstKey","firstRow","exportRows","scope","exportLabel","copyLink","onDocPointerdown","isDirty","onBeforeUnload","toastTimer","findBox","onRootKeydown","findText","findIndex","matches","list","goToMatch","findStep","onFindKeydown","findCount","viewCounts","activeRow","activeDef","rangeDims","rangeText","nameKey","formulaText","formulaEditable","onFormulaInput","onFormulaKeydown","hint","parts","valueAria","sum","numeric","status","changesText","saveTip","undoTip","redoTip","canSave","toast","toastUndo","toastAction","run","polite","assertive","announcedQuarter","discardOpen","discard","displayProps","displayOn","on","rootEl","tooltip","PhMonitor","PhLink","ToggleGroupRoot","ToggleGroupItem","PhArrowUUpLeft","PhArrowUUpRight","PhDownloadSimple","DropdownMenuRoot","DropdownMenuTrigger","PhExport","DropdownMenuPortal","DropdownMenuContent","DropdownMenuSub","DropdownMenuSubTrigger","DropdownMenuSubContent","DropdownMenuItem","mergeProps","toHandlers","PhCircleNotch","PhCaretUp","PhCaretDown","PhCopy","PhWarning","createSlots","vShow"],"sources":["../src/sheet/clipboard.ts","../src/sheet/parse.ts","../src/sheet/editors/useParseEnv.ts","../src/sheet/editors/NumberCell.vue","../src/sheet/editors/NumberCell.vue","../src/sheet/editors/OptionCell.vue","../src/sheet/editors/OptionCell.vue","../src/sheet/editors/TextCell.vue","../src/sheet/editors/TextCell.vue","../src/sheet/editors/DateCell.vue","../src/sheet/editors/DateCell.vue","../src/sheet/editors/context.ts","../src/sheet/editors/MultiCell.vue","../src/sheet/editors/MultiCell.vue","../src/sheet/fill.ts","../src/sheet/import/model.ts","../src/sheet/ImportDialog.vue","../src/sheet/ImportDialog.vue","../src/sheet/import/read.ts","../src/sheet/SaveErrorsDialog.vue","../src/sheet/SaveErrorsDialog.vue","../src/sheet/SheetMenu.vue","../src/sheet/SheetMenu.vue","../src/sheet/SheetRow.ts","../src/sheet/SheetGrid.vue","../src/sheet/SheetGrid.vue","../src/sheet/useSheetEditing.ts","../src/sheet/useSheetStore.ts","../src/sheet/useSheetTable.ts","../src/sheet/DataSheet.vue","../src/sheet/DataSheet.vue"],"sourcesContent":["// Pano biçimleri (07 §7): kopyada TSV (`text/plain`) + `<table>` (`text/html`), görüntülenen biçimde; yapıştırmada TSV\n// çözümleme (Excel'in tırnaklı, içinde sekme/satır sonu olan hücreleri dahil), `text/html` yalnızca TSV yoksa.\n\n/** Excel kuralı: sekme/satır sonu/tırnak içeren hücre çift tırnağa alınır, içteki tırnak ikilenir. */\nconst tsvCell = (s: string): string => (/[\\t\\n\\r\"]/.test(s) ? `\"${s.replace(/\"/g, '\"\"')}\"` : s)\nexport const toTsv = (matrix: string[][]): string => matrix.map((r) => r.map(tsvCell).join('\\t')).join('\\n')\n\nconst escapeHtml = (s: string): string =>\n s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\\n/g, '<br>')\nexport const toHtml = (matrix: string[][]): string =>\n `<table><tbody>${matrix.map((r) => `<tr>${r.map((c) => `<td>${escapeHtml(c)}</td>`).join('')}</tr>`).join('')}</tbody></table>`\n\n/** TSV → matris (CSV için `sep` verilir); sondaki tek boş satır (Excel'in eklediği) atılır. */\nexport function parseTsv(text: string, sep = '\\t'): string[][] {\n const rows: string[][] = []\n let row: string[] = []\n let cell = ''\n let quoted = false\n for (let i = 0; i < text.length; i++) {\n const ch = text[i]!\n if (quoted) {\n if (ch === '\"') {\n if (text[i + 1] === '\"') {\n cell += '\"'\n i++\n } else quoted = false\n } else cell += ch\n continue\n }\n if (ch === '\"' && cell === '') quoted = true\n else if (ch === sep) {\n row.push(cell)\n cell = ''\n } else if (ch === '\\n' || ch === '\\r') {\n if (ch === '\\r' && text[i + 1] === '\\n') i++\n row.push(cell)\n rows.push(row)\n row = []\n cell = ''\n } else cell += ch\n }\n if (cell !== '' || row.length) {\n row.push(cell)\n rows.push(row)\n }\n if (rows.length > 1 && rows[rows.length - 1]!.every((c) => c === '')) rows.pop()\n return rows\n}\n\n/** `<table>` → matris (yalnızca TSV yokken). */\nexport function parseHtmlTable(html: string): string[][] {\n if (typeof DOMParser === 'undefined') return []\n const doc = new DOMParser().parseFromString(html, 'text/html')\n return [...doc.querySelectorAll('tr')].map((tr) =>\n [...tr.querySelectorAll('td, th')].map((td) => (td.textContent ?? '').replace(/\\u00a0/g, ' ').trim()),\n )\n}\n\n/** Pano olayından matris: TSV öncelikli, sonra HTML tablosu, sonra düz metin tek hücre. */\nexport function matrixFromClipboard(data: DataTransfer | null): string[][] {\n const text = data?.getData('text/plain') ?? ''\n if (text) return parseTsv(text)\n const html = data?.getData('text/html') ?? ''\n return html ? parseHtmlTable(html) : []\n}\n","// Hücre girişlerinin çözümlenmesi (07 §5, §7): sayı yerel ayara göre (\"2240\", \"2.240,00\", \"2,240.00\"; \"%20\" → 20),\n// tarih \"24.10\", \"24.10.2026\", \"+7d\", \"today\"/\"bugün\", ISO; seçenek etiketle (büyük/küçük harf ve İ/ı duyarsız).\n// Çözülemeyen giriş ham metin olarak kalır; doğrulama onu tip hatası sayar (useSheetStore).\nimport { optionLabel } from '../core/cells/format'\nimport { TYPE_SPECS } from '../core/cells/specs'\nimport { isoDay } from '../core/filters/model'\nimport { parseNumber } from '../core/format/parse'\nimport type { ColumnDef, OptionDef } from '../types/columns'\n\nexport interface ParseEnv {\n locale: string\n today: Date\n /** i18n `date.today` (\"Today\" / \"Bugün\"); \"today\" her dilde kabul edilir. */\n todayWord: string\n /** i18n `common.yes` / `common.no` (boolean yapıştırma); true/false/1/0/yes/no her dilde. */\n yesWord: string\n noWord: string\n}\n\n/** Seçenek etiketle (büyük/küçük harf, İ/ı ve boşluk duyarsız) ya da değerle; eşleşmeyen ham metin (hata). */\nconst matchOption = (options: OptionDef[], text: string, locale: string): unknown => {\n const o = options.find((opt) => fold(opt.label, locale) === fold(text, locale) || String(opt.value) === text.trim())\n return o ? o.value : text.trim()\n}\n/** `;` veya `,` ayrılmış liste (07 §5). */\nconst splitList = (s: string): string[] =>\n s\n .split(/[;,]/)\n .map((p) => p.trim())\n .filter(Boolean)\n\n/** Yapıştırılan bir sütunun ondalık ayırıcısı (07 §7): `1.234,56` / `12,5` → virgül; `1,234.56` / `12.5` → nokta; belirsizse null. */\nexport function inferDecimal(texts: string[]): ',' | '.' | null {\n for (const raw of texts) {\n const s = raw.replace(/[\\s%\\u00a0A-Za-z₺€$£]/g, '')\n const comma = s.lastIndexOf(',')\n const dot = s.lastIndexOf('.')\n if (comma >= 0 && dot >= 0) return comma > dot ? ',' : '.'\n if (comma >= 0 && /,\\d{1,2}$/.test(s) && !/^\\d{1,3}(,\\d{3})+$/.test(s)) return ','\n if (dot >= 0 && /\\.\\d{1,2}$/.test(s) && !/^\\d{1,3}(\\.\\d{3})+$/.test(s)) return '.'\n }\n return null\n}\n\nconst fold = (s: string, locale: string): string => s.trim().toLocaleLowerCase(locale).replace(/ı|i̇/g, 'i')\n\nconst validDay = (y: number, m: number, d: number): string | null => {\n const dt = new Date(y, m - 1, d)\n return dt.getFullYear() === y && dt.getMonth() === m - 1 && dt.getDate() === d ? isoDay(dt) : null\n}\n\n/** \"24.10\" (bu yıl), \"24.10.2026\", \"24/10/26\", \"+7d\", \"-3d\", \"today\", ISO. Çözülemezse null. */\nexport function parseDateInput(text: string, env: ParseEnv): string | null {\n const s = text.trim()\n if (!s) return null\n const low = fold(s, env.locale)\n if (low === 'today' || low === fold(env.todayWord, env.locale)) return isoDay(env.today)\n const rel = /^([+-])(\\d+)d$/i.exec(s)\n if (rel) {\n const d = new Date(env.today)\n d.setDate(d.getDate() + (rel[1] === '-' ? -1 : 1) * Number(rel[2]))\n return isoDay(d)\n }\n const iso = /^(\\d{4})-(\\d{2})-(\\d{2})/.exec(s)\n if (iso) return validDay(+iso[1]!, +iso[2]!, +iso[3]!)\n const dmy = /^(\\d{1,2})[./](\\d{1,2})(?:[./](\\d{2}|\\d{4}))?$/.exec(s)\n if (dmy) {\n const y = dmy[3] ? (dmy[3].length === 2 ? 2000 + +dmy[3] : +dmy[3]) : env.today.getFullYear()\n return validDay(y, +dmy[2]!, +dmy[1]!)\n }\n return null\n}\n\n/** Editör / formül çubuğu metni → hücre değeri. Boş → null; çözülemeyen → ham metin (tip hatası). */\nexport function parseInput(def: ColumnDef, text: string, env: ParseEnv): unknown {\n const s = text.trim()\n if (s === '') return null\n if (TYPE_SPECS[def.type].numeric || def.type === 'star') {\n // Formül desteklenmez (07 §2): \"=\" ile başlayan giriş sayı sütununda hata olarak kalır.\n if (s.startsWith('=')) return s\n return parseNumber(env.locale, s) ?? s\n }\n switch (def.type) {\n case 'date':\n case 'datetime':\n return parseDateInput(s, env) ?? s\n case 'select':\n return matchOption(def.options, s, env.locale)\n case 'multiselect':\n return splitList(s).map((part) => matchOption(def.options, part, env.locale))\n case 'boolean': {\n const v = fold(s, env.locale)\n if (['true', '1', 'yes', fold(env.yesWord, env.locale)].includes(v)) return true\n if (['false', '0', 'no', fold(env.noWord, env.locale)].includes(v)) return false\n return s\n }\n case 'uppercase':\n return s.toLocaleUpperCase(env.locale)\n case 'lowercase':\n return s.toLocaleLowerCase(env.locale)\n default:\n return s\n }\n}\n\n/** Hücre değeri → editör / formül çubuğunun ham metni. */\nexport function inputText(def: ColumnDef, value: unknown): string {\n if (value === null || value === undefined) return ''\n if (def.type === 'select') return optionLabel(def.options, value)\n if (Array.isArray(value)) return value.join(', ')\n if (typeof value === 'object') return JSON.stringify(value)\n return String(value)\n}\n","// Yerleşik hücre editörlerinin ortak çözümleme bağlamı (parse.ts): yerel ayar, bugün, \"Today\" sözcüğü.\nimport { useDataTableContext } from '../../core/plugin'\nimport type { ParseEnv } from '../parse'\n\nexport function useParseEnv(): () => ParseEnv {\n const { i18n, locale } = useDataTableContext()\n return () => ({\n locale,\n today: new Date(),\n todayWord: i18n.t('date.today'),\n yesWord: i18n.t('common.yes'),\n noWord: i18n.t('common.no'),\n })\n}\n\n/** Odak editöre, imleç sonda (F2 / yazarak açılış, 07 §5). */\nexport function focusEnd(el: HTMLInputElement | HTMLTextAreaElement | null) {\n if (!el) return\n el.focus({ preventScroll: true })\n const n = el.value.length\n el.setSelectionRange(n, n)\n}\n","<script setup lang=\"ts\">\n// Sayı / para / yüzde hücre editörü (07 §5, T11-07): sağa yaslı; \"2240\", \"2.240,00\", \"2,240.00\" yerel ayara göre okunur,\n// \"%20\"/\"20%\" → 20. Sabit para kodu ve \"%\" soluk sağda. Çözülemeyen metin ham kalır (hata, kayıttan önce).\nimport { computed, onMounted, ref } from 'vue'\nimport type { ColumnDef } from '../../types/columns'\nimport { inputText, parseInput } from '../parse'\nimport { focusEnd, useParseEnv } from './useParseEnv'\n\nconst props = defineProps<{ modelValue: unknown; row: object; column: ColumnDef }>()\nconst emit = defineEmits<{ 'update:modelValue': [value: unknown] }>()\nconst env = useParseEnv()\nconst el = ref<HTMLInputElement | null>(null)\nconst text = ref(inputText(props.column, props.modelValue))\nconst suffix = computed(() => {\n const c = props.column\n return c.type === 'currency' && typeof c.currency === 'string' ? c.currency : c.type === 'percentage' ? '%' : ''\n})\nonMounted(() => focusEnd(el.value))\nconst onInput = () => {\n text.value = el.value!.value\n emit('update:modelValue', parseInput(props.column, text.value, env()))\n}\n</script>\n\n<template>\n <span class=\"dt-cell-editor is-number\">\n <input\n ref=\"el\"\n class=\"dt-cell-input is-right\"\n type=\"text\"\n inputmode=\"decimal\"\n :value=\"text\"\n :aria-label=\"column.header\"\n autocomplete=\"off\"\n @input=\"onInput\"\n />\n <span v-if=\"suffix\" class=\"dt-ccy\" aria-hidden=\"true\">{{ suffix }}</span>\n </span>\n</template>\n","<script setup lang=\"ts\">\n// Sayı / para / yüzde hücre editörü (07 §5, T11-07): sağa yaslı; \"2240\", \"2.240,00\", \"2,240.00\" yerel ayara göre okunur,\n// \"%20\"/\"20%\" → 20. Sabit para kodu ve \"%\" soluk sağda. Çözülemeyen metin ham kalır (hata, kayıttan önce).\nimport { computed, onMounted, ref } from 'vue'\nimport type { ColumnDef } from '../../types/columns'\nimport { inputText, parseInput } from '../parse'\nimport { focusEnd, useParseEnv } from './useParseEnv'\n\nconst props = defineProps<{ modelValue: unknown; row: object; column: ColumnDef }>()\nconst emit = defineEmits<{ 'update:modelValue': [value: unknown] }>()\nconst env = useParseEnv()\nconst el = ref<HTMLInputElement | null>(null)\nconst text = ref(inputText(props.column, props.modelValue))\nconst suffix = computed(() => {\n const c = props.column\n return c.type === 'currency' && typeof c.currency === 'string' ? c.currency : c.type === 'percentage' ? '%' : ''\n})\nonMounted(() => focusEnd(el.value))\nconst onInput = () => {\n text.value = el.value!.value\n emit('update:modelValue', parseInput(props.column, text.value, env()))\n}\n</script>\n\n<template>\n <span class=\"dt-cell-editor is-number\">\n <input\n ref=\"el\"\n class=\"dt-cell-input is-right\"\n type=\"text\"\n inputmode=\"decimal\"\n :value=\"text\"\n :aria-label=\"column.header\"\n autocomplete=\"off\"\n @input=\"onInput\"\n />\n <span v-if=\"suffix\" class=\"dt-ccy\" aria-hidden=\"true\">{{ suffix }}</span>\n </span>\n</template>\n","<script setup lang=\"ts\">\n// Seçenek hücre editörü (07 §5, T11-07): reka Combobox; yazmak listeyi süzer, Enter seçer, ilk Esc listeyi kapatır\n// (ikinci Esc düzenlemeyi iptal eder — sheet, `aria-expanded` ve `defaultPrevented` üzerinden anlar). Listede olmayan\n// metin ham kalır → \"“Pump” isn't an option\". Liste portalda: `dt-sheet-layer` dışarı tık sayılmaz. Alt↓ listeyi açar.\nimport {\n ComboboxAnchor,\n ComboboxContent,\n ComboboxEmpty,\n ComboboxInput,\n ComboboxItem,\n ComboboxPortal,\n ComboboxRoot,\n ComboboxViewport,\n} from 'reka-ui'\nimport { computed, nextTick, onMounted, ref, watch } from 'vue'\nimport { optionLabel } from '../../core/cells/format'\nimport { badge } from '../../core/cells/renderCell'\nimport { useDataTableContext } from '../../core/plugin'\nimport type { ColumnDef, OptionDef } from '../../types/columns'\nimport { inputText, parseInput } from '../parse'\nimport { focusEnd, useParseEnv } from './useParseEnv'\n\nconst props = defineProps<{ modelValue: unknown; row: object; column: ColumnDef }>()\nconst emit = defineEmits<{ 'update:modelValue': [value: unknown] }>()\nconst { i18n } = useDataTableContext()\nconst env = useParseEnv()\nconst def = computed(() => props.column as Extract<ColumnDef, { type: 'select' }>)\n// Satıra göre kapalı seçenekler listede yok (`row` taslak satır); etiket çözümü tam listeden.\nconst options = computed(() => {\n const d = def.value\n return d.optionEnabled ? d.options.filter((o) => d.optionEnabled!(o, props.row)) : d.options\n})\nconst open = ref(true)\n// reka listenin id'sini input'a geç yazıyor (aria-controls=\"\"): açılınca DOM'daki gerçek id okunur (axe aria-valid-attr-value).\nconst listId = ref<string | undefined>()\nwatch(\n open,\n (o) => {\n if (!o) return\n void nextTick(() => {\n listId.value = document.querySelector<HTMLElement>('.dt-cell-list[role=\"listbox\"]')?.id || undefined\n })\n },\n { immediate: true },\n)\nconst text = ref(inputText(props.column, props.modelValue))\nconst input = ref<{ $el: HTMLInputElement } | null>(null)\nconst inputEl = () => input.value?.$el ?? null\nonMounted(() => void nextTick(() => focusEnd(inputEl())))\n\nconst onText = (v: string) => {\n text.value = v\n emit('update:modelValue', parseInput(props.column, v, env()))\n}\nconst onSelect = (v: unknown) => {\n if (v === undefined || v === null) return\n emit('update:modelValue', v)\n text.value = optionLabel(def.value.options, v)\n open.value = false\n void nextTick(() => focusEnd(inputEl()))\n}\nconst onKeydown = (e: KeyboardEvent) => {\n if (e.altKey && e.key === 'ArrowDown') {\n e.preventDefault()\n open.value = true\n }\n}\n// Sabit bileşen: her render'da yeni bileşen üretmek rozeti mousedown–mouseup arasında DOM'da değiştirir, click kaybolur.\nconst Item = (p: { o: OptionDef }) => badge(p.o.tone, p.o.label)\n</script>\n\n<template>\n <ComboboxRoot\n v-model:open=\"open\"\n class=\"dt-cell-editor is-option\"\n :model-value=\"(modelValue as string | number | undefined) ?? undefined\"\n :reset-search-term-on-blur=\"false\"\n @update:model-value=\"onSelect\"\n >\n <!-- Liste hücreye göre konumlanır (altında, sağa hizalı): çapa editörün kendisi. -->\n <ComboboxAnchor class=\"dt-cell-anchor\">\n <ComboboxInput\n ref=\"input\"\n class=\"dt-cell-input\"\n autocomplete=\"off\"\n :aria-label=\"column.header\"\n :aria-controls=\"listId\"\n :model-value=\"text\"\n :display-value=\"() => text\"\n @update:model-value=\"onText\"\n @keydown=\"onKeydown\"\n />\n </ComboboxAnchor>\n <ComboboxPortal>\n <ComboboxContent\n class=\"dt-pop dt-cell-list dt-sheet-layer\"\n position=\"popper\"\n align=\"end\"\n :side-offset=\"2\"\n :aria-label=\"column.header\"\n >\n <ComboboxViewport>\n <ComboboxItem\n v-for=\"o in options\"\n :key=\"String(o.value)\"\n class=\"dt-pop-item dt-cell-option\"\n :value=\"o.value\"\n :text-value=\"o.label\"\n >\n <Item :o=\"o\" />\n <kbd class=\"dt-kbd dt-cell-option-enter\" aria-hidden=\"true\">↵</kbd>\n </ComboboxItem>\n <ComboboxEmpty class=\"dt-options-empty\">{{ i18n.t('picker.noMatch') }}</ComboboxEmpty>\n </ComboboxViewport>\n </ComboboxContent>\n </ComboboxPortal>\n </ComboboxRoot>\n</template>\n","<script setup lang=\"ts\">\n// Seçenek hücre editörü (07 §5, T11-07): reka Combobox; yazmak listeyi süzer, Enter seçer, ilk Esc listeyi kapatır\n// (ikinci Esc düzenlemeyi iptal eder — sheet, `aria-expanded` ve `defaultPrevented` üzerinden anlar). Listede olmayan\n// metin ham kalır → \"“Pump” isn't an option\". Liste portalda: `dt-sheet-layer` dışarı tık sayılmaz. Alt↓ listeyi açar.\nimport {\n ComboboxAnchor,\n ComboboxContent,\n ComboboxEmpty,\n ComboboxInput,\n ComboboxItem,\n ComboboxPortal,\n ComboboxRoot,\n ComboboxViewport,\n} from 'reka-ui'\nimport { computed, nextTick, onMounted, ref, watch } from 'vue'\nimport { optionLabel } from '../../core/cells/format'\nimport { badge } from '../../core/cells/renderCell'\nimport { useDataTableContext } from '../../core/plugin'\nimport type { ColumnDef, OptionDef } from '../../types/columns'\nimport { inputText, parseInput } from '../parse'\nimport { focusEnd, useParseEnv } from './useParseEnv'\n\nconst props = defineProps<{ modelValue: unknown; row: object; column: ColumnDef }>()\nconst emit = defineEmits<{ 'update:modelValue': [value: unknown] }>()\nconst { i18n } = useDataTableContext()\nconst env = useParseEnv()\nconst def = computed(() => props.column as Extract<ColumnDef, { type: 'select' }>)\n// Satıra göre kapalı seçenekler listede yok (`row` taslak satır); etiket çözümü tam listeden.\nconst options = computed(() => {\n const d = def.value\n return d.optionEnabled ? d.options.filter((o) => d.optionEnabled!(o, props.row)) : d.options\n})\nconst open = ref(true)\n// reka listenin id'sini input'a geç yazıyor (aria-controls=\"\"): açılınca DOM'daki gerçek id okunur (axe aria-valid-attr-value).\nconst listId = ref<string | undefined>()\nwatch(\n open,\n (o) => {\n if (!o) return\n void nextTick(() => {\n listId.value = document.querySelector<HTMLElement>('.dt-cell-list[role=\"listbox\"]')?.id || undefined\n })\n },\n { immediate: true },\n)\nconst text = ref(inputText(props.column, props.modelValue))\nconst input = ref<{ $el: HTMLInputElement } | null>(null)\nconst inputEl = () => input.value?.$el ?? null\nonMounted(() => void nextTick(() => focusEnd(inputEl())))\n\nconst onText = (v: string) => {\n text.value = v\n emit('update:modelValue', parseInput(props.column, v, env()))\n}\nconst onSelect = (v: unknown) => {\n if (v === undefined || v === null) return\n emit('update:modelValue', v)\n text.value = optionLabel(def.value.options, v)\n open.value = false\n void nextTick(() => focusEnd(inputEl()))\n}\nconst onKeydown = (e: KeyboardEvent) => {\n if (e.altKey && e.key === 'ArrowDown') {\n e.preventDefault()\n open.value = true\n }\n}\n// Sabit bileşen: her render'da yeni bileşen üretmek rozeti mousedown–mouseup arasında DOM'da değiştirir, click kaybolur.\nconst Item = (p: { o: OptionDef }) => badge(p.o.tone, p.o.label)\n</script>\n\n<template>\n <ComboboxRoot\n v-model:open=\"open\"\n class=\"dt-cell-editor is-option\"\n :model-value=\"(modelValue as string | number | undefined) ?? undefined\"\n :reset-search-term-on-blur=\"false\"\n @update:model-value=\"onSelect\"\n >\n <!-- Liste hücreye göre konumlanır (altında, sağa hizalı): çapa editörün kendisi. -->\n <ComboboxAnchor class=\"dt-cell-anchor\">\n <ComboboxInput\n ref=\"input\"\n class=\"dt-cell-input\"\n autocomplete=\"off\"\n :aria-label=\"column.header\"\n :aria-controls=\"listId\"\n :model-value=\"text\"\n :display-value=\"() => text\"\n @update:model-value=\"onText\"\n @keydown=\"onKeydown\"\n />\n </ComboboxAnchor>\n <ComboboxPortal>\n <ComboboxContent\n class=\"dt-pop dt-cell-list dt-sheet-layer\"\n position=\"popper\"\n align=\"end\"\n :side-offset=\"2\"\n :aria-label=\"column.header\"\n >\n <ComboboxViewport>\n <ComboboxItem\n v-for=\"o in options\"\n :key=\"String(o.value)\"\n class=\"dt-pop-item dt-cell-option\"\n :value=\"o.value\"\n :text-value=\"o.label\"\n >\n <Item :o=\"o\" />\n <kbd class=\"dt-kbd dt-cell-option-enter\" aria-hidden=\"true\">↵</kbd>\n </ComboboxItem>\n <ComboboxEmpty class=\"dt-options-empty\">{{ i18n.t('picker.noMatch') }}</ComboboxEmpty>\n </ComboboxViewport>\n </ComboboxContent>\n </ComboboxPortal>\n </ComboboxRoot>\n</template>\n","<script setup lang=\"ts\">\n// Metin hücre editörü (07 §5, T11-07): hücrenin yerinde input; `text` tipinde daha yüksek kutu (⇧↵ yeni satır). Değer\n// her tuşta çözümlenir ve yayılır; Enter/Tab/Esc'i sheet yönetir (editör sözleşmesi: props { modelValue, row, column }).\nimport { onMounted, ref } from 'vue'\nimport type { ColumnDef } from '../../types/columns'\nimport { inputText, parseInput } from '../parse'\nimport { focusEnd, useParseEnv } from './useParseEnv'\n\nconst props = defineProps<{ modelValue: unknown; row: object; column: ColumnDef }>()\nconst emit = defineEmits<{ 'update:modelValue': [value: unknown] }>()\nconst env = useParseEnv()\nconst el = ref<HTMLInputElement | HTMLTextAreaElement | null>(null)\nconst text = ref(inputText(props.column, props.modelValue))\nonMounted(() => focusEnd(el.value))\nconst onInput = () => {\n text.value = el.value!.value\n emit('update:modelValue', parseInput(props.column, text.value, env()))\n}\n</script>\n\n<template>\n <textarea\n v-if=\"column.type === 'text'\"\n ref=\"el\"\n class=\"dt-cell-input is-multiline\"\n :value=\"text\"\n :aria-label=\"column.header\"\n rows=\"3\"\n @input=\"onInput\"\n />\n <input\n v-else\n ref=\"el\"\n class=\"dt-cell-input\"\n type=\"text\"\n :value=\"text\"\n :aria-label=\"column.header\"\n autocomplete=\"off\"\n @input=\"onInput\"\n />\n</template>\n","<script setup lang=\"ts\">\n// Metin hücre editörü (07 §5, T11-07): hücrenin yerinde input; `text` tipinde daha yüksek kutu (⇧↵ yeni satır). Değer\n// her tuşta çözümlenir ve yayılır; Enter/Tab/Esc'i sheet yönetir (editör sözleşmesi: props { modelValue, row, column }).\nimport { onMounted, ref } from 'vue'\nimport type { ColumnDef } from '../../types/columns'\nimport { inputText, parseInput } from '../parse'\nimport { focusEnd, useParseEnv } from './useParseEnv'\n\nconst props = defineProps<{ modelValue: unknown; row: object; column: ColumnDef }>()\nconst emit = defineEmits<{ 'update:modelValue': [value: unknown] }>()\nconst env = useParseEnv()\nconst el = ref<HTMLInputElement | HTMLTextAreaElement | null>(null)\nconst text = ref(inputText(props.column, props.modelValue))\nonMounted(() => focusEnd(el.value))\nconst onInput = () => {\n text.value = el.value!.value\n emit('update:modelValue', parseInput(props.column, text.value, env()))\n}\n</script>\n\n<template>\n <textarea\n v-if=\"column.type === 'text'\"\n ref=\"el\"\n class=\"dt-cell-input is-multiline\"\n :value=\"text\"\n :aria-label=\"column.header\"\n rows=\"3\"\n @input=\"onInput\"\n />\n <input\n v-else\n ref=\"el\"\n class=\"dt-cell-input\"\n type=\"text\"\n :value=\"text\"\n :aria-label=\"column.header\"\n autocomplete=\"off\"\n @input=\"onInput\"\n />\n</template>\n","<script setup lang=\"ts\">\n// Tarih hücre editörü (07 §5, T11-07): yazılabilir (\"24.10\", \"+7d\", \"today\") + takvim popover'ı (reka Popover + Calendar).\n// Popover üstünde çözümlenen tarih (\"Wed, Oct 28 · in 7 days\"); kapanınca odak input'a döner (ikinci Esc düzenlemeyi\n// iptal eder). Popover portalda: `dt-sheet-layer` dışarı tık sayılmaz. Alt↓ takvimi açar.\nimport { getDayOfWeek, getLocalTimeZone, parseDate, startOfWeek, today, type DateValue } from '@internationalized/date'\nimport { PhCalendarBlank, PhCaretLeft, PhCaretRight } from '@phosphor-icons/vue'\nimport {\n CalendarCell,\n CalendarCellTrigger,\n CalendarGrid,\n CalendarGridBody,\n CalendarGridHead,\n CalendarGridRow,\n CalendarHeadCell,\n CalendarHeader,\n CalendarHeading,\n CalendarNext,\n CalendarPrev,\n CalendarRoot,\n PopoverContent,\n PopoverPortal,\n PopoverRoot,\n PopoverTrigger,\n} from 'reka-ui'\nimport { computed, nextTick, onMounted, ref } from 'vue'\nimport { getFormat, toDate } from '../../core/format'\nimport { useDataTableContext } from '../../core/plugin'\nimport type { ColumnDef } from '../../types/columns'\nimport { inputText, parseInput } from '../parse'\nimport { focusEnd, useParseEnv } from './useParseEnv'\n\nconst props = defineProps<{ modelValue: unknown; row: object; column: ColumnDef }>()\nconst emit = defineEmits<{ 'update:modelValue': [value: unknown] }>()\nconst { i18n, locale } = useDataTableContext()\nconst env = useParseEnv()\nconst fmt = getFormat(locale)\nconst dayFmt = new Intl.DateTimeFormat(locale, { weekday: 'short', month: 'short', day: 'numeric' })\nconst el = ref<HTMLInputElement | null>(null)\nconst open = ref(false)\nconst text = ref(inputText(props.column, props.modelValue))\nonMounted(() => focusEnd(el.value))\n\nconst tz = getLocalTimeZone()\nconst now = today(tz)\nconst weekStartsOn = getDayOfWeek(startOfWeek(now, locale), 'en-US') as 0 | 1 | 2 | 3 | 4 | 5 | 6\nconst safe = (s: unknown): DateValue | undefined => {\n try {\n return typeof s === 'string' && s ? parseDate(s.slice(0, 10)) : undefined\n } catch {\n return undefined\n }\n}\nconst single = computed(() => safe(props.modelValue))\nconst resolved = computed(() => {\n const v = props.modelValue\n if (typeof v !== 'string' || !single.value) return null\n const d = toDate(v.slice(0, 10))\n return { day: dayFmt.format(d), relative: fmt.relative(d) }\n})\n\nconst onInput = () => {\n text.value = el.value!.value\n emit('update:modelValue', parseInput(props.column, text.value, env()))\n}\nconst onPick = (d: DateValue | undefined) => {\n if (!d) return\n const iso = d.toString()\n text.value = iso\n emit('update:modelValue', iso)\n open.value = false\n}\nconst refocus = (e: Event) => {\n e.preventDefault()\n void nextTick(() => focusEnd(el.value))\n}\nconst onKeydown = (e: KeyboardEvent) => {\n if (e.altKey && e.key === 'ArrowDown') {\n e.preventDefault()\n open.value = true\n }\n}\n</script>\n\n<template>\n <span class=\"dt-cell-editor is-date\">\n <input\n ref=\"el\"\n class=\"dt-cell-input\"\n type=\"text\"\n :value=\"text\"\n :aria-label=\"column.header\"\n autocomplete=\"off\"\n @input=\"onInput\"\n @keydown=\"onKeydown\"\n />\n <PopoverRoot v-model:open=\"open\">\n <PopoverTrigger as-child>\n <button type=\"button\" class=\"dt-cell-editor-btn\" tabindex=\"-1\" :aria-label=\"i18n.t('type.date')\">\n <PhCalendarBlank :size=\"14\" aria-hidden=\"true\" />\n </button>\n </PopoverTrigger>\n <PopoverPortal>\n <PopoverContent\n class=\"dt-pop dt-cell-date dt-sheet-layer\"\n align=\"start\"\n :side-offset=\"4\"\n @close-auto-focus=\"refocus\"\n >\n <div v-if=\"resolved\" class=\"dt-cell-date-head\">\n <strong>{{ resolved.day }}</strong>\n <span>{{ resolved.relative }}</span>\n </div>\n <CalendarRoot\n v-slot=\"{ weekDays, grid }\"\n class=\"dt-calendar\"\n :model-value=\"single\"\n :locale=\"locale\"\n :week-starts-on=\"weekStartsOn\"\n :placeholder=\"single ?? now\"\n @update:model-value=\"(d) => onPick(d as DateValue | undefined)\"\n >\n <CalendarHeader class=\"dt-cal-head\">\n <CalendarPrev class=\"dt-icon-btn-sm\"><PhCaretLeft :size=\"16\" aria-hidden=\"true\" /></CalendarPrev>\n <CalendarHeading class=\"dt-cal-title\" />\n <CalendarNext class=\"dt-icon-btn-sm\"><PhCaretRight :size=\"16\" aria-hidden=\"true\" /></CalendarNext>\n </CalendarHeader>\n <CalendarGrid v-for=\"month in grid\" :key=\"month.value.toString()\" class=\"dt-cal-grid\">\n <CalendarGridHead>\n <CalendarGridRow>\n <CalendarHeadCell v-for=\"day in weekDays\" :key=\"day\" class=\"dt-cal-dow\">{{ day }}</CalendarHeadCell>\n </CalendarGridRow>\n </CalendarGridHead>\n <CalendarGridBody>\n <CalendarGridRow v-for=\"(week, i) in month.rows\" :key=\"i\">\n <CalendarCell v-for=\"d in week\" :key=\"d.toString()\" :date=\"d\" class=\"dt-cal-cell\">\n <CalendarCellTrigger :day=\"d\" :month=\"month.value\" class=\"dt-cal-day\" />\n </CalendarCell>\n </CalendarGridRow>\n </CalendarGridBody>\n </CalendarGrid>\n </CalendarRoot>\n </PopoverContent>\n </PopoverPortal>\n </PopoverRoot>\n </span>\n</template>\n","<script setup lang=\"ts\">\n// Tarih hücre editörü (07 §5, T11-07): yazılabilir (\"24.10\", \"+7d\", \"today\") + takvim popover'ı (reka Popover + Calendar).\n// Popover üstünde çözümlenen tarih (\"Wed, Oct 28 · in 7 days\"); kapanınca odak input'a döner (ikinci Esc düzenlemeyi\n// iptal eder). Popover portalda: `dt-sheet-layer` dışarı tık sayılmaz. Alt↓ takvimi açar.\nimport { getDayOfWeek, getLocalTimeZone, parseDate, startOfWeek, today, type DateValue } from '@internationalized/date'\nimport { PhCalendarBlank, PhCaretLeft, PhCaretRight } from '@phosphor-icons/vue'\nimport {\n CalendarCell,\n CalendarCellTrigger,\n CalendarGrid,\n CalendarGridBody,\n CalendarGridHead,\n CalendarGridRow,\n CalendarHeadCell,\n CalendarHeader,\n CalendarHeading,\n CalendarNext,\n CalendarPrev,\n CalendarRoot,\n PopoverContent,\n PopoverPortal,\n PopoverRoot,\n PopoverTrigger,\n} from 'reka-ui'\nimport { computed, nextTick, onMounted, ref } from 'vue'\nimport { getFormat, toDate } from '../../core/format'\nimport { useDataTableContext } from '../../core/plugin'\nimport type { ColumnDef } from '../../types/columns'\nimport { inputText, parseInput } from '../parse'\nimport { focusEnd, useParseEnv } from './useParseEnv'\n\nconst props = defineProps<{ modelValue: unknown; row: object; column: ColumnDef }>()\nconst emit = defineEmits<{ 'update:modelValue': [value: unknown] }>()\nconst { i18n, locale } = useDataTableContext()\nconst env = useParseEnv()\nconst fmt = getFormat(locale)\nconst dayFmt = new Intl.DateTimeFormat(locale, { weekday: 'short', month: 'short', day: 'numeric' })\nconst el = ref<HTMLInputElement | null>(null)\nconst open = ref(false)\nconst text = ref(inputText(props.column, props.modelValue))\nonMounted(() => focusEnd(el.value))\n\nconst tz = getLocalTimeZone()\nconst now = today(tz)\nconst weekStartsOn = getDayOfWeek(startOfWeek(now, locale), 'en-US') as 0 | 1 | 2 | 3 | 4 | 5 | 6\nconst safe = (s: unknown): DateValue | undefined => {\n try {\n return typeof s === 'string' && s ? parseDate(s.slice(0, 10)) : undefined\n } catch {\n return undefined\n }\n}\nconst single = computed(() => safe(props.modelValue))\nconst resolved = computed(() => {\n const v = props.modelValue\n if (typeof v !== 'string' || !single.value) return null\n const d = toDate(v.slice(0, 10))\n return { day: dayFmt.format(d), relative: fmt.relative(d) }\n})\n\nconst onInput = () => {\n text.value = el.value!.value\n emit('update:modelValue', parseInput(props.column, text.value, env()))\n}\nconst onPick = (d: DateValue | undefined) => {\n if (!d) return\n const iso = d.toString()\n text.value = iso\n emit('update:modelValue', iso)\n open.value = false\n}\nconst refocus = (e: Event) => {\n e.preventDefault()\n void nextTick(() => focusEnd(el.value))\n}\nconst onKeydown = (e: KeyboardEvent) => {\n if (e.altKey && e.key === 'ArrowDown') {\n e.preventDefault()\n open.value = true\n }\n}\n</script>\n\n<template>\n <span class=\"dt-cell-editor is-date\">\n <input\n ref=\"el\"\n class=\"dt-cell-input\"\n type=\"text\"\n :value=\"text\"\n :aria-label=\"column.header\"\n autocomplete=\"off\"\n @input=\"onInput\"\n @keydown=\"onKeydown\"\n />\n <PopoverRoot v-model:open=\"open\">\n <PopoverTrigger as-child>\n <button type=\"button\" class=\"dt-cell-editor-btn\" tabindex=\"-1\" :aria-label=\"i18n.t('type.date')\">\n <PhCalendarBlank :size=\"14\" aria-hidden=\"true\" />\n </button>\n </PopoverTrigger>\n <PopoverPortal>\n <PopoverContent\n class=\"dt-pop dt-cell-date dt-sheet-layer\"\n align=\"start\"\n :side-offset=\"4\"\n @close-auto-focus=\"refocus\"\n >\n <div v-if=\"resolved\" class=\"dt-cell-date-head\">\n <strong>{{ resolved.day }}</strong>\n <span>{{ resolved.relative }}</span>\n </div>\n <CalendarRoot\n v-slot=\"{ weekDays, grid }\"\n class=\"dt-calendar\"\n :model-value=\"single\"\n :locale=\"locale\"\n :week-starts-on=\"weekStartsOn\"\n :placeholder=\"single ?? now\"\n @update:model-value=\"(d) => onPick(d as DateValue | undefined)\"\n >\n <CalendarHeader class=\"dt-cal-head\">\n <CalendarPrev class=\"dt-icon-btn-sm\"><PhCaretLeft :size=\"16\" aria-hidden=\"true\" /></CalendarPrev>\n <CalendarHeading class=\"dt-cal-title\" />\n <CalendarNext class=\"dt-icon-btn-sm\"><PhCaretRight :size=\"16\" aria-hidden=\"true\" /></CalendarNext>\n </CalendarHeader>\n <CalendarGrid v-for=\"month in grid\" :key=\"month.value.toString()\" class=\"dt-cal-grid\">\n <CalendarGridHead>\n <CalendarGridRow>\n <CalendarHeadCell v-for=\"day in weekDays\" :key=\"day\" class=\"dt-cal-dow\">{{ day }}</CalendarHeadCell>\n </CalendarGridRow>\n </CalendarGridHead>\n <CalendarGridBody>\n <CalendarGridRow v-for=\"(week, i) in month.rows\" :key=\"i\">\n <CalendarCell v-for=\"d in week\" :key=\"d.toString()\" :date=\"d\" class=\"dt-cal-cell\">\n <CalendarCellTrigger :day=\"d\" :month=\"month.value\" class=\"dt-cal-day\" />\n </CalendarCell>\n </CalendarGridRow>\n </CalendarGridBody>\n </CalendarGrid>\n </CalendarRoot>\n </PopoverContent>\n </PopoverPortal>\n </PopoverRoot>\n </span>\n</template>\n","// Yerleşik editörlerin DataSheet'ten aldığı iç bağlam (public sözleşme değil; özel editörler yalnızca props alır).\nimport { inject, type InjectionKey } from 'vue'\n\nexport interface SheetEditorContext {\n /** Yazarak açılan `multiselect` editöründe aramaya giden ilk metin (seçimler korunur). */\n seed: () => string | undefined\n}\n\nexport const SHEET_EDITOR_KEY: InjectionKey<SheetEditorContext> = Symbol('dt-sheet-editor')\n\nexport const useSheetEditor = (): SheetEditorContext => inject(SHEET_EDITOR_KEY, { seed: () => undefined })\n","<script setup lang=\"ts\">\n// Çoklu seçim editörü (07 §5, 06 §7 T11-07): multiselect. Hücre içinde arama kutusu, altta seçenek listesi (reka Combobox,\n// `multiple`). Yazmak süzer; eşleşen seçenek yoksa liste açılmaz (boş listbox olmaz, axe). Enter vurgulu seçeneği aç/kapar;\n// seçim listeyi açık tutar, seçili seçenek tik alır, tekrar seçmek kaldırır. Listede olmayan metin yok sayılır: listede olmayan\n// değer yalnızca yapıştırmayla girer ve \"isn't an option\" hatası alır (select ile aynı). Esc kaydedip çıkar (SheetGrid).\n// Liste portalda: `dt-sheet-layer`.\nimport { PhCheck } from '@phosphor-icons/vue'\nimport {\n ComboboxAnchor,\n ComboboxContent,\n ComboboxInput,\n ComboboxItem,\n ComboboxItemIndicator,\n ComboboxPortal,\n ComboboxRoot,\n ComboboxViewport,\n} from 'reka-ui'\nimport { computed, nextTick, onMounted, ref, watch } from 'vue'\nimport { badge } from '../../core/cells/renderCell'\nimport type { ColumnDef, OptionDef } from '../../types/columns'\nimport { useDataTableContext } from '../../core/plugin'\nimport { useSheetEditor } from './context'\nimport { focusEnd } from './useParseEnv'\n\ntype Value = string | number\nconst props = defineProps<{ modelValue: unknown; row: object; column: ColumnDef }>()\nconst emit = defineEmits<{ 'update:modelValue': [value: unknown] }>()\nconst { locale } = useDataTableContext()\nconst lower = (t: string) => t.toLocaleLowerCase(locale)\nconst sheet = useSheetEditor()\n\nconst def = computed(() => props.column as Extract<ColumnDef, { type: 'multiselect' }>)\nconst values = computed<Value[]>(() => (Array.isArray(props.modelValue) ? (props.modelValue as Value[]) : []))\n/** Sütunun seçenekleri: satıra göre kapalı olanlar yok, seçili olanlar kalır. */\nconst suggestions = computed<OptionDef[]>(() => {\n const d = def.value\n return d.options.filter((o) => values.value.includes(o.value) || !d.optionEnabled || d.optionEnabled(o, props.row))\n})\n\nconst search = ref(sheet.seed() ?? '')\n/** Süzme burada (reka'nınki kapalı): eşleşme yoksa liste hiç açılmaz. */\nconst shown = computed(() => {\n const q = lower(search.value.trim())\n return q ? suggestions.value.filter((o) => lower(o.label).includes(q)) : suggestions.value\n})\nconst wantOpen = ref(true)\nconst open = computed({ get: () => wantOpen.value && shown.value.length > 0, set: (v) => (wantOpen.value = v) })\n// reka listenin id'sini input'a geç yazıyor (aria-controls=\"\"): açılınca DOM'daki gerçek id okunur (OptionCell ile aynı).\nconst listId = ref<string | undefined>()\nwatch(\n open,\n (o) => {\n if (o)\n void nextTick(() => {\n listId.value = document.querySelector<HTMLElement>('.dt-cell-list[role=\"listbox\"]')?.id || undefined\n })\n },\n { immediate: true },\n)\n/** reka aç/kapa yapılmış yeni diziyi verir; arama temizlenir, liste açık kalır. */\nconst onPick = (v: unknown) => {\n if (!Array.isArray(v)) return\n emit('update:modelValue', v.length ? v : null)\n search.value = ''\n void nextTick(reveal)\n}\nconst onKeydown = (e: KeyboardEvent) => {\n if (e.altKey && e.key === 'ArrowDown') {\n e.preventDefault()\n open.value = true\n }\n}\nconst input = ref<{ $el: HTMLInputElement } | null>(null)\nconst reveal = () => focusEnd(input.value?.$el ?? null)\nonMounted(() => void nextTick(reveal))\n\n// Sabit bileşen: her render'da yeni bileşen üretmek öğeyi mousedown–mouseup arasında değiştirir, click kaybolur.\nconst Item = (p: { o: OptionDef }) => badge(p.o.tone, p.o.label)\n</script>\n\n<template>\n <ComboboxRoot\n v-model:open=\"open\"\n class=\"dt-cell-editor is-multi\"\n multiple\n :model-value=\"values\"\n :reset-search-term-on-blur=\"false\"\n :reset-search-term-on-select=\"false\"\n ignore-filter\n @update:model-value=\"onPick\"\n >\n <ComboboxAnchor class=\"dt-cell-anchor\">\n <ComboboxInput\n ref=\"input\"\n v-model=\"search\"\n class=\"dt-cell-input\"\n :display-value=\"() => search\"\n autocomplete=\"off\"\n :aria-label=\"column.header\"\n :aria-controls=\"listId\"\n @keydown=\"onKeydown\"\n />\n </ComboboxAnchor>\n <ComboboxPortal>\n <ComboboxContent\n class=\"dt-pop dt-cell-list dt-sheet-layer\"\n position=\"popper\"\n align=\"start\"\n :side-offset=\"2\"\n :aria-label=\"column.header\"\n >\n <ComboboxViewport>\n <ComboboxItem\n v-for=\"o in shown\"\n :key=\"String(o.value)\"\n class=\"dt-pop-item dt-cell-option\"\n :value=\"o.value\"\n :text-value=\"o.label\"\n >\n <Item :o=\"o\" />\n <ComboboxItemIndicator class=\"dt-cell-option-check\">\n <PhCheck :size=\"14\" aria-hidden=\"true\" />\n </ComboboxItemIndicator>\n <kbd class=\"dt-kbd dt-cell-option-enter\" aria-hidden=\"true\">↵</kbd>\n </ComboboxItem>\n </ComboboxViewport>\n </ComboboxContent>\n </ComboboxPortal>\n </ComboboxRoot>\n</template>\n","<script setup lang=\"ts\">\n// Çoklu seçim editörü (07 §5, 06 §7 T11-07): multiselect. Hücre içinde arama kutusu, altta seçenek listesi (reka Combobox,\n// `multiple`). Yazmak süzer; eşleşen seçenek yoksa liste açılmaz (boş listbox olmaz, axe). Enter vurgulu seçeneği aç/kapar;\n// seçim listeyi açık tutar, seçili seçenek tik alır, tekrar seçmek kaldırır. Listede olmayan metin yok sayılır: listede olmayan\n// değer yalnızca yapıştırmayla girer ve \"isn't an option\" hatası alır (select ile aynı). Esc kaydedip çıkar (SheetGrid).\n// Liste portalda: `dt-sheet-layer`.\nimport { PhCheck } from '@phosphor-icons/vue'\nimport {\n ComboboxAnchor,\n ComboboxContent,\n ComboboxInput,\n ComboboxItem,\n ComboboxItemIndicator,\n ComboboxPortal,\n ComboboxRoot,\n ComboboxViewport,\n} from 'reka-ui'\nimport { computed, nextTick, onMounted, ref, watch } from 'vue'\nimport { badge } from '../../core/cells/renderCell'\nimport type { ColumnDef, OptionDef } from '../../types/columns'\nimport { useDataTableContext } from '../../core/plugin'\nimport { useSheetEditor } from './context'\nimport { focusEnd } from './useParseEnv'\n\ntype Value = string | number\nconst props = defineProps<{ modelValue: unknown; row: object; column: ColumnDef }>()\nconst emit = defineEmits<{ 'update:modelValue': [value: unknown] }>()\nconst { locale } = useDataTableContext()\nconst lower = (t: string) => t.toLocaleLowerCase(locale)\nconst sheet = useSheetEditor()\n\nconst def = computed(() => props.column as Extract<ColumnDef, { type: 'multiselect' }>)\nconst values = computed<Value[]>(() => (Array.isArray(props.modelValue) ? (props.modelValue as Value[]) : []))\n/** Sütunun seçenekleri: satıra göre kapalı olanlar yok, seçili olanlar kalır. */\nconst suggestions = computed<OptionDef[]>(() => {\n const d = def.value\n return d.options.filter((o) => values.value.includes(o.value) || !d.optionEnabled || d.optionEnabled(o, props.row))\n})\n\nconst search = ref(sheet.seed() ?? '')\n/** Süzme burada (reka'nınki kapalı): eşleşme yoksa liste hiç açılmaz. */\nconst shown = computed(() => {\n const q = lower(search.value.trim())\n return q ? suggestions.value.filter((o) => lower(o.label).includes(q)) : suggestions.value\n})\nconst wantOpen = ref(true)\nconst open = computed({ get: () => wantOpen.value && shown.value.length > 0, set: (v) => (wantOpen.value = v) })\n// reka listenin id'sini input'a geç yazıyor (aria-controls=\"\"): açılınca DOM'daki gerçek id okunur (OptionCell ile aynı).\nconst listId = ref<string | undefined>()\nwatch(\n open,\n (o) => {\n if (o)\n void nextTick(() => {\n listId.value = document.querySelector<HTMLElement>('.dt-cell-list[role=\"listbox\"]')?.id || undefined\n })\n },\n { immediate: true },\n)\n/** reka aç/kapa yapılmış yeni diziyi verir; arama temizlenir, liste açık kalır. */\nconst onPick = (v: unknown) => {\n if (!Array.isArray(v)) return\n emit('update:modelValue', v.length ? v : null)\n search.value = ''\n void nextTick(reveal)\n}\nconst onKeydown = (e: KeyboardEvent) => {\n if (e.altKey && e.key === 'ArrowDown') {\n e.preventDefault()\n open.value = true\n }\n}\nconst input = ref<{ $el: HTMLInputElement } | null>(null)\nconst reveal = () => focusEnd(input.value?.$el ?? null)\nonMounted(() => void nextTick(reveal))\n\n// Sabit bileşen: her render'da yeni bileşen üretmek öğeyi mousedown–mouseup arasında değiştirir, click kaybolur.\nconst Item = (p: { o: OptionDef }) => badge(p.o.tone, p.o.label)\n</script>\n\n<template>\n <ComboboxRoot\n v-model:open=\"open\"\n class=\"dt-cell-editor is-multi\"\n multiple\n :model-value=\"values\"\n :reset-search-term-on-blur=\"false\"\n :reset-search-term-on-select=\"false\"\n ignore-filter\n @update:model-value=\"onPick\"\n >\n <ComboboxAnchor class=\"dt-cell-anchor\">\n <ComboboxInput\n ref=\"input\"\n v-model=\"search\"\n class=\"dt-cell-input\"\n :display-value=\"() => search\"\n autocomplete=\"off\"\n :aria-label=\"column.header\"\n :aria-controls=\"listId\"\n @keydown=\"onKeydown\"\n />\n </ComboboxAnchor>\n <ComboboxPortal>\n <ComboboxContent\n class=\"dt-pop dt-cell-list dt-sheet-layer\"\n position=\"popper\"\n align=\"start\"\n :side-offset=\"2\"\n :aria-label=\"column.header\"\n >\n <ComboboxViewport>\n <ComboboxItem\n v-for=\"o in shown\"\n :key=\"String(o.value)\"\n class=\"dt-pop-item dt-cell-option\"\n :value=\"o.value\"\n :text-value=\"o.label\"\n >\n <Item :o=\"o\" />\n <ComboboxItemIndicator class=\"dt-cell-option-check\">\n <PhCheck :size=\"14\" aria-hidden=\"true\" />\n </ComboboxItemIndicator>\n <kbd class=\"dt-kbd dt-cell-option-enter\" aria-hidden=\"true\">↵</kbd>\n </ComboboxItem>\n </ComboboxViewport>\n </ComboboxContent>\n </ComboboxPortal>\n </ComboboxRoot>\n</template>\n","// Doldurma (07 §8): kaynak en az iki sayı ve sabit artışlıysa seri devam eder (1, 2, 3 / 10, 20), aksi halde kaynak\n// döngüyle kopyalanır. Yukarı doldurmada seri geriye gider, kopya sondan başlar.\n\n/** `count` hedef değer; `up` yukarı yön. */\nexport function fillValues(source: unknown[], count: number, up = false): unknown[] {\n if (!source.length || count <= 0) return []\n const nums = source.every((v) => typeof v === 'number') ? (source as number[]) : null\n if (nums && nums.length >= 2) {\n const step = nums[1]! - nums[0]!\n if (nums.every((v, i) => i === 0 || Math.abs(v - nums[i - 1]! - step) < 1e-9)) {\n const base = up ? nums[0]! : nums[nums.length - 1]!\n const dir = up ? -1 : 1\n return Array.from({ length: count }, (_, i) => round(base + dir * step * (i + 1)))\n }\n }\n const n = source.length\n return Array.from({ length: count }, (_, i) => (up ? source[(n - 1 - (i % n) + n) % n] : source[i % n]))\n}\n\n/** Kayan nokta artığı (0.1 + 0.2) görünmesin: 10 anlamlı basamak. */\nconst round = (n: number): number => Number(n.toPrecision(10))\n","// Excel'den içe aktarma — saf fonksiyonlar (07 §13, 01): başlık satırı tespiti ve sütun eşleme dosya biçiminden\n// bağımsızdır (.xlsx ve .csv aynı yol); `@medyat/vue-data-table/sheet`'ten dışa verilir ve ayrı test edilir.\nimport { isoDay } from '../../core/filters/model'\nimport type { ColumnDef } from '../../types/columns'\n\n/** Hücre metni: tarih yerel gün olarak ISO, sayı olduğu gibi, boş → ''. */\nexport function cellText(v: unknown): string {\n if (v === null || v === undefined) return ''\n if (v instanceof Date) return Number.isNaN(v.getTime()) ? '' : isoDay(v)\n return String(v).trim()\n}\n\n/** Başlık normalizasyonu: küçük harf, baştaki/sondaki ve ardışık boşluklar, Türkçe karakterler (ı→i, ş→s …). */\nconst TR: Record<string, string> = { ı: 'i', i̇: 'i', ş: 's', ğ: 'g', ç: 'c', ö: 'o', ü: 'u', â: 'a', î: 'i', û: 'u' }\nexport const normalizeHeader = (s: string): string =>\n s\n .toLocaleLowerCase('tr')\n .replace(/ı|i̇|ş|ğ|ç|ö|ü|â|î|û/g, (ch) => TR[ch] ?? ch)\n .replace(/[^a-z0-9]+/g, ' ')\n .trim()\n\nconst isNumberLike = (s: string) => /^[-+]?[\\d.,\\s]*\\d[\\d.,\\s]*%?$/.test(s)\n\n/**\n * Başlık satırı: ilk 20 satır içinde, boş olmayan hücre sayısı en yüksek ve hücrelerinin çoğu metin olan ilk satır;\n * eşitlikte ilk boş olmayan satır. Hiç aday yoksa 0.\n */\nexport function detectHeaderRow(rows: unknown[][]): number {\n let best = -1\n let bestScore = -1\n for (let i = 0; i < Math.min(rows.length, 20); i++) {\n const cells = (rows[i] ?? []).map(cellText).filter(Boolean)\n if (!cells.length) continue\n const textual = cells.filter((c) => !isNumberLike(c)).length\n if (textual * 2 < cells.length) continue\n if (cells.length > bestScore) {\n bestScore = cells.length\n best = i\n }\n }\n if (best >= 0) return best\n const first = rows.findIndex((r) => (r ?? []).some((c) => cellText(c) !== ''))\n return first < 0 ? 0 : first\n}\n\n/**\n * Otomatik eşleme: başlık normalize edilerek sütunun `header`, `id` ya da `importAliases` değerlerinden biriyle aynıysa\n * ve yalnızca tek bir sütuna uyuyorsa. Eşleşmeyen ya da birden fazla sütuna uyan başlık haritada yoktur.\n */\nexport function matchColumns(\n headers: string[],\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n columns: Array<Pick<ColumnDef<any>, 'id' | 'header' | 'importAliases'>>,\n): Record<number, string> {\n const out: Record<number, string> = {}\n const names = columns.map((c) => new Set([c.header, String(c.id), ...(c.importAliases ?? [])].map(normalizeHeader)))\n headers.forEach((h, i) => {\n const n = normalizeHeader(h)\n if (!n) return\n const hits = columns.filter((_, j) => names[j]!.has(n))\n if (hits.length === 1) out[i] = String(hits[0]!.id)\n })\n return out\n}\n","<script setup lang=\"ts\" generic=\"Row extends object\">\n// Import from Excel (07 §13, handoff 06 §11, T12-09/10/11): dosya yalnızca grid'i doldurur; Save'e kadar kaydedilmez.\n// Dosya (bırak/seç) → `parseFile` → sayfa · başlık satırı (otomatik, değiştirilebilir) · eşleşme anahtarı (eşlenmeden\n// Apply pasif) · sütun eşleme (otomatik tek/kesin, elle değiştirilebilir, boş kalan alınmaz, read-only pasif) · ilk değer\n// önizlemesi (1.650,00 → 1,650.00) · özet (listede/sunucuda olanlar günceller, yeni anahtarlar satır olur). Dosyadaki\n// boş hücre mevcut değeri silmez (Q3). `maxRows` aşılırsa Apply pasif.\nimport {\n PhArrowLeft,\n PhArrowRight,\n PhInfo,\n PhLock,\n PhTable,\n PhUploadSimple,\n PhWarningCircle,\n PhX,\n} from '@phosphor-icons/vue'\nimport {\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogOverlay,\n DialogPortal,\n DialogRoot,\n DialogTitle,\n} from 'reka-ui'\nimport { computed, ref, shallowRef, watch } from 'vue'\nimport { formatCell, type FormatEnv } from '../core/cells/format'\nimport { TYPE_SPECS } from '../core/cells/specs'\nimport { useDataTableContext } from '../core/plugin'\nimport type { ColumnDef } from '../types/columns'\nimport type { Plural } from '../types/core'\nimport type { ParsedWorkbook } from '../types/sheet'\nimport { cellText, detectHeaderRow, matchColumns } from './import/model'\nimport { inferDecimal, parseInput, type ParseEnv } from './parse'\n\nexport interface ImportRow {\n key: string\n values: Record<string, unknown>\n}\nexport interface ImportPayload {\n rows: ImportRow[]\n addNew: boolean\n}\n\nconst props = defineProps<{\n parseFile: (file: File) => Promise<ParsedWorkbook>\n columns: Array<ColumnDef<Row>>\n keyColumn: string\n entity: Plural\n maxRows: number\n /** Şu anki satır sayısı (sınır için). */\n rowCount: number\n inList: (key: string) => boolean\n parseEnv: (locale?: string) => ParseEnv\n fmtEnv: FormatEnv\n}>()\nconst emit = defineEmits<{ apply: [payload: ImportPayload] }>()\nconst open = defineModel<boolean>('open', { default: false })\nconst { i18n, locale } = useDataTableContext()\nconst SKIP = '__skip__'\n\nconst keyDef = computed(() => props.columns.find((c) => c.id === props.keyColumn))\nconst keyHeader = computed(() => keyDef.value?.header ?? props.keyColumn)\n/** Eşlenebilir alanlar: anahtar dışındaki sütunlar; düzenlenemeyenler listede pasif. */\nconst fields = computed(() =>\n props.columns\n .filter((c) => c.id !== props.keyColumn)\n .map((c) => ({ id: c.id as string, def: c, editable: !!c.editable })),\n)\n\nconst file = shallowRef<File | null>(null)\nconst workbook = shallowRef<ParsedWorkbook | null>(null)\nconst loading = ref(false)\nconst failed = ref(false)\n/** `parseFile`'ın fırlattığı sebep (uygulamanın metni); `import.failed` başlığının altında gösterilir. */\nconst failReason = ref('')\nconst sheetIndex = ref(0)\nconst headerRow = ref(0)\nconst mapping = ref<Record<number, string>>({})\nconst keyCol = ref<number | null>(null)\nconst addNew = ref(true)\nconst showNew = ref(false)\nconst dragging = ref(false)\nconst input = ref<HTMLInputElement | null>(null)\n\nconst rows = computed(() => workbook.value?.sheets[sheetIndex.value]?.rows ?? [])\nconst headers = computed(() => (rows.value[headerRow.value] ?? []).map(cellText))\nconst dataRows = computed(() =>\n rows.value.slice(headerRow.value + 1).filter((r) => (r ?? []).some((c) => cellText(c) !== '')),\n)\nconst headerOptions = computed(() => Math.min(rows.value.length, 20))\n\nconst rebuild = () => {\n const auto = matchColumns(headers.value, props.columns)\n const m: Record<number, string> = {}\n let key: number | null = null\n for (const [i, id] of Object.entries(auto)) {\n if (id === props.keyColumn) key = key ?? Number(i)\n else if (fields.value.find((f) => f.id === id)?.editable) m[Number(i)] = id\n }\n mapping.value = m\n keyCol.value = key\n showNew.value = false\n}\nconst load = async (f: File) => {\n file.value = f\n failed.value = false\n loading.value = true\n try {\n const wb = await props.parseFile(f)\n workbook.value = wb\n sheetIndex.value = 0\n headerRow.value = detectHeaderRow(wb.sheets[0]?.rows ?? [])\n rebuild()\n } catch (e) {\n workbook.value = null\n failed.value = true\n failReason.value = e instanceof Error ? e.message : ''\n } finally {\n loading.value = false\n }\n}\nwatch(sheetIndex, () => {\n headerRow.value = detectHeaderRow(rows.value)\n rebuild()\n})\nconst onHeaderRow = (n: number) => {\n headerRow.value = n\n rebuild()\n}\nconst onPick = (e: Event) => {\n const f = (e.target as HTMLInputElement).files?.[0]\n if (f) void load(f)\n ;(e.target as HTMLInputElement).value = ''\n}\nconst onDrop = (e: DragEvent) => {\n dragging.value = false\n const f = e.dataTransfer?.files?.[0]\n if (f) void load(f)\n}\nconst reset = () => {\n file.value = null\n workbook.value = null\n failed.value = false\n mapping.value = {}\n keyCol.value = null\n}\nwatch(open, (o) => {\n if (!o) reset()\n})\n\n// Anahtarlar: listede olanlar o satırı günceller, olmayanlar satır olarak eklenir (sunucu anahtara göre upsert eder, D47).\nconst keyTexts = computed(() =>\n keyCol.value === null ? [] : dataRows.value.map((r) => cellText(r?.[keyCol.value!])).filter(Boolean),\n)\nconst summary = computed(() => {\n if (!keyTexts.value.length) return null\n const seen = new Set<string>()\n let updates = 0\n const news: string[] = []\n for (const k of keyTexts.value) {\n if (seen.has(k)) continue\n seen.add(k)\n if (props.inList(k)) updates++\n else news.push(k)\n }\n return { updates, news }\n})\nconst overLimit = computed(() => {\n const s = summary.value\n return !!s && addNew.value && props.rowCount + s.news.length > props.maxRows\n})\nconst canApply = computed(() => !!workbook.value && keyCol.value !== null && !!summary.value && !overLimit.value)\n\n// Önizleme: ilk veri satırının ham değeri ve çözümlenmiş biçimi (sütun bazında ondalık çıkarımı, 07 §7).\nconst localeFor = (col: number, def: ColumnDef<Row>): string => {\n if (!TYPE_SPECS[def.type].numeric) return locale\n const dec = inferDecimal(dataRows.value.slice(0, 50).map((r) => cellText(r?.[col])))\n return dec === ',' ? 'de' : dec === '.' ? 'en' : locale\n}\nconst convert = (col: number, def: ColumnDef<Row>, raw: unknown): unknown => {\n if (typeof raw === 'number' || typeof raw === 'boolean') return raw\n if (raw instanceof Date) return cellText(raw)\n const text = cellText(raw)\n return text === '' ? null : parseInput(def, text, props.parseEnv(localeFor(col, def)))\n}\nconst preview = (col: number): { raw: string; shown: string | null } => {\n const row = dataRows.value[0]\n const raw = cellText(row?.[col])\n const id = mapping.value[col]\n const def = id ? props.columns.find((c) => c.id === id) : undefined\n if (!def || !raw) return { raw, shown: null }\n const value = convert(col, def, row?.[col])\n const shown = formatCell(def, {} as Row, value, props.fmtEnv)\n return { raw, shown: shown === raw ? null : shown }\n}\n\nconst apply = () => {\n if (!canApply.value || keyCol.value === null) return\n const out: ImportRow[] = []\n for (const r of dataRows.value) {\n const key = cellText(r?.[keyCol.value])\n if (!key) continue\n const values: Record<string, unknown> = {}\n for (const [col, id] of Object.entries(mapping.value)) {\n if (!id || id === SKIP) continue\n const def = props.columns.find((c) => c.id === id)\n const raw = r?.[Number(col)]\n if (!def || cellText(raw) === '') continue // boş hücre mevcut değeri silmez (Q3)\n values[id] = convert(Number(col), def, raw)\n }\n out.push({ key, values })\n }\n emit('apply', { rows: out, addNew: addNew.value })\n open.value = false\n}\nconst sheetInfo = computed(() => {\n const s = workbook.value?.sheets[sheetIndex.value]\n return s ? i18n.t('import.sheetInfo', { sheet: s.name, count: dataRows.value.length }) : ''\n})\n</script>\n\n<template>\n <DialogRoot v-model:open=\"open\">\n <DialogPortal>\n <DialogOverlay class=\"dt-scrim\" />\n <DialogContent class=\"dt-dialog dt-import\">\n <div class=\"dt-import-head\">\n <div>\n <DialogTitle class=\"dt-dialog-title\">{{ i18n.t('import.title') }}</DialogTitle>\n <DialogDescription class=\"dt-dialog-body\">\n {{ i18n.t('import.body', { key: keyHeader, entity }) }}\n </DialogDescription>\n </div>\n <DialogClose class=\"dt-btn dt-btn-icon dt-btn-ghost\" :aria-label=\"i18n.t('common.close')\">\n <PhX :size=\"16\" aria-hidden=\"true\" />\n </DialogClose>\n </div>\n <div class=\"dt-import-body\">\n <input ref=\"input\" type=\"file\" class=\"dt-sr-only\" accept=\".xlsx,.xls,.csv\" tabindex=\"-1\" @change=\"onPick\" />\n <button\n v-if=\"!workbook\"\n type=\"button\"\n class=\"dt-import-drop\"\n :class=\"{ 'is-over': dragging, 'is-failed': failed }\"\n :aria-busy=\"loading ? 'true' : undefined\"\n @click=\"input?.click()\"\n @dragover.prevent=\"dragging = true\"\n @dragleave=\"dragging = false\"\n @drop.prevent=\"onDrop\"\n >\n <span class=\"dt-import-drop-icon\"><PhUploadSimple :size=\"20\" aria-hidden=\"true\" /></span>\n <span>{{ i18n.t('import.drop') }}</span>\n </button>\n <template v-else>\n <div class=\"dt-import-file\">\n <span class=\"dt-import-file-icon\"><PhTable :size=\"18\" aria-hidden=\"true\" /></span>\n <span class=\"dt-import-file-text\">\n <strong>{{ file?.name }}</strong>\n <label v-if=\"workbook.sheets.length > 1\" class=\"dt-select dt-import-sheet\">\n <select v-model=\"sheetIndex\" :aria-label=\"i18n.t('import.sheetInfo', { sheet: '', count: 0 })\">\n <option v-for=\"(s, i) in workbook.sheets\" :key=\"i\" :value=\"i\">\n {{ i18n.t('import.sheetInfo', { sheet: s.name, count: s.rows.length }) }}\n </option>\n </select>\n </label>\n <span v-else class=\"dt-import-sheet-info\">{{ sheetInfo }}</span>\n </span>\n <button type=\"button\" class=\"dt-btn dt-btn-sm\" @click=\"input?.click()\">\n {{ i18n.t('import.replace') }}\n </button>\n </div>\n <div class=\"dt-import-match\">\n <span class=\"dt-import-match-label\">{{ i18n.t('import.matchBy') }}</span>\n <span class=\"dt-import-key\">\n <PhLock :size=\"12\" aria-hidden=\"true\" />\n <span class=\"dt-mono\">{{ keyHeader }}</span>\n </span>\n <PhArrowLeft :size=\"14\" aria-hidden=\"true\" />\n <label class=\"dt-select dt-import-keysel\" :class=\"{ 'is-missing': keyCol === null }\">\n <select\n :value=\"keyCol ?? ''\"\n :aria-label=\"i18n.t('import.excelColumn')\"\n @change=\"\n keyCol =\n ($event.target as HTMLSelectElement).value === ''\n ? null\n : Number(($event.target as HTMLSelectElement).value)\n \"\n >\n <option value=\"\">{{ i18n.t('import.excelColumn') }}</option>\n <option v-for=\"(h, i) in headers\" :key=\"i\" :value=\"i\" :disabled=\"!h\">{{ h }}</option>\n </select>\n </label>\n <span class=\"dt-import-spacer\" />\n <label class=\"dt-select dt-import-headerrow\">\n <span class=\"dt-import-match-label\">{{ i18n.t('import.headerRow') }}</span>\n <select :value=\"headerRow\" @change=\"onHeaderRow(Number(($event.target as HTMLSelectElement).value))\">\n <option v-for=\"n in headerOptions\" :key=\"n\" :value=\"n - 1\">\n {{ i18n.t('import.headerRowN', { n }) }}\n </option>\n </select>\n </label>\n </div>\n <p v-if=\"keyCol === null\" class=\"dt-import-warn\">\n <PhWarningCircle :size=\"14\" aria-hidden=\"true\" />\n {{ i18n.t('import.keyRequired', { key: keyHeader }) }}\n </p>\n <table class=\"dt-import-table\">\n <colgroup>\n <col class=\"dt-import-col-excel\" />\n <col class=\"dt-import-col-arrow\" />\n <col class=\"dt-import-col-field\" />\n <col />\n </colgroup>\n <thead>\n <tr>\n <th>{{ i18n.t('import.excelColumn') }}</th>\n <th />\n <th>{{ i18n.t('import.field') }}</th>\n <th>{{ i18n.t('import.firstValue') }}</th>\n </tr>\n </thead>\n <tbody>\n <tr\n v-for=\"(h, i) in headers\"\n :key=\"i\"\n :class=\"{ 'is-skipped': i !== keyCol && (mapping[i] ?? '') === SKIP }\"\n >\n <td class=\"dt-import-col\" :title=\"h\">{{ h }}</td>\n <td><PhArrowRight :size=\"14\" aria-hidden=\"true\" /></td>\n <td>\n <template v-if=\"i === keyCol\">\n <span class=\"dt-mono\">{{ keyHeader }}</span>\n <span class=\"dt-import-muted\">{{ i18n.t('import.matchKey') }}</span>\n </template>\n <label v-else class=\"dt-select dt-import-field\">\n <select\n :value=\"mapping[i] ?? ''\"\n :aria-label=\"i18n.t('import.field')\"\n @change=\"mapping = { ...mapping, [i]: ($event.target as HTMLSelectElement).value }\"\n >\n <option value=\"\" disabled>{{ i18n.t('import.chooseField') }}</option>\n <option :value=\"SKIP\">{{ i18n.t('import.skip') }}</option>\n <option v-for=\"f in fields\" :key=\"f.id\" :value=\"f.id\" :disabled=\"!f.editable\">\n {{ f.def.header }}{{ f.editable ? '' : ` · ${i18n.t('sheet.readOnly.badge')}` }}\n </option>\n </select>\n </label>\n </td>\n <td class=\"dt-import-preview\">\n <template v-if=\"i === keyCol\">\n <span class=\"dt-mono\">{{ preview(i).raw }}</span>\n </template>\n <template v-else-if=\"preview(i).shown\">\n <span class=\"dt-import-muted\">{{ preview(i).raw }}</span>\n <PhArrowRight :size=\"12\" aria-hidden=\"true\" />\n <strong>{{ preview(i).shown }}</strong>\n </template>\n <span v-else :class=\"{ 'dt-import-muted': !mapping[i] || mapping[i] === SKIP }\">\n {{ preview(i).raw }}\n </span>\n </td>\n </tr>\n </tbody>\n </table>\n <div v-if=\"summary && keyCol !== null\" class=\"dt-import-summary\">\n <div class=\"dt-import-summary-line\">\n <PhInfo :size=\"16\" aria-hidden=\"true\" />\n <span>\n {{\n i18n.t('import.summary', {\n updates: summary.updates,\n news: summary.news.length,\n key: keyHeader,\n })\n }}\n </span>\n <button\n v-if=\"summary.news.length\"\n type=\"button\"\n class=\"dt-link dt-import-link\"\n @click=\"showNew = !showNew\"\n >\n {{ i18n.t('import.seeNew', { key: keyHeader }) }}\n </button>\n </div>\n <div v-if=\"showNew\" class=\"dt-import-newlist dt-mono\">{{ summary.news.join(', ') }}</div>\n <label v-if=\"summary.news.length\" class=\"dt-check-row\">\n <input v-model=\"addNew\" type=\"checkbox\" class=\"dt-checkbox\" />\n {{ i18n.t('import.addNew', { count: summary.news.length, key: keyHeader }) }}\n </label>\n <p v-if=\"overLimit\" class=\"dt-import-warn\">\n <PhWarningCircle :size=\"14\" aria-hidden=\"true\" />\n {{ i18n.t('sheet.limitFile', { count: rowCount + summary.news.length, max: maxRows }) }}\n </p>\n </div>\n </template>\n <p v-if=\"failed && !workbook\" class=\"dt-import-error\" role=\"alert\">\n {{ i18n.t('import.failed') }}\n <template v-if=\"failReason\">· {{ failReason }}</template>\n </p>\n </div>\n <div class=\"dt-import-foot\">\n <DialogClose class=\"dt-btn\">{{ i18n.t('common.cancel') }}</DialogClose>\n <button type=\"button\" class=\"dt-btn dt-btn-primary\" :disabled=\"!canApply\" @click=\"apply\">\n {{ i18n.t('import.apply') }}\n </button>\n </div>\n </DialogContent>\n </DialogPortal>\n </DialogRoot>\n</template>\n","<script setup lang=\"ts\" generic=\"Row extends object\">\n// Import from Excel (07 §13, handoff 06 §11, T12-09/10/11): dosya yalnızca grid'i doldurur; Save'e kadar kaydedilmez.\n// Dosya (bırak/seç) → `parseFile` → sayfa · başlık satırı (otomatik, değiştirilebilir) · eşleşme anahtarı (eşlenmeden\n// Apply pasif) · sütun eşleme (otomatik tek/kesin, elle değiştirilebilir, boş kalan alınmaz, read-only pasif) · ilk değer\n// önizlemesi (1.650,00 → 1,650.00) · özet (listede/sunucuda olanlar günceller, yeni anahtarlar satır olur). Dosyadaki\n// boş hücre mevcut değeri silmez (Q3). `maxRows` aşılırsa Apply pasif.\nimport {\n PhArrowLeft,\n PhArrowRight,\n PhInfo,\n PhLock,\n PhTable,\n PhUploadSimple,\n PhWarningCircle,\n PhX,\n} from '@phosphor-icons/vue'\nimport {\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogOverlay,\n DialogPortal,\n DialogRoot,\n DialogTitle,\n} from 'reka-ui'\nimport { computed, ref, shallowRef, watch } from 'vue'\nimport { formatCell, type FormatEnv } from '../core/cells/format'\nimport { TYPE_SPECS } from '../core/cells/specs'\nimport { useDataTableContext } from '../core/plugin'\nimport type { ColumnDef } from '../types/columns'\nimport type { Plural } from '../types/core'\nimport type { ParsedWorkbook } from '../types/sheet'\nimport { cellText, detectHeaderRow, matchColumns } from './import/model'\nimport { inferDecimal, parseInput, type ParseEnv } from './parse'\n\nexport interface ImportRow {\n key: string\n values: Record<string, unknown>\n}\nexport interface ImportPayload {\n rows: ImportRow[]\n addNew: boolean\n}\n\nconst props = defineProps<{\n parseFile: (file: File) => Promise<ParsedWorkbook>\n columns: Array<ColumnDef<Row>>\n keyColumn: string\n entity: Plural\n maxRows: number\n /** Şu anki satır sayısı (sınır için). */\n rowCount: number\n inList: (key: string) => boolean\n parseEnv: (locale?: string) => ParseEnv\n fmtEnv: FormatEnv\n}>()\nconst emit = defineEmits<{ apply: [payload: ImportPayload] }>()\nconst open = defineModel<boolean>('open', { default: false })\nconst { i18n, locale } = useDataTableContext()\nconst SKIP = '__skip__'\n\nconst keyDef = computed(() => props.columns.find((c) => c.id === props.keyColumn))\nconst keyHeader = computed(() => keyDef.value?.header ?? props.keyColumn)\n/** Eşlenebilir alanlar: anahtar dışındaki sütunlar; düzenlenemeyenler listede pasif. */\nconst fields = computed(() =>\n props.columns\n .filter((c) => c.id !== props.keyColumn)\n .map((c) => ({ id: c.id as string, def: c, editable: !!c.editable })),\n)\n\nconst file = shallowRef<File | null>(null)\nconst workbook = shallowRef<ParsedWorkbook | null>(null)\nconst loading = ref(false)\nconst failed = ref(false)\n/** `parseFile`'ın fırlattığı sebep (uygulamanın metni); `import.failed` başlığının altında gösterilir. */\nconst failReason = ref('')\nconst sheetIndex = ref(0)\nconst headerRow = ref(0)\nconst mapping = ref<Record<number, string>>({})\nconst keyCol = ref<number | null>(null)\nconst addNew = ref(true)\nconst showNew = ref(false)\nconst dragging = ref(false)\nconst input = ref<HTMLInputElement | null>(null)\n\nconst rows = computed(() => workbook.value?.sheets[sheetIndex.value]?.rows ?? [])\nconst headers = computed(() => (rows.value[headerRow.value] ?? []).map(cellText))\nconst dataRows = computed(() =>\n rows.value.slice(headerRow.value + 1).filter((r) => (r ?? []).some((c) => cellText(c) !== '')),\n)\nconst headerOptions = computed(() => Math.min(rows.value.length, 20))\n\nconst rebuild = () => {\n const auto = matchColumns(headers.value, props.columns)\n const m: Record<number, string> = {}\n let key: number | null = null\n for (const [i, id] of Object.entries(auto)) {\n if (id === props.keyColumn) key = key ?? Number(i)\n else if (fields.value.find((f) => f.id === id)?.editable) m[Number(i)] = id\n }\n mapping.value = m\n keyCol.value = key\n showNew.value = false\n}\nconst load = async (f: File) => {\n file.value = f\n failed.value = false\n loading.value = true\n try {\n const wb = await props.parseFile(f)\n workbook.value = wb\n sheetIndex.value = 0\n headerRow.value = detectHeaderRow(wb.sheets[0]?.rows ?? [])\n rebuild()\n } catch (e) {\n workbook.value = null\n failed.value = true\n failReason.value = e instanceof Error ? e.message : ''\n } finally {\n loading.value = false\n }\n}\nwatch(sheetIndex, () => {\n headerRow.value = detectHeaderRow(rows.value)\n rebuild()\n})\nconst onHeaderRow = (n: number) => {\n headerRow.value = n\n rebuild()\n}\nconst onPick = (e: Event) => {\n const f = (e.target as HTMLInputElement).files?.[0]\n if (f) void load(f)\n ;(e.target as HTMLInputElement).value = ''\n}\nconst onDrop = (e: DragEvent) => {\n dragging.value = false\n const f = e.dataTransfer?.files?.[0]\n if (f) void load(f)\n}\nconst reset = () => {\n file.value = null\n workbook.value = null\n failed.value = false\n mapping.value = {}\n keyCol.value = null\n}\nwatch(open, (o) => {\n if (!o) reset()\n})\n\n// Anahtarlar: listede olanlar o satırı günceller, olmayanlar satır olarak eklenir (sunucu anahtara göre upsert eder, D47).\nconst keyTexts = computed(() =>\n keyCol.value === null ? [] : dataRows.value.map((r) => cellText(r?.[keyCol.value!])).filter(Boolean),\n)\nconst summary = computed(() => {\n if (!keyTexts.value.length) return null\n const seen = new Set<string>()\n let updates = 0\n const news: string[] = []\n for (const k of keyTexts.value) {\n if (seen.has(k)) continue\n seen.add(k)\n if (props.inList(k)) updates++\n else news.push(k)\n }\n return { updates, news }\n})\nconst overLimit = computed(() => {\n const s = summary.value\n return !!s && addNew.value && props.rowCount + s.news.length > props.maxRows\n})\nconst canApply = computed(() => !!workbook.value && keyCol.value !== null && !!summary.value && !overLimit.value)\n\n// Önizleme: ilk veri satırının ham değeri ve çözümlenmiş biçimi (sütun bazında ondalık çıkarımı, 07 §7).\nconst localeFor = (col: number, def: ColumnDef<Row>): string => {\n if (!TYPE_SPECS[def.type].numeric) return locale\n const dec = inferDecimal(dataRows.value.slice(0, 50).map((r) => cellText(r?.[col])))\n return dec === ',' ? 'de' : dec === '.' ? 'en' : locale\n}\nconst convert = (col: number, def: ColumnDef<Row>, raw: unknown): unknown => {\n if (typeof raw === 'number' || typeof raw === 'boolean') return raw\n if (raw instanceof Date) return cellText(raw)\n const text = cellText(raw)\n return text === '' ? null : parseInput(def, text, props.parseEnv(localeFor(col, def)))\n}\nconst preview = (col: number): { raw: string; shown: string | null } => {\n const row = dataRows.value[0]\n const raw = cellText(row?.[col])\n const id = mapping.value[col]\n const def = id ? props.columns.find((c) => c.id === id) : undefined\n if (!def || !raw) return { raw, shown: null }\n const value = convert(col, def, row?.[col])\n const shown = formatCell(def, {} as Row, value, props.fmtEnv)\n return { raw, shown: shown === raw ? null : shown }\n}\n\nconst apply = () => {\n if (!canApply.value || keyCol.value === null) return\n const out: ImportRow[] = []\n for (const r of dataRows.value) {\n const key = cellText(r?.[keyCol.value])\n if (!key) continue\n const values: Record<string, unknown> = {}\n for (const [col, id] of Object.entries(mapping.value)) {\n if (!id || id === SKIP) continue\n const def = props.columns.find((c) => c.id === id)\n const raw = r?.[Number(col)]\n if (!def || cellText(raw) === '') continue // boş hücre mevcut değeri silmez (Q3)\n values[id] = convert(Number(col), def, raw)\n }\n out.push({ key, values })\n }\n emit('apply', { rows: out, addNew: addNew.value })\n open.value = false\n}\nconst sheetInfo = computed(() => {\n const s = workbook.value?.sheets[sheetIndex.value]\n return s ? i18n.t('import.sheetInfo', { sheet: s.name, count: dataRows.value.length }) : ''\n})\n</script>\n\n<template>\n <DialogRoot v-model:open=\"open\">\n <DialogPortal>\n <DialogOverlay class=\"dt-scrim\" />\n <DialogContent class=\"dt-dialog dt-import\">\n <div class=\"dt-import-head\">\n <div>\n <DialogTitle class=\"dt-dialog-title\">{{ i18n.t('import.title') }}</DialogTitle>\n <DialogDescription class=\"dt-dialog-body\">\n {{ i18n.t('import.body', { key: keyHeader, entity }) }}\n </DialogDescription>\n </div>\n <DialogClose class=\"dt-btn dt-btn-icon dt-btn-ghost\" :aria-label=\"i18n.t('common.close')\">\n <PhX :size=\"16\" aria-hidden=\"true\" />\n </DialogClose>\n </div>\n <div class=\"dt-import-body\">\n <input ref=\"input\" type=\"file\" class=\"dt-sr-only\" accept=\".xlsx,.xls,.csv\" tabindex=\"-1\" @change=\"onPick\" />\n <button\n v-if=\"!workbook\"\n type=\"button\"\n class=\"dt-import-drop\"\n :class=\"{ 'is-over': dragging, 'is-failed': failed }\"\n :aria-busy=\"loading ? 'true' : undefined\"\n @click=\"input?.click()\"\n @dragover.prevent=\"dragging = true\"\n @dragleave=\"dragging = false\"\n @drop.prevent=\"onDrop\"\n >\n <span class=\"dt-import-drop-icon\"><PhUploadSimple :size=\"20\" aria-hidden=\"true\" /></span>\n <span>{{ i18n.t('import.drop') }}</span>\n </button>\n <template v-else>\n <div class=\"dt-import-file\">\n <span class=\"dt-import-file-icon\"><PhTable :size=\"18\" aria-hidden=\"true\" /></span>\n <span class=\"dt-import-file-text\">\n <strong>{{ file?.name }}</strong>\n <label v-if=\"workbook.sheets.length > 1\" class=\"dt-select dt-import-sheet\">\n <select v-model=\"sheetIndex\" :aria-label=\"i18n.t('import.sheetInfo', { sheet: '', count: 0 })\">\n <option v-for=\"(s, i) in workbook.sheets\" :key=\"i\" :value=\"i\">\n {{ i18n.t('import.sheetInfo', { sheet: s.name, count: s.rows.length }) }}\n </option>\n </select>\n </label>\n <span v-else class=\"dt-import-sheet-info\">{{ sheetInfo }}</span>\n </span>\n <button type=\"button\" class=\"dt-btn dt-btn-sm\" @click=\"input?.click()\">\n {{ i18n.t('import.replace') }}\n </button>\n </div>\n <div class=\"dt-import-match\">\n <span class=\"dt-import-match-label\">{{ i18n.t('import.matchBy') }}</span>\n <span class=\"dt-import-key\">\n <PhLock :size=\"12\" aria-hidden=\"true\" />\n <span class=\"dt-mono\">{{ keyHeader }}</span>\n </span>\n <PhArrowLeft :size=\"14\" aria-hidden=\"true\" />\n <label class=\"dt-select dt-import-keysel\" :class=\"{ 'is-missing': keyCol === null }\">\n <select\n :value=\"keyCol ?? ''\"\n :aria-label=\"i18n.t('import.excelColumn')\"\n @change=\"\n keyCol =\n ($event.target as HTMLSelectElement).value === ''\n ? null\n : Number(($event.target as HTMLSelectElement).value)\n \"\n >\n <option value=\"\">{{ i18n.t('import.excelColumn') }}</option>\n <option v-for=\"(h, i) in headers\" :key=\"i\" :value=\"i\" :disabled=\"!h\">{{ h }}</option>\n </select>\n </label>\n <span class=\"dt-import-spacer\" />\n <label class=\"dt-select dt-import-headerrow\">\n <span class=\"dt-import-match-label\">{{ i18n.t('import.headerRow') }}</span>\n <select :value=\"headerRow\" @change=\"onHeaderRow(Number(($event.target as HTMLSelectElement).value))\">\n <option v-for=\"n in headerOptions\" :key=\"n\" :value=\"n - 1\">\n {{ i18n.t('import.headerRowN', { n }) }}\n </option>\n </select>\n </label>\n </div>\n <p v-if=\"keyCol === null\" class=\"dt-import-warn\">\n <PhWarningCircle :size=\"14\" aria-hidden=\"true\" />\n {{ i18n.t('import.keyRequired', { key: keyHeader }) }}\n </p>\n <table class=\"dt-import-table\">\n <colgroup>\n <col class=\"dt-import-col-excel\" />\n <col class=\"dt-import-col-arrow\" />\n <col class=\"dt-import-col-field\" />\n <col />\n </colgroup>\n <thead>\n <tr>\n <th>{{ i18n.t('import.excelColumn') }}</th>\n <th />\n <th>{{ i18n.t('import.field') }}</th>\n <th>{{ i18n.t('import.firstValue') }}</th>\n </tr>\n </thead>\n <tbody>\n <tr\n v-for=\"(h, i) in headers\"\n :key=\"i\"\n :class=\"{ 'is-skipped': i !== keyCol && (mapping[i] ?? '') === SKIP }\"\n >\n <td class=\"dt-import-col\" :title=\"h\">{{ h }}</td>\n <td><PhArrowRight :size=\"14\" aria-hidden=\"true\" /></td>\n <td>\n <template v-if=\"i === keyCol\">\n <span class=\"dt-mono\">{{ keyHeader }}</span>\n <span class=\"dt-import-muted\">{{ i18n.t('import.matchKey') }}</span>\n </template>\n <label v-else class=\"dt-select dt-import-field\">\n <select\n :value=\"mapping[i] ?? ''\"\n :aria-label=\"i18n.t('import.field')\"\n @change=\"mapping = { ...mapping, [i]: ($event.target as HTMLSelectElement).value }\"\n >\n <option value=\"\" disabled>{{ i18n.t('import.chooseField') }}</option>\n <option :value=\"SKIP\">{{ i18n.t('import.skip') }}</option>\n <option v-for=\"f in fields\" :key=\"f.id\" :value=\"f.id\" :disabled=\"!f.editable\">\n {{ f.def.header }}{{ f.editable ? '' : ` · ${i18n.t('sheet.readOnly.badge')}` }}\n </option>\n </select>\n </label>\n </td>\n <td class=\"dt-import-preview\">\n <template v-if=\"i === keyCol\">\n <span class=\"dt-mono\">{{ preview(i).raw }}</span>\n </template>\n <template v-else-if=\"preview(i).shown\">\n <span class=\"dt-import-muted\">{{ preview(i).raw }}</span>\n <PhArrowRight :size=\"12\" aria-hidden=\"true\" />\n <strong>{{ preview(i).shown }}</strong>\n </template>\n <span v-else :class=\"{ 'dt-import-muted': !mapping[i] || mapping[i] === SKIP }\">\n {{ preview(i).raw }}\n </span>\n </td>\n </tr>\n </tbody>\n </table>\n <div v-if=\"summary && keyCol !== null\" class=\"dt-import-summary\">\n <div class=\"dt-import-summary-line\">\n <PhInfo :size=\"16\" aria-hidden=\"true\" />\n <span>\n {{\n i18n.t('import.summary', {\n updates: summary.updates,\n news: summary.news.length,\n key: keyHeader,\n })\n }}\n </span>\n <button\n v-if=\"summary.news.length\"\n type=\"button\"\n class=\"dt-link dt-import-link\"\n @click=\"showNew = !showNew\"\n >\n {{ i18n.t('import.seeNew', { key: keyHeader }) }}\n </button>\n </div>\n <div v-if=\"showNew\" class=\"dt-import-newlist dt-mono\">{{ summary.news.join(', ') }}</div>\n <label v-if=\"summary.news.length\" class=\"dt-check-row\">\n <input v-model=\"addNew\" type=\"checkbox\" class=\"dt-checkbox\" />\n {{ i18n.t('import.addNew', { count: summary.news.length, key: keyHeader }) }}\n </label>\n <p v-if=\"overLimit\" class=\"dt-import-warn\">\n <PhWarningCircle :size=\"14\" aria-hidden=\"true\" />\n {{ i18n.t('sheet.limitFile', { count: rowCount + summary.news.length, max: maxRows }) }}\n </p>\n </div>\n </template>\n <p v-if=\"failed && !workbook\" class=\"dt-import-error\" role=\"alert\">\n {{ i18n.t('import.failed') }}\n <template v-if=\"failReason\">· {{ failReason }}</template>\n </p>\n </div>\n <div class=\"dt-import-foot\">\n <DialogClose class=\"dt-btn\">{{ i18n.t('common.cancel') }}</DialogClose>\n <button type=\"button\" class=\"dt-btn dt-btn-primary\" :disabled=\"!canApply\" @click=\"apply\">\n {{ i18n.t('import.apply') }}\n </button>\n </div>\n </DialogContent>\n </DialogPortal>\n </DialogRoot>\n</template>\n","// Yerleşik dosya okuyucu (07 §13, D46): `parseFile` verilmezse kullanılır. .xlsx `read-excel-file` ile (peer, ilk\n// kullanımda yüklenir), .csv paketin ayrıştırıcısıyla (`;` veya `,`, tırnaklı). Eski ikili .xls okunmaz.\nimport type { I18n } from '../../core/i18n'\nimport type { ParsedWorkbook } from '../../types/sheet'\nimport { parseTsv } from '../clipboard'\n\n/** Kütüphane tarihi UTC duvar saatiyle verir; yerel güne çevrilir (cellText yerel gün okur). */\nconst local = (d: Date) =>\n new Date(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate(), d.getUTCHours(), d.getUTCMinutes(), d.getUTCSeconds())\n\nexport async function readWorkbook(file: File, i18n: I18n): Promise<ParsedWorkbook> {\n if (/\\.csv$/i.test(file.name)) {\n const text = (await file.text()).replace(/^\\uFEFF/, '')\n const first = text.slice(0, text.search(/\\r?\\n|$/))\n const sep = first.split(';').length > first.split(',').length ? ';' : ','\n return { sheets: [{ name: file.name.replace(/\\.csv$/i, ''), rows: parseTsv(text, sep) }] }\n }\n if (!/\\.xlsx$/i.test(file.name)) throw new Error(i18n.t('import.xlsxOnly'))\n const { default: readXlsxFile } = await import('read-excel-file/browser')\n const sheets = await readXlsxFile(file)\n return {\n sheets: sheets.map((s) => ({\n name: s.sheet,\n rows: s.data.map((r) => r.map((v) => (v instanceof Date ? local(v) : v))),\n })),\n }\n}\n","<script setup lang=\"ts\">\n// \"Save with errors\" dialog'u (07 §14, handoff 06 §10, T12-01): hatalı satırlar gönderilmez; Fix first (ilk odak)\n// Errors görünümüne geçip ilk hataya gider, \"Save N rows\" kalanını teslim eder. `alertdialog`, 480 px.\nimport { PhWarningCircle } from '@phosphor-icons/vue'\nimport {\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogOverlay,\n AlertDialogPortal,\n AlertDialogRoot,\n AlertDialogTitle,\n} from 'reka-ui'\nimport { useDataTableContext } from '../core/plugin'\n\nexport interface ErrorRowItem {\n rowNo: number\n key: string\n message: string\n}\ndefineProps<{\n /** Hatalı satırlar (gutter sırasıyla). */\n errors: ErrorRowItem[]\n /** Gönderilecek satır sayısı. */\n okRows: number\n}>()\nconst emit = defineEmits<{ fix: []; save: [] }>()\nconst open = defineModel<boolean>('open', { default: false })\nconst { i18n } = useDataTableContext()\nconst save = () => {\n emit('save')\n open.value = false\n}\n</script>\n\n<template>\n <AlertDialogRoot v-model:open=\"open\">\n <AlertDialogPortal>\n <AlertDialogOverlay class=\"dt-scrim\" />\n <AlertDialogContent class=\"dt-dialog dt-dialog-errors\">\n <AlertDialogTitle class=\"dt-dialog-title\">\n {{ i18n.t('sheet.errDialog.title', { count: errors.length }) }}\n </AlertDialogTitle>\n <AlertDialogDescription class=\"dt-dialog-body\">\n {{ i18n.t('sheet.errDialog.body', { count: okRows }) }}\n </AlertDialogDescription>\n <ul class=\"dt-error-list\">\n <li v-for=\"e in errors.slice(0, 8)\" :key=\"e.rowNo\" class=\"dt-error-row\">\n <PhWarningCircle :size=\"14\" aria-hidden=\"true\" />\n <span class=\"dt-error-no\">{{ e.rowNo }}</span>\n <span class=\"dt-mono\">{{ e.key }}</span>\n <span class=\"dt-error-msg\">{{ e.message }}</span>\n </li>\n </ul>\n <div class=\"dt-dialog-actions\">\n <AlertDialogCancel class=\"dt-btn\" @click=\"emit('fix')\">{{ i18n.t('sheet.errDialog.fix') }}</AlertDialogCancel>\n <button type=\"button\" class=\"dt-btn dt-btn-primary\" :disabled=\"!okRows\" @click=\"save\">\n {{ i18n.t('sheet.errDialog.save', { count: okRows }) }}\n </button>\n </div>\n </AlertDialogContent>\n </AlertDialogPortal>\n </AlertDialogRoot>\n</template>\n","<script setup lang=\"ts\">\n// \"Save with errors\" dialog'u (07 §14, handoff 06 §10, T12-01): hatalı satırlar gönderilmez; Fix first (ilk odak)\n// Errors görünümüne geçip ilk hataya gider, \"Save N rows\" kalanını teslim eder. `alertdialog`, 480 px.\nimport { PhWarningCircle } from '@phosphor-icons/vue'\nimport {\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogOverlay,\n AlertDialogPortal,\n AlertDialogRoot,\n AlertDialogTitle,\n} from 'reka-ui'\nimport { useDataTableContext } from '../core/plugin'\n\nexport interface ErrorRowItem {\n rowNo: number\n key: string\n message: string\n}\ndefineProps<{\n /** Hatalı satırlar (gutter sırasıyla). */\n errors: ErrorRowItem[]\n /** Gönderilecek satır sayısı. */\n okRows: number\n}>()\nconst emit = defineEmits<{ fix: []; save: [] }>()\nconst open = defineModel<boolean>('open', { default: false })\nconst { i18n } = useDataTableContext()\nconst save = () => {\n emit('save')\n open.value = false\n}\n</script>\n\n<template>\n <AlertDialogRoot v-model:open=\"open\">\n <AlertDialogPortal>\n <AlertDialogOverlay class=\"dt-scrim\" />\n <AlertDialogContent class=\"dt-dialog dt-dialog-errors\">\n <AlertDialogTitle class=\"dt-dialog-title\">\n {{ i18n.t('sheet.errDialog.title', { count: errors.length }) }}\n </AlertDialogTitle>\n <AlertDialogDescription class=\"dt-dialog-body\">\n {{ i18n.t('sheet.errDialog.body', { count: okRows }) }}\n </AlertDialogDescription>\n <ul class=\"dt-error-list\">\n <li v-for=\"e in errors.slice(0, 8)\" :key=\"e.rowNo\" class=\"dt-error-row\">\n <PhWarningCircle :size=\"14\" aria-hidden=\"true\" />\n <span class=\"dt-error-no\">{{ e.rowNo }}</span>\n <span class=\"dt-mono\">{{ e.key }}</span>\n <span class=\"dt-error-msg\">{{ e.message }}</span>\n </li>\n </ul>\n <div class=\"dt-dialog-actions\">\n <AlertDialogCancel class=\"dt-btn\" @click=\"emit('fix')\">{{ i18n.t('sheet.errDialog.fix') }}</AlertDialogCancel>\n <button type=\"button\" class=\"dt-btn dt-btn-primary\" :disabled=\"!okRows\" @click=\"save\">\n {{ i18n.t('sheet.errDialog.save', { count: okRows }) }}\n </button>\n </div>\n </AlertDialogContent>\n </AlertDialogPortal>\n </AlertDialogRoot>\n</template>\n","<script setup lang=\"ts\">\n// Hücre menüsü (07 §9, T11-03, 236 px): sağ tıklanan noktada (reka ContextMenu; kök ızgara tetikleyici). Cut · Copy ·\n// Paste · Fill down · Clear · ─ · Insert row above / below · Remove from list (⌘−, nötr, D12) · ─ · Open {entity}\n// (yalnızca sunucuda var olan satırlar, yeni sekmede). Kısayollar mono.\nimport { ContextMenuContent, ContextMenuItem, ContextMenuPortal, ContextMenuSeparator } from 'reka-ui'\nimport { FILL_KBD, REMOVE_KBD, mac } from '../core/interaction/kbd'\nimport { useDataTableContext } from '../core/plugin'\nimport type { Plural } from '../types/core'\nimport type { SheetApi } from './useSheetEditing'\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyRow = any\ndefineProps<{\n sheet: SheetApi<AnyRow>\n entity: Plural\n href?: string\n /** Kaydederken ve salt okunurken yazan öğeler pasif. */\n readOnly: boolean\n}>()\nconst { i18n } = useDataTableContext()\nconst K = { cut: mac ? '⌘X' : 'Ctrl+X', copy: mac ? '⌘C' : 'Ctrl+C', paste: mac ? '⌘V' : 'Ctrl+V', clear: 'Del' }\n</script>\n\n<template>\n <ContextMenuPortal>\n <ContextMenuContent class=\"dt-menu dt-sheet-menu\">\n <ContextMenuItem class=\"dt-menu-item\" :disabled=\"readOnly\" @select=\"sheet.copyToClipboard(true)\">\n {{ i18n.t('sheet.menu.cut') }}\n <kbd class=\"dt-kbd\">{{ K.cut }}</kbd>\n </ContextMenuItem>\n <ContextMenuItem class=\"dt-menu-item\" @select=\"sheet.copyToClipboard(false)\">\n {{ i18n.t('sheet.menu.copy') }}\n <kbd class=\"dt-kbd\">{{ K.copy }}</kbd>\n </ContextMenuItem>\n <ContextMenuItem class=\"dt-menu-item\" :disabled=\"readOnly\" @select=\"sheet.pasteFromClipboard()\">\n {{ i18n.t('sheet.menu.paste') }}\n <kbd class=\"dt-kbd\">{{ K.paste }}</kbd>\n </ContextMenuItem>\n <ContextMenuItem class=\"dt-menu-item\" :disabled=\"readOnly\" @select=\"sheet.fillDown()\">\n {{ i18n.t('sheet.menu.fillDown') }}\n <kbd class=\"dt-kbd\">{{ FILL_KBD }}</kbd>\n </ContextMenuItem>\n <ContextMenuItem class=\"dt-menu-item\" :disabled=\"readOnly\" @select=\"sheet.clearCells()\">\n {{ i18n.t('sheet.menu.clear') }}\n <kbd class=\"dt-kbd\">{{ K.clear }}</kbd>\n </ContextMenuItem>\n <ContextMenuSeparator class=\"dt-menu-sep\" />\n <ContextMenuItem class=\"dt-menu-item\" :disabled=\"readOnly\" @select=\"sheet.insertRow('above')\">\n {{ i18n.t('sheet.menu.insertAbove') }}\n </ContextMenuItem>\n <ContextMenuItem class=\"dt-menu-item\" :disabled=\"readOnly\" @select=\"sheet.insertRow('below')\">\n {{ i18n.t('sheet.menu.insertBelow') }}\n </ContextMenuItem>\n <ContextMenuItem class=\"dt-menu-item\" :disabled=\"readOnly\" @select=\"sheet.removeSelectedRows()\">\n {{ i18n.t('sheet.menu.remove') }}\n <kbd class=\"dt-kbd\">{{ REMOVE_KBD }}</kbd>\n </ContextMenuItem>\n <template v-if=\"href\">\n <ContextMenuSeparator class=\"dt-menu-sep\" />\n <ContextMenuItem as-child class=\"dt-menu-item\">\n <a :href=\"href\" target=\"_blank\" rel=\"noopener\">{{ i18n.t('sheet.menu.open', { entity }) }}</a>\n </ContextMenuItem>\n </template>\n </ContextMenuContent>\n </ContextMenuPortal>\n</template>\n","<script setup lang=\"ts\">\n// Hücre menüsü (07 §9, T11-03, 236 px): sağ tıklanan noktada (reka ContextMenu; kök ızgara tetikleyici). Cut · Copy ·\n// Paste · Fill down · Clear · ─ · Insert row above / below · Remove from list (⌘−, nötr, D12) · ─ · Open {entity}\n// (yalnızca sunucuda var olan satırlar, yeni sekmede). Kısayollar mono.\nimport { ContextMenuContent, ContextMenuItem, ContextMenuPortal, ContextMenuSeparator } from 'reka-ui'\nimport { FILL_KBD, REMOVE_KBD, mac } from '../core/interaction/kbd'\nimport { useDataTableContext } from '../core/plugin'\nimport type { Plural } from '../types/core'\nimport type { SheetApi } from './useSheetEditing'\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyRow = any\ndefineProps<{\n sheet: SheetApi<AnyRow>\n entity: Plural\n href?: string\n /** Kaydederken ve salt okunurken yazan öğeler pasif. */\n readOnly: boolean\n}>()\nconst { i18n } = useDataTableContext()\nconst K = { cut: mac ? '⌘X' : 'Ctrl+X', copy: mac ? '⌘C' : 'Ctrl+C', paste: mac ? '⌘V' : 'Ctrl+V', clear: 'Del' }\n</script>\n\n<template>\n <ContextMenuPortal>\n <ContextMenuContent class=\"dt-menu dt-sheet-menu\">\n <ContextMenuItem class=\"dt-menu-item\" :disabled=\"readOnly\" @select=\"sheet.copyToClipboard(true)\">\n {{ i18n.t('sheet.menu.cut') }}\n <kbd class=\"dt-kbd\">{{ K.cut }}</kbd>\n </ContextMenuItem>\n <ContextMenuItem class=\"dt-menu-item\" @select=\"sheet.copyToClipboard(false)\">\n {{ i18n.t('sheet.menu.copy') }}\n <kbd class=\"dt-kbd\">{{ K.copy }}</kbd>\n </ContextMenuItem>\n <ContextMenuItem class=\"dt-menu-item\" :disabled=\"readOnly\" @select=\"sheet.pasteFromClipboard()\">\n {{ i18n.t('sheet.menu.paste') }}\n <kbd class=\"dt-kbd\">{{ K.paste }}</kbd>\n </ContextMenuItem>\n <ContextMenuItem class=\"dt-menu-item\" :disabled=\"readOnly\" @select=\"sheet.fillDown()\">\n {{ i18n.t('sheet.menu.fillDown') }}\n <kbd class=\"dt-kbd\">{{ FILL_KBD }}</kbd>\n </ContextMenuItem>\n <ContextMenuItem class=\"dt-menu-item\" :disabled=\"readOnly\" @select=\"sheet.clearCells()\">\n {{ i18n.t('sheet.menu.clear') }}\n <kbd class=\"dt-kbd\">{{ K.clear }}</kbd>\n </ContextMenuItem>\n <ContextMenuSeparator class=\"dt-menu-sep\" />\n <ContextMenuItem class=\"dt-menu-item\" :disabled=\"readOnly\" @select=\"sheet.insertRow('above')\">\n {{ i18n.t('sheet.menu.insertAbove') }}\n </ContextMenuItem>\n <ContextMenuItem class=\"dt-menu-item\" :disabled=\"readOnly\" @select=\"sheet.insertRow('below')\">\n {{ i18n.t('sheet.menu.insertBelow') }}\n </ContextMenuItem>\n <ContextMenuItem class=\"dt-menu-item\" :disabled=\"readOnly\" @select=\"sheet.removeSelectedRows()\">\n {{ i18n.t('sheet.menu.remove') }}\n <kbd class=\"dt-kbd\">{{ REMOVE_KBD }}</kbd>\n </ContextMenuItem>\n <template v-if=\"href\">\n <ContextMenuSeparator class=\"dt-menu-sep\" />\n <ContextMenuItem as-child class=\"dt-menu-item\">\n <a :href=\"href\" target=\"_blank\" rel=\"noopener\">{{ i18n.t('sheet.menu.open', { entity }) }}</a>\n </ContextMenuItem>\n </template>\n </ContextMenuContent>\n </ContextMenuPortal>\n</template>\n","// Sheet satırı + hücreler (07 §3–4, handoff 06 §5): render fonksiyonu (sanal listede yüzlerce örnek). Gutter (56 px,\n// satır no + işaret), hücre durumları (editable / read-only / active / in selection / editing / changed / error / warning /\n// required / new / fill target / match), editör hücrenin yerinde. Satırın taslak ve hata Map'leri prop'tur: yalnızca\n// değişen satır yeniden çizilir.\nimport { PhLock, PhPlus, PhWarningCircle } from '@phosphor-icons/vue'\nimport { defineComponent, h, type Component, type PropType, type VNodeChild } from 'vue'\nimport { formatCell, isEmptyValue } from '../core/cells/format'\nimport { cellFillStyle, renderCellContent, type RenderEnv } from '../core/cells/renderCell'\nimport { alignOf, isNumericType } from '../core/cells/specs'\nimport type { LayoutColumn } from '../core/columns/useColumnLayout'\nimport { withFill } from '../core/grid/Row'\nimport type { ColumnDef } from '../types/columns'\nimport { inputText } from './parse'\nimport type { Issue } from './useSheetStore'\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- satır tipi DataSheet'te; accessor parametreleri karşıt değişken\ntype AnyRow = any\n\n/** Bu satırdaki seçili sütun dizini aralığı ve dış kenarlar (aralık > 1 hücre olduğunda). */\nexport interface RowSelection {\n from: number\n to: number\n top: boolean\n bottom: boolean\n}\n/** Doldurma hedefi: sütun dizini aralığı; `last` son hedef satır (alt kenar). */\nexport interface RowFill {\n from: number\n to: number\n last: boolean\n}\nexport interface CellEditing {\n columnId: string\n value: unknown\n /** false: formül çubuğundan düzenleniyor; hücre editör açmaz, taslağı gösterir. */\n inCell: boolean\n}\n\n/** Sheet'te hücre içinde link yok (07 §9: \"Open product\" hücre menüsünde); `id`/`ajax` tipinin `href`'i çizimde düşer. */\nconst plainDefs = new WeakMap<ColumnDef<AnyRow>, ColumnDef<AnyRow>>()\nconst plain = (def: ColumnDef<AnyRow>): ColumnDef<AnyRow> => {\n if (!def.href) return def\n let p = plainDefs.get(def)\n if (!p) plainDefs.set(def, (p = { ...def, href: undefined }))\n return p\n}\n\nexport default defineComponent({\n name: 'DtSheetRow',\n props: {\n row: { type: Object as PropType<object>, required: true },\n index: { type: Number, required: true },\n /** Kararlı satır numarası (yükleme sırası, 07 §3). */\n rowNo: { type: Number, required: true },\n columns: { type: Array as PropType<Array<LayoutColumn<AnyRow>>>, required: true },\n env: { type: Object as PropType<RenderEnv>, required: true },\n keyColumn: { type: String, required: true },\n read: { type: Function as PropType<(row: AnyRow, def: ColumnDef<AnyRow>) => unknown>, required: true },\n original: { type: Function as PropType<(row: AnyRow, def: ColumnDef<AnyRow>) => unknown>, required: true },\n canEdit: { type: Function as PropType<(row: AnyRow, def: ColumnDef<AnyRow>) => boolean>, required: true },\n /** Satırın taslak hali: editör (`optionEnabled`) `editable` ve doğrulayıcılarla aynı güncel satırı görür. */\n current: { type: Function as PropType<(row: AnyRow) => AnyRow>, required: true },\n editorFor: { type: Function as PropType<(def: ColumnDef<AnyRow>) => Component | null>, required: true },\n draft: { type: Map as PropType<Map<string, unknown>>, default: undefined },\n issues: { type: Map as PropType<Map<string, Issue>>, default: undefined },\n /** Eklenen satır (07 §9): gutter'da `+`. */\n isNew: { type: Boolean, default: false },\n /** Sunucu satır hatası (07 §14): anahtar hücresinde ve gutter ipucunda. */\n rowError: { type: String as PropType<string | undefined>, default: undefined },\n /** Aktif hücrenin sütun id'si (roving tabindex 0). */\n active: { type: String as PropType<string | null>, default: null },\n selection: { type: Object as PropType<RowSelection | null>, default: null },\n /** Fill handle'ın çizildiği hücre (tek hücrede aktif, aralıkta sağ alt köşe). */\n handleAt: { type: String as PropType<string | null>, default: null },\n fill: { type: Object as PropType<RowFill | null>, default: null },\n /** Find in grid eşleşen sütunlar. */\n found: { type: Set as PropType<Set<string>>, default: undefined },\n editing: { type: Object as PropType<CellEditing | null>, default: null },\n /** Hata balonu ilk satırda hücrenin altında (üstte header'ın altında kalırdı). */\n tipBelow: { type: Boolean, default: false },\n /** Telefonda gutter yok (07 §17). */\n gutter: { type: Boolean, default: true },\n /** Hata balonu id'leri için örnek öneki (`aria-describedby`, 08 §5). */\n uid: { type: String, default: 'dt' },\n style: { type: Object as PropType<Record<string, string>>, default: undefined },\n },\n emits: ['edit-value', 'use-suggestion'],\n setup(props, { emit }) {\n const t = (key: string, params?: Record<string, string | number>) => props.env.i18n.t(key, params)\n\n const renderCell = (col: LayoutColumn<AnyRow>, i: number): VNodeChild => {\n const def = col.def\n const id = col.id\n const value = props.read(props.row, def)\n const editable = props.canEdit(props.row, def)\n const issue = props.issues?.get(id)\n const changed = props.draft?.has(id) ?? false\n const isActive = props.active === id\n const sel = props.selection\n const inSel = !!sel && i >= sel.from && i <= sel.to\n const fill = props.fill\n const inFill = !!fill && i >= fill.from && i <= fill.to\n const ed = props.editing?.columnId === id ? props.editing : null\n const isKey = id === props.keyColumn\n\n let content: VNodeChild\n if (ed?.inCell) {\n const Editor = props.editorFor(def)!\n content = h(Editor, {\n modelValue: ed.value,\n row: props.current(props.row),\n column: def,\n 'onUpdate:modelValue': (v: unknown) => emit('edit-value', v),\n })\n } else if (ed) content = h('span', { class: 'dt-cell-content' }, inputText(def, ed.value))\n else if (issue?.level === 'error' && isEmptyValue(value) && issue.message === t('sheet.required'))\n content = h('span', { class: 'dt-cell-content dt-cell-required' }, issue.message)\n else\n content = h('span', { class: 'dt-cell-content' }, [renderCellContent(plain(def), props.row, value, props.env)])\n\n const children: VNodeChild[] = [content]\n if (isKey && props.rowError && !ed)\n children.push(h('span', { class: 'dt-cell-tip is-error', role: 'tooltip' }, props.rowError))\n if (!editable && !isKey)\n children.push(\n h(PhLock, { size: 12, class: 'dt-cell-lock', role: 'img', 'aria-label': t('sheet.readOnly.badge') }),\n )\n const tipId = issue ? `${props.uid}-${props.rowNo}-${i}` : undefined\n if (issue)\n children.push(\n h('span', { id: tipId, class: ['dt-cell-tip', `is-${issue.level}`], role: 'tooltip' }, [\n issue.message,\n issue.suggest\n ? h(\n 'button',\n {\n type: 'button',\n class: 'dt-cell-tip-btn',\n tabindex: -1,\n onClick: () => emit('use-suggestion', def, issue.suggest!.value),\n },\n t('sheet.useOption', { option: issue.suggest.label }),\n )\n : null,\n ]),\n )\n if (props.handleAt === id && !ed) children.push(h('span', { class: 'dt-fill-handle', 'aria-hidden': 'true' }))\n\n return h(\n 'div',\n {\n class: [\n 'dt-cell',\n `is-${alignOf(def)}`,\n {\n 'is-numeric': isNumericType(def.type),\n 'is-key': isKey,\n 'is-new': isKey && props.isNew,\n 'is-readonly': !editable,\n 'is-active': isActive,\n 'is-selected': inSel,\n 'is-edge-l': inSel && i === sel!.from,\n 'is-edge-r': inSel && i === sel!.to,\n 'is-edge-t': inSel && sel!.top,\n 'is-edge-b': inSel && sel!.bottom,\n 'is-fill': inFill,\n 'is-fill-end': inFill && fill!.last,\n 'is-match': props.found?.has(id) ?? false,\n 'is-editing': !!ed,\n 'is-changed': changed,\n 'is-error': issue?.level === 'error' || (isKey && !!props.rowError),\n 'is-warning': issue?.level === 'warning',\n 'is-tip-below': props.tipBelow,\n 'is-pinned-start': col.pinned === 'start',\n 'is-pinned-end': col.pinned === 'end',\n 'is-pin-edge': col.pinEdge,\n },\n ],\n style: {\n ...(col.pinned === 'start'\n ? { left: `var(${col.offsetVar})` }\n : col.pinned === 'end'\n ? { right: `var(${col.offsetVar})` }\n : null),\n ...cellFillStyle(def, value),\n },\n role: 'gridcell',\n tabindex: isActive ? 0 : -1,\n 'aria-readonly': editable ? undefined : 'true',\n 'aria-selected': inSel ? 'true' : undefined,\n 'aria-describedby': tipId,\n 'aria-invalid': issue?.level === 'error' ? 'true' : undefined,\n 'data-col': id,\n // Öncelik Error > Warning > Changed (07 §4): hata/uyarı balonu varken \"Was …\" ipucu yok; yeni satırda orijinal yok.\n 'data-dt-tip':\n changed && !issue && !ed && !props.isNew\n ? t('sheet.was', { value: formatCell(def, props.row, props.original(props.row, def), props.env) })\n : undefined,\n },\n children,\n )\n }\n\n const gutter = () => {\n let hasError = !!props.rowError\n for (const i of props.issues?.values() ?? []) if (i.level === 'error') hasError = true\n const changed = !!props.draft?.size\n return h(\n 'div',\n {\n class: ['dt-cell', 'dt-gutter', 'is-pinned-start'],\n style: { left: '0px' },\n role: 'rowheader',\n 'data-dt-tip': props.rowError,\n },\n [\n hasError\n ? h(PhWarningCircle, {\n size: 13,\n class: 'dt-mark is-error',\n role: 'img',\n 'aria-label': t('sheet.hasErrors'),\n })\n : props.isNew\n ? h(PhPlus, { size: 13, class: 'dt-mark is-new', role: 'img', 'aria-label': t('sheet.addedRow') })\n : changed\n ? h('span', { class: 'dt-mark is-changed', role: 'img', 'aria-label': t('sheet.changed') })\n : null,\n h('span', { class: 'dt-gutter-no' }, String(props.rowNo)),\n ],\n )\n }\n\n return () => {\n const index = new Map(props.columns.map((c, i) => [c.id, i]))\n return h(\n 'div',\n {\n class: ['dt-row', { 'is-active-row': props.active !== null }],\n role: 'row',\n 'aria-rowindex': props.index + 2,\n 'data-index': props.index,\n style: props.style,\n },\n [props.gutter ? gutter() : null, ...withFill(props.columns, (col) => renderCell(col, index.get(col.id)!))],\n )\n }\n },\n})\n","<script setup lang=\"ts\">\n// Sheet ızgarası (07 §2–10, 08 §2 sheet, handoff 06 §5): tek kayan alan, sticky header (yerel sıralama oku), gutter\n// (56 px) + sola sabit sütunlar, sanal satırlar (aktif satır DOM'da kalır); hücre odaklı klavye (roving tabindex = aktif\n// hücre), fare ile hücre / aralık seçimi (TanStack handler'ları, gutter = satır, kenarda otomatik kaydırma), fill handle\n// sürükleme, pano olayları, hücre menüsü (sağ tık / ⇧F10), düzenleme başlatma ve onaylama kuralları. Veri, seçim ve\n// düzenleme durumu `sheet` nesnesinden (DataSheet kurar); bu dosya yalnızca DOM, odak ve kaydırmayı yönetir.\nimport { PhArrowUp, PhLock } from '@phosphor-icons/vue'\nimport { useVirtualizer } from '@tanstack/vue-virtual'\nimport { ContextMenuRoot, ContextMenuTrigger } from 'reka-ui'\nimport { computed, nextTick, onBeforeUnmount, onMounted, ref, shallowRef, useId, watch, watchEffect } from 'vue'\nimport { RemoteLabels } from '../core/cells/remoteLabels'\nimport type { RenderEnv } from '../core/cells/renderCell'\nimport { alignOf, isNumericType } from '../core/cells/specs'\nimport type { ColumnLayoutApi, LayoutColumn } from '../core/columns/useColumnLayout'\nimport { getFormat } from '../core/format'\nimport SkeletonRow from '../core/grid/SkeletonRow'\nimport { INTERACTIVE_SELECTOR, isInteractive, isTextInput } from '../core/interaction/isInteractive'\nimport { useDataTableContext } from '../core/plugin'\nimport type { ColumnDef } from '../types/columns'\nimport type { Density, Plural } from '../types/core'\nimport SheetMenu from './SheetMenu.vue'\nimport SheetRow, { type CellEditing, type RowFill, type RowSelection } from './SheetRow'\nimport type { SheetApi } from './useSheetEditing'\nimport type { Direction } from './useSheetTable'\n\n// İç bileşen: satır tipi DataSheet'te tiplidir.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyRow = any\nconst GUTTER_FULL = 56\n/** Sürüklerken bu kadar yakınken kenar kaydırır (px / kare). */\nconst EDGE = 24\nconst SCROLL_STEP = 12\n\nconst props = withDefaults(\n defineProps<{\n sheet: SheetApi<AnyRow>\n layout: ColumnLayoutApi<AnyRow>\n rows: AnyRow[]\n density?: Density\n /** role=grid aria-label. */\n label: string\n /** aria-busy. */\n loading?: boolean\n /** Açılış: 24 iskelet satır (07 §15). */\n skeleton?: boolean\n verticalLines?: boolean\n keyColumn: string\n /** Find in grid eşleşmeleri: satır anahtarı → sütunlar. */\n found?: Map<string, Set<string>> | null\n /** Kaydederken (07 §14): aria-readonly; kaydırma, Find ve seçim serbest. */\n readOnly?: boolean\n /** Yerel sıralama (07 §10): sütun → yön ve öncelik. */\n sort?: ReadonlyMap<string, { dir: 'asc' | 'desc'; index: number | null }>\n entity: Plural\n /** Telefon (D14, 07 §17): gutter ve işaret yok, seçim aralığı ve fill handle yok; dokunma hücreyi odaklar. */\n phone?: boolean\n }>(),\n {\n density: 'compact',\n loading: false,\n skeleton: false,\n verticalLines: true,\n found: null,\n readOnly: false,\n phone: false,\n },\n)\ndefineSlots<{ state?: () => unknown }>()\n\nconst ctx = useDataTableContext()\nconst uid = useId()\nconst root = ref<HTMLElement | null>(null)\nconst scrollEl = ref<HTMLElement | null>(null)\nconst layout = props.layout\nconst sheet = props.sheet\nconst table = sheet.table\nconst store = sheet.store\nconst keyOf = store.keyOf\n\nconst coarse = typeof matchMedia === 'function' && matchMedia('(pointer: coarse)').matches\nconst density = computed<Density>(() => (coarse && props.density === 'compact' ? 'standard' : props.density))\n\nconst GUTTER_W = computed(() => (props.phone ? 0 : GUTTER_FULL))\n// Gutter track'i başa eklenir; sola sabit sütunların ofseti o kadar kayar (GridRoot ile aynı yöntem).\nwatchEffect(\n () => {\n const el = root.value\n if (!el) return\n const g = GUTTER_W.value\n el.style.setProperty('--cols', `${g ? `${g}px ` : ''}${layout.colsVar.value}`)\n el.style.setProperty('--dt-min-w', `${layout.minWidth.value + g}px`)\n const startVars = new Set(layout.start.value.map((c) => c.offsetVar))\n for (const [name, value] of Object.entries(layout.offsetVars.value))\n el.style.setProperty(name, startVars.has(name) ? `${parseFloat(value) + g}px` : value)\n },\n { flush: 'sync' },\n)\n\nconst rowHeight = ref(32)\n// Sticky header akış içinde: sanal öğeler header kadar aşağıda başlar (TanStack `scrollMargin`), header görünür alanın üstünü\n// (`scrollPaddingStart`), yatay kaydırma çubuğu altını (`scrollPaddingEnd`) örter. Yoksa ↓ ile inen satır tam bir header\n// yüksekliği kadar kabın altında kalır (08 §2).\nconst headH = ref(32)\nconst barH = ref(0)\nconst readBarH = () => {\n const el = scrollEl.value\n barH.value = el ? Math.max(0, el.offsetHeight - el.clientHeight) : 0\n}\nconst readRowHeight = () => {\n const v = root.value ? parseFloat(getComputedStyle(root.value).getPropertyValue('--dt-row-h')) : NaN\n rowHeight.value = Number.isFinite(v) ? v : 32\n headH.value = root.value?.querySelector<HTMLElement>('.dt-head')?.offsetHeight ?? headH.value\n readBarH()\n}\nonMounted(readRowHeight)\nwatch(density, () => requestAnimationFrame(readRowHeight))\n\nconst labels = new RemoteLabels()\nconst env = computed<RenderEnv>(() => ({\n fmt: getFormat(ctx.locale),\n i18n: ctx.i18n,\n today: new Date(),\n labels,\n density: density.value,\n coarse,\n}))\nconst columns = computed(() => layout.columns.value)\nconst defById = computed(() => new Map(columns.value.map((c) => [c.id, c.def])))\nconst indexByKey = computed(() => {\n const m = new Map<string, number>()\n props.rows.forEach((r, i) => m.set(keyOf(r), i))\n return m\n})\nconst active = table.active\nconst activeIndex = computed(() => (active.value ? (indexByKey.value.get(active.value.rowId) ?? -1) : -1))\n// Aralık görünümü yalnızca birden çok hücrede (tek hücre = aktif çerçeve, 07 §4).\nconst multi = computed(() => {\n const b = table.bounds.value\n return !!b && (b.maxRowIndex > b.minRowIndex || b.maxColumnIndex > b.minColumnIndex)\n})\nconst selectionFor = (i: number): RowSelection | null => {\n const b = table.bounds.value\n if (!b || !multi.value || i < b.minRowIndex || i > b.maxRowIndex) return null\n return { from: b.minColumnIndex, to: b.maxColumnIndex, top: i === b.minRowIndex, bottom: i === b.maxRowIndex }\n}\n/** Fill handle: tek hücrede aktif hücre, aralıkta sağ alt köşe. */\nconst handleFor = (i: number): string | null => {\n const b = table.bounds.value\n if (!b || fillDrag.value || props.phone) return null\n if (!multi.value) return i === activeIndex.value ? (active.value?.columnId ?? null) : null\n return i === b.maxRowIndex ? (columns.value[b.maxColumnIndex]?.id ?? null) : null\n}\nconst editingFor = (i: number): CellEditing | null => {\n const e = sheet.edit.editing.value\n const row = props.rows[i]\n return e && row && keyOf(e.row) === keyOf(row)\n ? { columnId: e.def.id as string, value: e.value, inCell: e.inCell }\n : null\n}\nconst foundFor = (i: number) => {\n const row = props.rows[i]\n return row ? props.found?.get(keyOf(row)) : undefined\n}\n\nconst count = computed(() => (props.skeleton ? 24 : props.rows.length))\nconst virtualizer = useVirtualizer(\n computed(() => ({\n count: count.value,\n getScrollElement: () => scrollEl.value,\n estimateSize: () => rowHeight.value + 1,\n scrollMargin: headH.value,\n scrollPaddingStart: headH.value,\n scrollPaddingEnd: barH.value,\n overscan: 10,\n getItemKey: (i: number) => (props.skeleton ? `sk-${i}` : keyOf(props.rows[i]!)),\n // Aktif satır her zaman DOM'da (08 §2): kaydırma odağı kaybettirmez.\n rangeExtractor: (range: { startIndex: number; endIndex: number; overscan: number; count: number }) => {\n const start = Math.max(0, range.startIndex - range.overscan)\n const end = Math.min(range.count - 1, range.endIndex + range.overscan)\n const out: number[] = []\n const a = props.skeleton ? -1 : activeIndex.value\n if (a >= 0 && a < start) out.push(a)\n for (let i = start; i <= end; i++) out.push(i)\n if (a > end && a < range.count) out.push(a)\n return out\n },\n })),\n)\nconst virtualRows = computed(() => virtualizer.value.getVirtualItems())\nconst totalSize = computed(() => virtualizer.value.getTotalSize())\nwatch(rowHeight, () => virtualizer.value.measure())\n\nconst scrolledStart = shallowRef(false)\nconst onScroll = () => {\n readBarH()\n scrolledStart.value = (scrollEl.value?.scrollLeft ?? 0) > 0\n}\n\n/** Hücre elemanı (id'de nokta olabilir: dataset karşılaştırması). */\nconst cellEl = (i: number, columnId: string): HTMLElement | null => {\n const row = root.value?.querySelector<HTMLElement>(`.dt-row[data-index=\"${i}\"]`)\n if (!row) return null\n for (const c of row.querySelectorAll<HTMLElement>('.dt-cell[data-col]')) if (c.dataset.col === columnId) return c\n return null\n}\nconst pinnedWidth = (): number => {\n let w = 0\n for (const c of root.value?.querySelectorAll<HTMLElement>('.dt-head .is-pinned-start') ?? []) w += c.offsetWidth\n return w\n}\n/** Yatayda görünüre getir: sola sabit sütunların altında kalmasın. */\nconst revealX = (el: HTMLElement) => {\n const sc = scrollEl.value\n if (!sc || el.classList.contains('is-pinned-start')) return\n const r = el.getBoundingClientRect()\n const s = sc.getBoundingClientRect()\n const left = s.left + pinnedWidth()\n if (r.left < left) sc.scrollLeft -= left - r.left\n else if (r.right > s.right) sc.scrollLeft += r.right - s.right\n}\n/** ⇧+ok: seçimin hareket eden ucu görünür alana gelir; odak aktif hücrede (anchor) kalır, o satır zaten DOM'da tutulur. */\nconst revealEnd = () => {\n const end = table.rangeEnd.value\n const i = end ? indexByKey.value.get(end.rowId) : undefined\n if (!end || i === undefined) return\n virtualizer.value.scrollToIndex(i, { align: 'auto' })\n requestAnimationFrame(() => {\n const el = cellEl(i, end.columnId)\n if (el) revealX(el)\n })\n}\n/** Aktif hücreyi DOM'a getirip odaklar: önce üst bileşenin `rows` prop'u gelsin (görünüm değişimi, yeni/geri gelen satır\n * dizini kaydırır), sonra sanal listede sonraki karede DOM'a girsin. */\nconst focusActive = () => void nextTick(() => focusNow(0))\nconst focusNow = (round: number) => {\n const a = active.value\n // Hücre editörü açıksa odak ondadır (Add row → anahtar hücresi düzenlemede); çalınmaz.\n if (!a || sheet.edit.editing.value?.inCell) return\n const i = indexByKey.value.get(a.rowId)\n if (i === undefined) {\n if (round < 3) requestAnimationFrame(() => focusNow(round + 1))\n return\n }\n virtualizer.value.scrollToIndex(i, { align: 'auto' })\n const tryFocus = (attempt: number) => {\n const el = cellEl(i, a.columnId)\n if (el) {\n el.focus({ preventScroll: true })\n revealX(el)\n } else if (attempt < 3) requestAnimationFrame(() => tryFocus(attempt + 1))\n }\n tryFocus(0)\n}\n\nconst focusCell = (i: number, columnId: string) => {\n const row = props.rows[Math.max(0, Math.min(props.rows.length - 1, i))]\n if (!row) return\n table.focus(keyOf(row), columnId)\n focusActive()\n}\n/** Tab / ⇧Tab: satır sonunda sonraki satırın başına (08 §4). */\nconst step = (dir: 'left' | 'right') => {\n const a = active.value\n if (!a) return\n const cols = columns.value\n const ci = cols.findIndex((c) => c.id === a.columnId)\n const ri = activeIndex.value\n if (dir === 'right') {\n if (ci < cols.length - 1) table.move('right')\n else if (ri < props.rows.length - 1) table.focus(keyOf(props.rows[ri + 1]), cols[0]!.id)\n } else if (ci > 0) table.move('left')\n else if (ri > 0) table.focus(keyOf(props.rows[ri - 1]), cols[cols.length - 1]!.id)\n focusActive()\n}\n/** ⌘ + ok: kenara atla. */\nconst jump = (dir: Direction) => {\n const a = active.value!\n const cols = columns.value\n if (dir === 'left') table.focus(a.rowId, cols[0]!.id)\n else if (dir === 'right') table.focus(a.rowId, cols[cols.length - 1]!.id)\n else {\n const row = props.rows[dir === 'up' ? 0 : props.rows.length - 1]\n if (row) table.focus(keyOf(row), a.columnId)\n }\n}\nconst pageSize = () => Math.max(1, Math.floor((scrollEl.value?.clientHeight ?? 0) / (rowHeight.value + 1)) - 1)\nconst DIR: Record<string, Direction> = { ArrowUp: 'up', ArrowDown: 'down', ArrowLeft: 'left', ArrowRight: 'right' }\nconst mac = typeof navigator !== 'undefined' && /Mac|iPhone|iPad/.test(navigator.platform)\n\nconst onKeydown = (e: KeyboardEvent) => {\n const target = e.target as HTMLElement\n const ed = sheet.edit.editing.value\n if (ed?.inCell) {\n // Tab her zaman onaylar (listede olmayan metin olduğu gibi kalır → hata, 07 §5). Enter/Esc: açık combobox\n // (aria-expanded), kendi işini yapmış widget (defaultPrevented) ve düğmeler önce.\n if (e.key === 'Tab') {\n e.preventDefault()\n sheet.edit.commit()\n step(e.shiftKey ? 'left' : 'right')\n return\n }\n // Yerleşik multiselect: seçimler listede tik ile yapılır, Esc liste açıkken de kaydedip çıkar (07 §5).\n if (e.key === 'Escape' && ed.def.type === 'multiselect' && !ed.def.editor) {\n e.preventDefault()\n sheet.edit.commit()\n focusActive()\n return\n }\n if (e.defaultPrevented || target.getAttribute('aria-expanded') === 'true' || target.tagName === 'BUTTON') return\n if (e.key === 'Enter' && !(e.shiftKey && target.tagName === 'TEXTAREA')) {\n e.preventDefault()\n sheet.edit.commit()\n table.move('down')\n focusActive()\n } else if (e.key === 'Escape') {\n e.preventDefault()\n sheet.edit.cancel()\n focusActive()\n }\n return\n }\n const cell = target.closest<HTMLElement>('.dt-cell[data-col]')\n if (!cell) return\n if (target !== cell) {\n // Hücre içi widget: ızgara tuşları kapalı, Esc hücreye döner (08 §2).\n if (e.key === 'Escape') {\n e.preventDefault()\n cell.focus()\n }\n return\n }\n const a = active.value\n const row = props.rows[activeIndex.value]\n const def = a ? defById.value.get(a.columnId) : undefined\n if (!a || !row || !def) return\n const editable = sheet.canEdit(row, def)\n const mod = e.metaKey || e.ctrlKey\n const dir = DIR[e.key]\n if (dir) {\n e.preventDefault()\n if (e.shiftKey) {\n table.extend(dir)\n void nextTick(revealEnd)\n return\n }\n if (mod) jump(dir)\n else table.move(dir)\n focusActive()\n return\n }\n switch (e.key) {\n case 'Tab':\n e.preventDefault()\n step(e.shiftKey ? 'left' : 'right')\n return\n case 'Enter': {\n e.preventDefault()\n const widget = editable ? null : cell.querySelector<HTMLElement>(INTERACTIVE_SELECTOR)\n if (widget) widget.focus()\n else {\n table.move('down')\n focusActive()\n }\n return\n }\n case 'F2':\n e.preventDefault()\n sheet.edit.start(row, def, { inCell: true })\n return\n case 'Escape':\n e.preventDefault()\n table.focus(a.rowId, a.columnId)\n return\n case ' ':\n e.preventDefault()\n if (def.type === 'boolean' && editable) sheet.toggle(row, def)\n return\n case 'Delete':\n case 'Backspace':\n e.preventDefault()\n sheet.clearCells()\n return\n case 'Home':\n e.preventDefault()\n focusCell(mod ? 0 : activeIndex.value, columns.value[0]!.id)\n return\n case 'End':\n e.preventDefault()\n focusCell(mod ? props.rows.length - 1 : activeIndex.value, columns.value[columns.value.length - 1]!.id)\n return\n case 'PageDown':\n e.preventDefault()\n focusCell(activeIndex.value + pageSize(), a.columnId)\n return\n case 'PageUp':\n e.preventDefault()\n focusCell(activeIndex.value - pageSize(), a.columnId)\n return\n case 'F8':\n e.preventDefault()\n sheet.goToError(e.shiftKey ? -1 : 1)\n return\n case 'ContextMenu':\n case 'F10':\n if (e.key === 'F10' && !e.shiftKey) return\n e.preventDefault()\n openMenuAt(cell)\n return\n }\n if (mod) {\n // ⌘C / ⌘X / ⌘V tarayıcının copy/cut/paste olaylarıyla gelir (aşağıda); burada yalnızca kısayol tuşları.\n const k = e.key.toLowerCase()\n if (k === 'a' && !e.shiftKey) {\n e.preventDefault()\n table.selectAll()\n } else if (k === 's') {\n e.preventDefault()\n sheet.save()\n } else if (k === 'd' && !e.shiftKey) {\n e.preventDefault()\n sheet.fillDown()\n } else if (k === 'z' && !e.shiftKey) {\n e.preventDefault()\n sheet.undo()\n } else if ((k === 'z' && e.shiftKey) || (k === 'y' && !mac)) {\n e.preventDefault()\n sheet.redo()\n } else if (e.key === '-' || e.key === 'Subtract') {\n e.preventDefault()\n sheet.removeSelectedRows()\n }\n return\n }\n // Yazmaya başlamak: düzenleme açılır, içerik yazılanla değiştirilir (07 §5).\n if (e.key.length === 1 && !e.altKey && editable) {\n e.preventDefault()\n sheet.edit.start(row, def, { inCell: true, replace: e.key })\n }\n}\n\n/** Pano (07 §7): odak hücredeyken (editör ya da widget input'u değilken). */\nconst clipboard = (e: ClipboardEvent, action: 'copy' | 'cut' | 'paste') => {\n if (sheet.edit.editing.value?.inCell || isTextInput(e.target as Element)) return\n if (!(e.target as HTMLElement).closest('.dt-cell[data-col]')) return\n if (sheet[action](e.clipboardData)) e.preventDefault()\n}\n\ninterface Hit {\n index: number\n row: AnyRow\n columnId: string\n cell: HTMLElement\n target: HTMLElement\n}\nconst hitAt = (target: HTMLElement | null): Hit | null => {\n const cell = target?.closest<HTMLElement>('.dt-cell[data-col]')\n const rowEl = target?.closest<HTMLElement>('.dt-row[data-index]')\n if (!cell || !rowEl || props.skeleton) return null\n const index = Number(rowEl.dataset.index)\n const row = props.rows[index]\n return row ? { index, row, columnId: cell.dataset.col!, cell, target: target! } : null\n}\nconst hit = (e: Event): Hit | null => hitAt(e.target as HTMLElement)\n\n// Sürükleme (seçim ya da doldurma): kenara yaklaşınca otomatik kayar, kayan içerikte imlecin altındaki hücre izlenir.\nconst dragging = shallowRef<'select' | 'fill' | null>(null)\nconst fillDrag = shallowRef<{ fromRow: number; toRow: number; cols: [number, number]; target: number } | null>(null)\nconst fillLabel = shallowRef<{ left: number; top: number; text: string } | null>(null)\nlet pointer = { x: 0, y: 0 }\nlet scrollRaf = 0\nconst extendTo = (h: Hit | null) => {\n if (!h) return\n if (dragging.value === 'fill') {\n const f = fillDrag.value!\n const target = h.index > f.toRow ? h.index : h.index < f.fromRow ? h.index : f.toRow\n if (target !== f.target) {\n fillDrag.value = { ...f, target }\n updateFillLabel()\n }\n } else table.extendHandler(keyOf(h.row), h.columnId)?.(new MouseEvent('mouseover'))\n}\nconst autoScroll = () => {\n scrollRaf = 0\n const sc = scrollEl.value\n if (!dragging.value || !sc) return\n const r = sc.getBoundingClientRect()\n let dy = 0\n if (pointer.y < r.top + EDGE) dy = -SCROLL_STEP\n else if (pointer.y > r.bottom - EDGE) dy = SCROLL_STEP\n let dx = 0\n if (dragging.value === 'select') {\n if (pointer.x < r.left + pinnedWidth() + EDGE) dx = -SCROLL_STEP\n else if (pointer.x > r.right - EDGE) dx = SCROLL_STEP\n }\n if (dy || dx) {\n sc.scrollTop += dy\n sc.scrollLeft += dx\n extendTo(hitAt(document.elementFromPoint(pointer.x, pointer.y) as HTMLElement | null))\n scrollRaf = requestAnimationFrame(autoScroll)\n }\n}\nconst onMousemove = (e: MouseEvent) => {\n if (!dragging.value) return\n pointer = { x: e.clientX, y: e.clientY }\n if (dragging.value === 'fill') extendTo(hit(e))\n if (!scrollRaf) scrollRaf = requestAnimationFrame(autoScroll)\n}\nconst updateFillLabel = () => {\n const f = fillDrag.value\n if (!f || f.target === f.toRow) {\n fillLabel.value = null\n return\n }\n const last = f.target > f.toRow ? f.target : f.target\n const el = cellEl(last, columns.value[f.cols[1]]!.id)\n const rootRect = root.value?.getBoundingClientRect()\n if (!el || !rootRect) {\n fillLabel.value = null\n return\n }\n const r = el.getBoundingClientRect()\n fillLabel.value = {\n left: r.right - rootRect.left + 10,\n top: r.bottom - rootRect.top - 13,\n text: sheet.fillLabel(f.fromRow, f.toRow, f.cols, f.target),\n }\n}\nconst onDocMouseup = () => {\n if (dragging.value === 'fill' && fillDrag.value) {\n const f = fillDrag.value\n if (f.target !== f.toRow) sheet.fill(f.fromRow, f.toRow, f.cols, f.target)\n fillDrag.value = null\n fillLabel.value = null\n focusActive()\n }\n dragging.value = null\n cancelAnimationFrame(scrollRaf)\n scrollRaf = 0\n}\nonMounted(() => document.addEventListener('mouseup', onDocMouseup))\nonBeforeUnmount(() => {\n document.removeEventListener('mouseup', onDocMouseup)\n cancelAnimationFrame(scrollRaf)\n})\n\nlet rowAnchor = -1\nconst onMousedown = (e: MouseEvent) => {\n if (e.button !== 0) return\n const target = e.target as HTMLElement\n // Fill handle (07 §8): 4 px dışarı taştığı için alt satırın hücresi hedef olabilir; dikdörtgenle tespit.\n const handle = root.value?.querySelector<HTMLElement>('.dt-fill-handle')\n const hr = handle?.getBoundingClientRect()\n if (\n hr &&\n e.clientX >= hr.left - 2 &&\n e.clientX <= hr.right + 2 &&\n e.clientY >= hr.top - 2 &&\n e.clientY <= hr.bottom + 2\n ) {\n const b = table.bounds.value\n if (!b) return\n e.preventDefault()\n sheet.edit.commit()\n fillDrag.value = {\n fromRow: b.minRowIndex,\n toRow: b.maxRowIndex,\n cols: [b.minColumnIndex, b.maxColumnIndex],\n target: b.maxRowIndex,\n }\n dragging.value = 'fill'\n pointer = { x: e.clientX, y: e.clientY }\n return\n }\n const rowEl = target.closest<HTMLElement>('.dt-row[data-index]')\n if (target.closest('.dt-gutter') && rowEl && !props.skeleton) {\n // Gutter: satırın tamamı, ⇧ ile satır aralığı (07 §6).\n e.preventDefault()\n const i = Number(rowEl.dataset.index)\n const cols = columns.value\n const from = e.shiftKey && rowAnchor >= 0 ? rowAnchor : i\n rowAnchor = from\n sheet.edit.commit()\n table.selectRange({\n anchorRowId: keyOf(props.rows[from]),\n anchorColumnId: cols[0]!.id,\n focusRowId: keyOf(props.rows[i]),\n focusColumnId: cols[cols.length - 1]!.id,\n })\n focusActive()\n return\n }\n const h = hit(e)\n if (!h) return\n rowAnchor = -1\n const ed = sheet.edit.editing.value\n if (ed?.inCell && h.cell.classList.contains('is-editing')) return\n // Başka hücreye mousedown onaylar (07 §5); hücredeki düğme hücreyi aktif yapar ama düzenlemez.\n sheet.edit.commit()\n if (props.phone) {\n // Telefon: dokunma yalnızca hücreyi odaklar (kaydırma serbest, aralık yok).\n table.focus(keyOf(h.row), h.columnId)\n return\n }\n if (!isInteractive(h.target, h.cell)) e.preventDefault()\n table.startHandler(keyOf(h.row), h.columnId)?.(e)\n dragging.value = 'select'\n pointer = { x: e.clientX, y: e.clientY }\n h.cell.focus({ preventScroll: true })\n}\nconst onMouseover = (e: MouseEvent) => {\n if (dragging.value === 'fill') return\n const h = hit(e)\n if (h) table.extendHandler(keyOf(h.row), h.columnId)?.(e)\n}\nconst onDblclick = (e: MouseEvent) => {\n const h = hit(e)\n if (!h || isInteractive(h.target, h.cell)) return\n const def = defById.value.get(h.columnId)\n if (!def) return\n // boolean: düzenleme modu yok (07 §5); çift tık Space gibi Yes ↔ No çevirir.\n if (def.type === 'boolean' && !def.editor) {\n if (sheet.canEdit(h.row, def)) sheet.toggle(h.row, def)\n return\n }\n sheet.edit.start(h.row, def, { inCell: true })\n}\nconst fillFor = (i: number): RowFill | null => {\n const f = fillDrag.value\n if (!f || f.target === f.toRow) return null\n const down = f.target > f.toRow\n const inRange = down ? i > f.toRow && i <= f.target : i < f.fromRow && i >= f.target\n if (!inRange) return null\n return { from: f.cols[0], to: f.cols[1], last: down ? i === f.target : i === f.fromRow - 1 }\n}\n\n/** Sağ tık (07 §9): hedef hücre seçimin dışındaysa aktif olur; hücre dışı (header, boş alan) için menü açılmaz. */\nconst onContextmenuCapture = (e: MouseEvent) => {\n const h = hit(e)\n if (!h || props.skeleton) {\n e.stopPropagation()\n return\n }\n const b = table.bounds.value\n const ci = columns.value.findIndex((c) => c.id === h.columnId)\n const inside =\n !!b && h.index >= b.minRowIndex && h.index <= b.maxRowIndex && ci >= b.minColumnIndex && ci <= b.maxColumnIndex\n if (!inside) {\n sheet.edit.commit()\n table.focus(keyOf(h.row), h.columnId)\n h.cell.focus({ preventScroll: true })\n }\n}\n/** ⇧F10 / Menü tuşu: menü hücrenin köşesinde (reka tetikleyicisi contextmenu olayından konum alır). */\nconst openMenuAt = (cell: HTMLElement) => {\n const r = cell.getBoundingClientRect()\n cell.dispatchEvent(\n new MouseEvent('contextmenu', { bubbles: true, cancelable: true, clientX: r.left + 8, clientY: r.bottom - 4 }),\n )\n}\nconst menuHref = computed(() => {\n const row = props.rows[activeIndex.value]\n return row ? sheet.openHref(row) : undefined\n})\nconst sortOf = (id: string) => props.sort?.get(id)\n\nconst unitOf = (def: ColumnDef<AnyRow>) => (typeof def.unit === 'string' ? def.unit : undefined)\n// D33: anahtar sütunda anahtar metni, açıklama varsa altına ikinci satır; aksi halde ad + açıklama.\nconst headTip = (col: { id: string; def: ColumnDef<AnyRow> }) => {\n const key = col.id === props.keyColumn ? ctx.i18n.t('sheet.keyTooltip', { key: col.def.header }) : undefined\n return col.def.description ? `${key ?? col.def.header}\\n${col.def.description}` : key\n}\nconst resize = (col: LayoutColumn<AnyRow>, e: MouseEvent | TouchEvent) => {\n const cell = (e.currentTarget as HTMLElement).parentElement!\n layout.setWidth(col.id, cell.getBoundingClientRect().width)\n col.header.getResizeHandler()(e)\n}\nconst requiredLabel = ctx.i18n.t('sheet.required').toLocaleLowerCase(ctx.locale)\n\ndefineExpose({ focusActive, scrollToIndex: (i: number) => virtualizer.value.scrollToIndex(i) })\n</script>\n\n<template>\n <ContextMenuRoot>\n <ContextMenuTrigger as-child>\n <div\n ref=\"root\"\n class=\"dt-grid dt-sheet-grid\"\n :class=\"{\n 'is-scrolled-start': scrolledStart,\n 'is-skeleton': skeleton,\n 'has-vlines': verticalLines,\n 'is-filling': dragging === 'fill',\n 'is-phone': phone,\n }\"\n role=\"grid\"\n :aria-label=\"label\"\n :aria-rowcount=\"skeleton ? -1 : rows.length\"\n :aria-colcount=\"columns.length + (phone ? 0 : 1)\"\n :aria-busy=\"loading || readOnly ? 'true' : undefined\"\n :aria-readonly=\"readOnly ? 'true' : undefined\"\n :data-density=\"density\"\n @keydown=\"onKeydown\"\n @mousedown=\"onMousedown\"\n @mousemove=\"onMousemove\"\n @mouseover=\"onMouseover\"\n @dblclick=\"onDblclick\"\n @contextmenu.capture=\"onContextmenuCapture\"\n @copy=\"clipboard($event, 'copy')\"\n @cut=\"clipboard($event, 'cut')\"\n @paste=\"clipboard($event, 'paste')\"\n >\n <div ref=\"scrollEl\" class=\"dt-scroll\" @scroll.passive=\"onScroll\">\n <div class=\"dt-head\" role=\"row\" aria-rowindex=\"1\">\n <div v-if=\"!phone\" class=\"dt-head-cell dt-gutter is-pinned-start\" style=\"left: 0px\" role=\"columnheader\">\n {{ ctx.i18n.t('sheet.err.row') }}\n </div>\n <div\n v-for=\"col in columns\"\n :key=\"col.id\"\n class=\"dt-head-cell\"\n :class=\"[\n `is-${alignOf(col.def)}`,\n {\n 'is-numeric': isNumericType(col.def.type),\n 'is-key': col.id === keyColumn,\n 'is-pinned-start': col.pinned === 'start',\n 'is-pin-edge': col.pinEdge,\n 'is-resizing': layout.resizing.value?.id === col.id,\n },\n ]\"\n :style=\"col.pinned === 'start' ? { left: `var(${col.offsetVar})` } : undefined\"\n role=\"columnheader\"\n :aria-sort=\"\n sortOf(col.id)?.dir === 'asc' ? 'ascending' : sortOf(col.id)?.dir === 'desc' ? 'descending' : undefined\n \"\n :data-col=\"col.id\"\n >\n <PhLock v-if=\"col.id === keyColumn\" :size=\"12\" class=\"dt-head-lock\" aria-hidden=\"true\" />\n <button\n type=\"button\"\n class=\"dt-head-label\"\n tabindex=\"-1\"\n :data-dt-tip=\"headTip(col)\"\n :aria-describedby=\"col.def.description ? `${uid}-desc-${col.id}` : undefined\"\n @click=\"sheet.sort(col.id, $event.shiftKey)\"\n >\n <span class=\"dt-head-text\">{{ col.def.header }}</span>\n <span v-if=\"col.def.required\" class=\"dt-head-required\" :aria-label=\"requiredLabel\">*</span>\n <span v-if=\"unitOf(col.def)\" class=\"dt-head-unit\">{{ unitOf(col.def) }}</span>\n <span v-if=\"sortOf(col.id)\" class=\"dt-head-sort\" aria-hidden=\"true\">\n <PhArrowUp :size=\"12\" :class=\"{ 'is-desc': sortOf(col.id)!.dir === 'desc' }\" />\n <span v-if=\"sortOf(col.id)!.index\" class=\"dt-head-sort-index\">{{ sortOf(col.id)!.index }}</span>\n </span>\n </button>\n <span v-if=\"col.def.description\" :id=\"`${uid}-desc-${col.id}`\" class=\"dt-sr-only\">\n {{ col.def.description }}\n </span>\n <span class=\"dt-head-sep\" aria-hidden=\"true\" />\n <span\n class=\"dt-resize\"\n aria-hidden=\"true\"\n @mousedown=\"resize(col, $event)\"\n @touchstart.passive=\"resize(col, $event)\"\n >\n <span v-if=\"layout.resizing.value?.id === col.id\" class=\"dt-resize-badge\">\n {{ Math.round(layout.resizing.value!.size) }} px\n </span>\n </span>\n </div>\n <div class=\"dt-head-cell dt-cell-fill\" role=\"presentation\" aria-hidden=\"true\" />\n </div>\n <div class=\"dt-body\" role=\"presentation\" :style=\"{ height: `${totalSize}px` }\">\n <div\n v-for=\"item in virtualRows\"\n :key=\"String(item.key)\"\n class=\"dt-item\"\n :data-index=\"item.index\"\n :style=\"{ transform: `translateY(${item.start - headH}px)` }\"\n >\n <SkeletonRow v-if=\"skeleton\" :index=\"item.index\" :columns=\"columns\" :gutter=\"!phone\" />\n <SheetRow\n v-else\n :row=\"rows[item.index]!\"\n :index=\"item.index\"\n :row-no=\"store.rowNoOf(keyOf(rows[item.index]))\"\n :gutter=\"!phone\"\n :uid=\"uid\"\n :columns=\"columns\"\n :env=\"env\"\n :key-column=\"keyColumn\"\n :read=\"store.read\"\n :original=\"store.original\"\n :can-edit=\"sheet.canEdit\"\n :current=\"store.current\"\n :editor-for=\"sheet.editorFor\"\n :draft=\"store.rowDraft(keyOf(rows[item.index]))\"\n :issues=\"store.rowIssues(keyOf(rows[item.index]))\"\n :is-new=\"store.isNew(keyOf(rows[item.index]))\"\n :row-error=\"store.rowError(keyOf(rows[item.index]))\"\n :active=\"activeIndex === item.index ? active!.columnId : null\"\n :selection=\"selectionFor(item.index)\"\n :handle-at=\"handleFor(item.index)\"\n :fill=\"fillFor(item.index)\"\n :found=\"foundFor(item.index)\"\n :editing=\"editingFor(item.index)\"\n :tip-below=\"item.index === 0\"\n @edit-value=\"(v) => sheet.edit.setValue(v)\"\n @use-suggestion=\"(def, v) => sheet.useSuggestion(rows[item.index], def, v)\"\n />\n </div>\n </div>\n </div>\n <div\n v-if=\"fillLabel\"\n class=\"dt-fill-label\"\n role=\"status\"\n :style=\"{ left: `${fillLabel.left}px`, top: `${fillLabel.top}px` }\"\n >\n {{ fillLabel.text }}\n </div>\n <div v-if=\"$slots.state && !skeleton && rows.length === 0\" class=\"dt-body-state\"><slot name=\"state\" /></div>\n <SheetMenu :sheet=\"sheet\" :entity=\"entity\" :href=\"menuHref\" :read-only=\"readOnly || loading\" />\n </div>\n </ContextMenuTrigger>\n </ContextMenuRoot>\n</template>\n","<script setup lang=\"ts\">\n// Sheet ızgarası (07 §2–10, 08 §2 sheet, handoff 06 §5): tek kayan alan, sticky header (yerel sıralama oku), gutter\n// (56 px) + sola sabit sütunlar, sanal satırlar (aktif satır DOM'da kalır); hücre odaklı klavye (roving tabindex = aktif\n// hücre), fare ile hücre / aralık seçimi (TanStack handler'ları, gutter = satır, kenarda otomatik kaydırma), fill handle\n// sürükleme, pano olayları, hücre menüsü (sağ tık / ⇧F10), düzenleme başlatma ve onaylama kuralları. Veri, seçim ve\n// düzenleme durumu `sheet` nesnesinden (DataSheet kurar); bu dosya yalnızca DOM, odak ve kaydırmayı yönetir.\nimport { PhArrowUp, PhLock } from '@phosphor-icons/vue'\nimport { useVirtualizer } from '@tanstack/vue-virtual'\nimport { ContextMenuRoot, ContextMenuTrigger } from 'reka-ui'\nimport { computed, nextTick, onBeforeUnmount, onMounted, ref, shallowRef, useId, watch, watchEffect } from 'vue'\nimport { RemoteLabels } from '../core/cells/remoteLabels'\nimport type { RenderEnv } from '../core/cells/renderCell'\nimport { alignOf, isNumericType } from '../core/cells/specs'\nimport type { ColumnLayoutApi, LayoutColumn } from '../core/columns/useColumnLayout'\nimport { getFormat } from '../core/format'\nimport SkeletonRow from '../core/grid/SkeletonRow'\nimport { INTERACTIVE_SELECTOR, isInteractive, isTextInput } from '../core/interaction/isInteractive'\nimport { useDataTableContext } from '../core/plugin'\nimport type { ColumnDef } from '../types/columns'\nimport type { Density, Plural } from '../types/core'\nimport SheetMenu from './SheetMenu.vue'\nimport SheetRow, { type CellEditing, type RowFill, type RowSelection } from './SheetRow'\nimport type { SheetApi } from './useSheetEditing'\nimport type { Direction } from './useSheetTable'\n\n// İç bileşen: satır tipi DataSheet'te tiplidir.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyRow = any\nconst GUTTER_FULL = 56\n/** Sürüklerken bu kadar yakınken kenar kaydırır (px / kare). */\nconst EDGE = 24\nconst SCROLL_STEP = 12\n\nconst props = withDefaults(\n defineProps<{\n sheet: SheetApi<AnyRow>\n layout: ColumnLayoutApi<AnyRow>\n rows: AnyRow[]\n density?: Density\n /** role=grid aria-label. */\n label: string\n /** aria-busy. */\n loading?: boolean\n /** Açılış: 24 iskelet satır (07 §15). */\n skeleton?: boolean\n verticalLines?: boolean\n keyColumn: string\n /** Find in grid eşleşmeleri: satır anahtarı → sütunlar. */\n found?: Map<string, Set<string>> | null\n /** Kaydederken (07 §14): aria-readonly; kaydırma, Find ve seçim serbest. */\n readOnly?: boolean\n /** Yerel sıralama (07 §10): sütun → yön ve öncelik. */\n sort?: ReadonlyMap<string, { dir: 'asc' | 'desc'; index: number | null }>\n entity: Plural\n /** Telefon (D14, 07 §17): gutter ve işaret yok, seçim aralığı ve fill handle yok; dokunma hücreyi odaklar. */\n phone?: boolean\n }>(),\n {\n density: 'compact',\n loading: false,\n skeleton: false,\n verticalLines: true,\n found: null,\n readOnly: false,\n phone: false,\n },\n)\ndefineSlots<{ state?: () => unknown }>()\n\nconst ctx = useDataTableContext()\nconst uid = useId()\nconst root = ref<HTMLElement | null>(null)\nconst scrollEl = ref<HTMLElement | null>(null)\nconst layout = props.layout\nconst sheet = props.sheet\nconst table = sheet.table\nconst store = sheet.store\nconst keyOf = store.keyOf\n\nconst coarse = typeof matchMedia === 'function' && matchMedia('(pointer: coarse)').matches\nconst density = computed<Density>(() => (coarse && props.density === 'compact' ? 'standard' : props.density))\n\nconst GUTTER_W = computed(() => (props.phone ? 0 : GUTTER_FULL))\n// Gutter track'i başa eklenir; sola sabit sütunların ofseti o kadar kayar (GridRoot ile aynı yöntem).\nwatchEffect(\n () => {\n const el = root.value\n if (!el) return\n const g = GUTTER_W.value\n el.style.setProperty('--cols', `${g ? `${g}px ` : ''}${layout.colsVar.value}`)\n el.style.setProperty('--dt-min-w', `${layout.minWidth.value + g}px`)\n const startVars = new Set(layout.start.value.map((c) => c.offsetVar))\n for (const [name, value] of Object.entries(layout.offsetVars.value))\n el.style.setProperty(name, startVars.has(name) ? `${parseFloat(value) + g}px` : value)\n },\n { flush: 'sync' },\n)\n\nconst rowHeight = ref(32)\n// Sticky header akış içinde: sanal öğeler header kadar aşağıda başlar (TanStack `scrollMargin`), header görünür alanın üstünü\n// (`scrollPaddingStart`), yatay kaydırma çubuğu altını (`scrollPaddingEnd`) örter. Yoksa ↓ ile inen satır tam bir header\n// yüksekliği kadar kabın altında kalır (08 §2).\nconst headH = ref(32)\nconst barH = ref(0)\nconst readBarH = () => {\n const el = scrollEl.value\n barH.value = el ? Math.max(0, el.offsetHeight - el.clientHeight) : 0\n}\nconst readRowHeight = () => {\n const v = root.value ? parseFloat(getComputedStyle(root.value).getPropertyValue('--dt-row-h')) : NaN\n rowHeight.value = Number.isFinite(v) ? v : 32\n headH.value = root.value?.querySelector<HTMLElement>('.dt-head')?.offsetHeight ?? headH.value\n readBarH()\n}\nonMounted(readRowHeight)\nwatch(density, () => requestAnimationFrame(readRowHeight))\n\nconst labels = new RemoteLabels()\nconst env = computed<RenderEnv>(() => ({\n fmt: getFormat(ctx.locale),\n i18n: ctx.i18n,\n today: new Date(),\n labels,\n density: density.value,\n coarse,\n}))\nconst columns = computed(() => layout.columns.value)\nconst defById = computed(() => new Map(columns.value.map((c) => [c.id, c.def])))\nconst indexByKey = computed(() => {\n const m = new Map<string, number>()\n props.rows.forEach((r, i) => m.set(keyOf(r), i))\n return m\n})\nconst active = table.active\nconst activeIndex = computed(() => (active.value ? (indexByKey.value.get(active.value.rowId) ?? -1) : -1))\n// Aralık görünümü yalnızca birden çok hücrede (tek hücre = aktif çerçeve, 07 §4).\nconst multi = computed(() => {\n const b = table.bounds.value\n return !!b && (b.maxRowIndex > b.minRowIndex || b.maxColumnIndex > b.minColumnIndex)\n})\nconst selectionFor = (i: number): RowSelection | null => {\n const b = table.bounds.value\n if (!b || !multi.value || i < b.minRowIndex || i > b.maxRowIndex) return null\n return { from: b.minColumnIndex, to: b.maxColumnIndex, top: i === b.minRowIndex, bottom: i === b.maxRowIndex }\n}\n/** Fill handle: tek hücrede aktif hücre, aralıkta sağ alt köşe. */\nconst handleFor = (i: number): string | null => {\n const b = table.bounds.value\n if (!b || fillDrag.value || props.phone) return null\n if (!multi.value) return i === activeIndex.value ? (active.value?.columnId ?? null) : null\n return i === b.maxRowIndex ? (columns.value[b.maxColumnIndex]?.id ?? null) : null\n}\nconst editingFor = (i: number): CellEditing | null => {\n const e = sheet.edit.editing.value\n const row = props.rows[i]\n return e && row && keyOf(e.row) === keyOf(row)\n ? { columnId: e.def.id as string, value: e.value, inCell: e.inCell }\n : null\n}\nconst foundFor = (i: number) => {\n const row = props.rows[i]\n return row ? props.found?.get(keyOf(row)) : undefined\n}\n\nconst count = computed(() => (props.skeleton ? 24 : props.rows.length))\nconst virtualizer = useVirtualizer(\n computed(() => ({\n count: count.value,\n getScrollElement: () => scrollEl.value,\n estimateSize: () => rowHeight.value + 1,\n scrollMargin: headH.value,\n scrollPaddingStart: headH.value,\n scrollPaddingEnd: barH.value,\n overscan: 10,\n getItemKey: (i: number) => (props.skeleton ? `sk-${i}` : keyOf(props.rows[i]!)),\n // Aktif satır her zaman DOM'da (08 §2): kaydırma odağı kaybettirmez.\n rangeExtractor: (range: { startIndex: number; endIndex: number; overscan: number; count: number }) => {\n const start = Math.max(0, range.startIndex - range.overscan)\n const end = Math.min(range.count - 1, range.endIndex + range.overscan)\n const out: number[] = []\n const a = props.skeleton ? -1 : activeIndex.value\n if (a >= 0 && a < start) out.push(a)\n for (let i = start; i <= end; i++) out.push(i)\n if (a > end && a < range.count) out.push(a)\n return out\n },\n })),\n)\nconst virtualRows = computed(() => virtualizer.value.getVirtualItems())\nconst totalSize = computed(() => virtualizer.value.getTotalSize())\nwatch(rowHeight, () => virtualizer.value.measure())\n\nconst scrolledStart = shallowRef(false)\nconst onScroll = () => {\n readBarH()\n scrolledStart.value = (scrollEl.value?.scrollLeft ?? 0) > 0\n}\n\n/** Hücre elemanı (id'de nokta olabilir: dataset karşılaştırması). */\nconst cellEl = (i: number, columnId: string): HTMLElement | null => {\n const row = root.value?.querySelector<HTMLElement>(`.dt-row[data-index=\"${i}\"]`)\n if (!row) return null\n for (const c of row.querySelectorAll<HTMLElement>('.dt-cell[data-col]')) if (c.dataset.col === columnId) return c\n return null\n}\nconst pinnedWidth = (): number => {\n let w = 0\n for (const c of root.value?.querySelectorAll<HTMLElement>('.dt-head .is-pinned-start') ?? []) w += c.offsetWidth\n return w\n}\n/** Yatayda görünüre getir: sola sabit sütunların altında kalmasın. */\nconst revealX = (el: HTMLElement) => {\n const sc = scrollEl.value\n if (!sc || el.classList.contains('is-pinned-start')) return\n const r = el.getBoundingClientRect()\n const s = sc.getBoundingClientRect()\n const left = s.left + pinnedWidth()\n if (r.left < left) sc.scrollLeft -= left - r.left\n else if (r.right > s.right) sc.scrollLeft += r.right - s.right\n}\n/** ⇧+ok: seçimin hareket eden ucu görünür alana gelir; odak aktif hücrede (anchor) kalır, o satır zaten DOM'da tutulur. */\nconst revealEnd = () => {\n const end = table.rangeEnd.value\n const i = end ? indexByKey.value.get(end.rowId) : undefined\n if (!end || i === undefined) return\n virtualizer.value.scrollToIndex(i, { align: 'auto' })\n requestAnimationFrame(() => {\n const el = cellEl(i, end.columnId)\n if (el) revealX(el)\n })\n}\n/** Aktif hücreyi DOM'a getirip odaklar: önce üst bileşenin `rows` prop'u gelsin (görünüm değişimi, yeni/geri gelen satır\n * dizini kaydırır), sonra sanal listede sonraki karede DOM'a girsin. */\nconst focusActive = () => void nextTick(() => focusNow(0))\nconst focusNow = (round: number) => {\n const a = active.value\n // Hücre editörü açıksa odak ondadır (Add row → anahtar hücresi düzenlemede); çalınmaz.\n if (!a || sheet.edit.editing.value?.inCell) return\n const i = indexByKey.value.get(a.rowId)\n if (i === undefined) {\n if (round < 3) requestAnimationFrame(() => focusNow(round + 1))\n return\n }\n virtualizer.value.scrollToIndex(i, { align: 'auto' })\n const tryFocus = (attempt: number) => {\n const el = cellEl(i, a.columnId)\n if (el) {\n el.focus({ preventScroll: true })\n revealX(el)\n } else if (attempt < 3) requestAnimationFrame(() => tryFocus(attempt + 1))\n }\n tryFocus(0)\n}\n\nconst focusCell = (i: number, columnId: string) => {\n const row = props.rows[Math.max(0, Math.min(props.rows.length - 1, i))]\n if (!row) return\n table.focus(keyOf(row), columnId)\n focusActive()\n}\n/** Tab / ⇧Tab: satır sonunda sonraki satırın başına (08 §4). */\nconst step = (dir: 'left' | 'right') => {\n const a = active.value\n if (!a) return\n const cols = columns.value\n const ci = cols.findIndex((c) => c.id === a.columnId)\n const ri = activeIndex.value\n if (dir === 'right') {\n if (ci < cols.length - 1) table.move('right')\n else if (ri < props.rows.length - 1) table.focus(keyOf(props.rows[ri + 1]), cols[0]!.id)\n } else if (ci > 0) table.move('left')\n else if (ri > 0) table.focus(keyOf(props.rows[ri - 1]), cols[cols.length - 1]!.id)\n focusActive()\n}\n/** ⌘ + ok: kenara atla. */\nconst jump = (dir: Direction) => {\n const a = active.value!\n const cols = columns.value\n if (dir === 'left') table.focus(a.rowId, cols[0]!.id)\n else if (dir === 'right') table.focus(a.rowId, cols[cols.length - 1]!.id)\n else {\n const row = props.rows[dir === 'up' ? 0 : props.rows.length - 1]\n if (row) table.focus(keyOf(row), a.columnId)\n }\n}\nconst pageSize = () => Math.max(1, Math.floor((scrollEl.value?.clientHeight ?? 0) / (rowHeight.value + 1)) - 1)\nconst DIR: Record<string, Direction> = { ArrowUp: 'up', ArrowDown: 'down', ArrowLeft: 'left', ArrowRight: 'right' }\nconst mac = typeof navigator !== 'undefined' && /Mac|iPhone|iPad/.test(navigator.platform)\n\nconst onKeydown = (e: KeyboardEvent) => {\n const target = e.target as HTMLElement\n const ed = sheet.edit.editing.value\n if (ed?.inCell) {\n // Tab her zaman onaylar (listede olmayan metin olduğu gibi kalır → hata, 07 §5). Enter/Esc: açık combobox\n // (aria-expanded), kendi işini yapmış widget (defaultPrevented) ve düğmeler önce.\n if (e.key === 'Tab') {\n e.preventDefault()\n sheet.edit.commit()\n step(e.shiftKey ? 'left' : 'right')\n return\n }\n // Yerleşik multiselect: seçimler listede tik ile yapılır, Esc liste açıkken de kaydedip çıkar (07 §5).\n if (e.key === 'Escape' && ed.def.type === 'multiselect' && !ed.def.editor) {\n e.preventDefault()\n sheet.edit.commit()\n focusActive()\n return\n }\n if (e.defaultPrevented || target.getAttribute('aria-expanded') === 'true' || target.tagName === 'BUTTON') return\n if (e.key === 'Enter' && !(e.shiftKey && target.tagName === 'TEXTAREA')) {\n e.preventDefault()\n sheet.edit.commit()\n table.move('down')\n focusActive()\n } else if (e.key === 'Escape') {\n e.preventDefault()\n sheet.edit.cancel()\n focusActive()\n }\n return\n }\n const cell = target.closest<HTMLElement>('.dt-cell[data-col]')\n if (!cell) return\n if (target !== cell) {\n // Hücre içi widget: ızgara tuşları kapalı, Esc hücreye döner (08 §2).\n if (e.key === 'Escape') {\n e.preventDefault()\n cell.focus()\n }\n return\n }\n const a = active.value\n const row = props.rows[activeIndex.value]\n const def = a ? defById.value.get(a.columnId) : undefined\n if (!a || !row || !def) return\n const editable = sheet.canEdit(row, def)\n const mod = e.metaKey || e.ctrlKey\n const dir = DIR[e.key]\n if (dir) {\n e.preventDefault()\n if (e.shiftKey) {\n table.extend(dir)\n void nextTick(revealEnd)\n return\n }\n if (mod) jump(dir)\n else table.move(dir)\n focusActive()\n return\n }\n switch (e.key) {\n case 'Tab':\n e.preventDefault()\n step(e.shiftKey ? 'left' : 'right')\n return\n case 'Enter': {\n e.preventDefault()\n const widget = editable ? null : cell.querySelector<HTMLElement>(INTERACTIVE_SELECTOR)\n if (widget) widget.focus()\n else {\n table.move('down')\n focusActive()\n }\n return\n }\n case 'F2':\n e.preventDefault()\n sheet.edit.start(row, def, { inCell: true })\n return\n case 'Escape':\n e.preventDefault()\n table.focus(a.rowId, a.columnId)\n return\n case ' ':\n e.preventDefault()\n if (def.type === 'boolean' && editable) sheet.toggle(row, def)\n return\n case 'Delete':\n case 'Backspace':\n e.preventDefault()\n sheet.clearCells()\n return\n case 'Home':\n e.preventDefault()\n focusCell(mod ? 0 : activeIndex.value, columns.value[0]!.id)\n return\n case 'End':\n e.preventDefault()\n focusCell(mod ? props.rows.length - 1 : activeIndex.value, columns.value[columns.value.length - 1]!.id)\n return\n case 'PageDown':\n e.preventDefault()\n focusCell(activeIndex.value + pageSize(), a.columnId)\n return\n case 'PageUp':\n e.preventDefault()\n focusCell(activeIndex.value - pageSize(), a.columnId)\n return\n case 'F8':\n e.preventDefault()\n sheet.goToError(e.shiftKey ? -1 : 1)\n return\n case 'ContextMenu':\n case 'F10':\n if (e.key === 'F10' && !e.shiftKey) return\n e.preventDefault()\n openMenuAt(cell)\n return\n }\n if (mod) {\n // ⌘C / ⌘X / ⌘V tarayıcının copy/cut/paste olaylarıyla gelir (aşağıda); burada yalnızca kısayol tuşları.\n const k = e.key.toLowerCase()\n if (k === 'a' && !e.shiftKey) {\n e.preventDefault()\n table.selectAll()\n } else if (k === 's') {\n e.preventDefault()\n sheet.save()\n } else if (k === 'd' && !e.shiftKey) {\n e.preventDefault()\n sheet.fillDown()\n } else if (k === 'z' && !e.shiftKey) {\n e.preventDefault()\n sheet.undo()\n } else if ((k === 'z' && e.shiftKey) || (k === 'y' && !mac)) {\n e.preventDefault()\n sheet.redo()\n } else if (e.key === '-' || e.key === 'Subtract') {\n e.preventDefault()\n sheet.removeSelectedRows()\n }\n return\n }\n // Yazmaya başlamak: düzenleme açılır, içerik yazılanla değiştirilir (07 §5).\n if (e.key.length === 1 && !e.altKey && editable) {\n e.preventDefault()\n sheet.edit.start(row, def, { inCell: true, replace: e.key })\n }\n}\n\n/** Pano (07 §7): odak hücredeyken (editör ya da widget input'u değilken). */\nconst clipboard = (e: ClipboardEvent, action: 'copy' | 'cut' | 'paste') => {\n if (sheet.edit.editing.value?.inCell || isTextInput(e.target as Element)) return\n if (!(e.target as HTMLElement).closest('.dt-cell[data-col]')) return\n if (sheet[action](e.clipboardData)) e.preventDefault()\n}\n\ninterface Hit {\n index: number\n row: AnyRow\n columnId: string\n cell: HTMLElement\n target: HTMLElement\n}\nconst hitAt = (target: HTMLElement | null): Hit | null => {\n const cell = target?.closest<HTMLElement>('.dt-cell[data-col]')\n const rowEl = target?.closest<HTMLElement>('.dt-row[data-index]')\n if (!cell || !rowEl || props.skeleton) return null\n const index = Number(rowEl.dataset.index)\n const row = props.rows[index]\n return row ? { index, row, columnId: cell.dataset.col!, cell, target: target! } : null\n}\nconst hit = (e: Event): Hit | null => hitAt(e.target as HTMLElement)\n\n// Sürükleme (seçim ya da doldurma): kenara yaklaşınca otomatik kayar, kayan içerikte imlecin altındaki hücre izlenir.\nconst dragging = shallowRef<'select' | 'fill' | null>(null)\nconst fillDrag = shallowRef<{ fromRow: number; toRow: number; cols: [number, number]; target: number } | null>(null)\nconst fillLabel = shallowRef<{ left: number; top: number; text: string } | null>(null)\nlet pointer = { x: 0, y: 0 }\nlet scrollRaf = 0\nconst extendTo = (h: Hit | null) => {\n if (!h) return\n if (dragging.value === 'fill') {\n const f = fillDrag.value!\n const target = h.index > f.toRow ? h.index : h.index < f.fromRow ? h.index : f.toRow\n if (target !== f.target) {\n fillDrag.value = { ...f, target }\n updateFillLabel()\n }\n } else table.extendHandler(keyOf(h.row), h.columnId)?.(new MouseEvent('mouseover'))\n}\nconst autoScroll = () => {\n scrollRaf = 0\n const sc = scrollEl.value\n if (!dragging.value || !sc) return\n const r = sc.getBoundingClientRect()\n let dy = 0\n if (pointer.y < r.top + EDGE) dy = -SCROLL_STEP\n else if (pointer.y > r.bottom - EDGE) dy = SCROLL_STEP\n let dx = 0\n if (dragging.value === 'select') {\n if (pointer.x < r.left + pinnedWidth() + EDGE) dx = -SCROLL_STEP\n else if (pointer.x > r.right - EDGE) dx = SCROLL_STEP\n }\n if (dy || dx) {\n sc.scrollTop += dy\n sc.scrollLeft += dx\n extendTo(hitAt(document.elementFromPoint(pointer.x, pointer.y) as HTMLElement | null))\n scrollRaf = requestAnimationFrame(autoScroll)\n }\n}\nconst onMousemove = (e: MouseEvent) => {\n if (!dragging.value) return\n pointer = { x: e.clientX, y: e.clientY }\n if (dragging.value === 'fill') extendTo(hit(e))\n if (!scrollRaf) scrollRaf = requestAnimationFrame(autoScroll)\n}\nconst updateFillLabel = () => {\n const f = fillDrag.value\n if (!f || f.target === f.toRow) {\n fillLabel.value = null\n return\n }\n const last = f.target > f.toRow ? f.target : f.target\n const el = cellEl(last, columns.value[f.cols[1]]!.id)\n const rootRect = root.value?.getBoundingClientRect()\n if (!el || !rootRect) {\n fillLabel.value = null\n return\n }\n const r = el.getBoundingClientRect()\n fillLabel.value = {\n left: r.right - rootRect.left + 10,\n top: r.bottom - rootRect.top - 13,\n text: sheet.fillLabel(f.fromRow, f.toRow, f.cols, f.target),\n }\n}\nconst onDocMouseup = () => {\n if (dragging.value === 'fill' && fillDrag.value) {\n const f = fillDrag.value\n if (f.target !== f.toRow) sheet.fill(f.fromRow, f.toRow, f.cols, f.target)\n fillDrag.value = null\n fillLabel.value = null\n focusActive()\n }\n dragging.value = null\n cancelAnimationFrame(scrollRaf)\n scrollRaf = 0\n}\nonMounted(() => document.addEventListener('mouseup', onDocMouseup))\nonBeforeUnmount(() => {\n document.removeEventListener('mouseup', onDocMouseup)\n cancelAnimationFrame(scrollRaf)\n})\n\nlet rowAnchor = -1\nconst onMousedown = (e: MouseEvent) => {\n if (e.button !== 0) return\n const target = e.target as HTMLElement\n // Fill handle (07 §8): 4 px dışarı taştığı için alt satırın hücresi hedef olabilir; dikdörtgenle tespit.\n const handle = root.value?.querySelector<HTMLElement>('.dt-fill-handle')\n const hr = handle?.getBoundingClientRect()\n if (\n hr &&\n e.clientX >= hr.left - 2 &&\n e.clientX <= hr.right + 2 &&\n e.clientY >= hr.top - 2 &&\n e.clientY <= hr.bottom + 2\n ) {\n const b = table.bounds.value\n if (!b) return\n e.preventDefault()\n sheet.edit.commit()\n fillDrag.value = {\n fromRow: b.minRowIndex,\n toRow: b.maxRowIndex,\n cols: [b.minColumnIndex, b.maxColumnIndex],\n target: b.maxRowIndex,\n }\n dragging.value = 'fill'\n pointer = { x: e.clientX, y: e.clientY }\n return\n }\n const rowEl = target.closest<HTMLElement>('.dt-row[data-index]')\n if (target.closest('.dt-gutter') && rowEl && !props.skeleton) {\n // Gutter: satırın tamamı, ⇧ ile satır aralığı (07 §6).\n e.preventDefault()\n const i = Number(rowEl.dataset.index)\n const cols = columns.value\n const from = e.shiftKey && rowAnchor >= 0 ? rowAnchor : i\n rowAnchor = from\n sheet.edit.commit()\n table.selectRange({\n anchorRowId: keyOf(props.rows[from]),\n anchorColumnId: cols[0]!.id,\n focusRowId: keyOf(props.rows[i]),\n focusColumnId: cols[cols.length - 1]!.id,\n })\n focusActive()\n return\n }\n const h = hit(e)\n if (!h) return\n rowAnchor = -1\n const ed = sheet.edit.editing.value\n if (ed?.inCell && h.cell.classList.contains('is-editing')) return\n // Başka hücreye mousedown onaylar (07 §5); hücredeki düğme hücreyi aktif yapar ama düzenlemez.\n sheet.edit.commit()\n if (props.phone) {\n // Telefon: dokunma yalnızca hücreyi odaklar (kaydırma serbest, aralık yok).\n table.focus(keyOf(h.row), h.columnId)\n return\n }\n if (!isInteractive(h.target, h.cell)) e.preventDefault()\n table.startHandler(keyOf(h.row), h.columnId)?.(e)\n dragging.value = 'select'\n pointer = { x: e.clientX, y: e.clientY }\n h.cell.focus({ preventScroll: true })\n}\nconst onMouseover = (e: MouseEvent) => {\n if (dragging.value === 'fill') return\n const h = hit(e)\n if (h) table.extendHandler(keyOf(h.row), h.columnId)?.(e)\n}\nconst onDblclick = (e: MouseEvent) => {\n const h = hit(e)\n if (!h || isInteractive(h.target, h.cell)) return\n const def = defById.value.get(h.columnId)\n if (!def) return\n // boolean: düzenleme modu yok (07 §5); çift tık Space gibi Yes ↔ No çevirir.\n if (def.type === 'boolean' && !def.editor) {\n if (sheet.canEdit(h.row, def)) sheet.toggle(h.row, def)\n return\n }\n sheet.edit.start(h.row, def, { inCell: true })\n}\nconst fillFor = (i: number): RowFill | null => {\n const f = fillDrag.value\n if (!f || f.target === f.toRow) return null\n const down = f.target > f.toRow\n const inRange = down ? i > f.toRow && i <= f.target : i < f.fromRow && i >= f.target\n if (!inRange) return null\n return { from: f.cols[0], to: f.cols[1], last: down ? i === f.target : i === f.fromRow - 1 }\n}\n\n/** Sağ tık (07 §9): hedef hücre seçimin dışındaysa aktif olur; hücre dışı (header, boş alan) için menü açılmaz. */\nconst onContextmenuCapture = (e: MouseEvent) => {\n const h = hit(e)\n if (!h || props.skeleton) {\n e.stopPropagation()\n return\n }\n const b = table.bounds.value\n const ci = columns.value.findIndex((c) => c.id === h.columnId)\n const inside =\n !!b && h.index >= b.minRowIndex && h.index <= b.maxRowIndex && ci >= b.minColumnIndex && ci <= b.maxColumnIndex\n if (!inside) {\n sheet.edit.commit()\n table.focus(keyOf(h.row), h.columnId)\n h.cell.focus({ preventScroll: true })\n }\n}\n/** ⇧F10 / Menü tuşu: menü hücrenin köşesinde (reka tetikleyicisi contextmenu olayından konum alır). */\nconst openMenuAt = (cell: HTMLElement) => {\n const r = cell.getBoundingClientRect()\n cell.dispatchEvent(\n new MouseEvent('contextmenu', { bubbles: true, cancelable: true, clientX: r.left + 8, clientY: r.bottom - 4 }),\n )\n}\nconst menuHref = computed(() => {\n const row = props.rows[activeIndex.value]\n return row ? sheet.openHref(row) : undefined\n})\nconst sortOf = (id: string) => props.sort?.get(id)\n\nconst unitOf = (def: ColumnDef<AnyRow>) => (typeof def.unit === 'string' ? def.unit : undefined)\n// D33: anahtar sütunda anahtar metni, açıklama varsa altına ikinci satır; aksi halde ad + açıklama.\nconst headTip = (col: { id: string; def: ColumnDef<AnyRow> }) => {\n const key = col.id === props.keyColumn ? ctx.i18n.t('sheet.keyTooltip', { key: col.def.header }) : undefined\n return col.def.description ? `${key ?? col.def.header}\\n${col.def.description}` : key\n}\nconst resize = (col: LayoutColumn<AnyRow>, e: MouseEvent | TouchEvent) => {\n const cell = (e.currentTarget as HTMLElement).parentElement!\n layout.setWidth(col.id, cell.getBoundingClientRect().width)\n col.header.getResizeHandler()(e)\n}\nconst requiredLabel = ctx.i18n.t('sheet.required').toLocaleLowerCase(ctx.locale)\n\ndefineExpose({ focusActive, scrollToIndex: (i: number) => virtualizer.value.scrollToIndex(i) })\n</script>\n\n<template>\n <ContextMenuRoot>\n <ContextMenuTrigger as-child>\n <div\n ref=\"root\"\n class=\"dt-grid dt-sheet-grid\"\n :class=\"{\n 'is-scrolled-start': scrolledStart,\n 'is-skeleton': skeleton,\n 'has-vlines': verticalLines,\n 'is-filling': dragging === 'fill',\n 'is-phone': phone,\n }\"\n role=\"grid\"\n :aria-label=\"label\"\n :aria-rowcount=\"skeleton ? -1 : rows.length\"\n :aria-colcount=\"columns.length + (phone ? 0 : 1)\"\n :aria-busy=\"loading || readOnly ? 'true' : undefined\"\n :aria-readonly=\"readOnly ? 'true' : undefined\"\n :data-density=\"density\"\n @keydown=\"onKeydown\"\n @mousedown=\"onMousedown\"\n @mousemove=\"onMousemove\"\n @mouseover=\"onMouseover\"\n @dblclick=\"onDblclick\"\n @contextmenu.capture=\"onContextmenuCapture\"\n @copy=\"clipboard($event, 'copy')\"\n @cut=\"clipboard($event, 'cut')\"\n @paste=\"clipboard($event, 'paste')\"\n >\n <div ref=\"scrollEl\" class=\"dt-scroll\" @scroll.passive=\"onScroll\">\n <div class=\"dt-head\" role=\"row\" aria-rowindex=\"1\">\n <div v-if=\"!phone\" class=\"dt-head-cell dt-gutter is-pinned-start\" style=\"left: 0px\" role=\"columnheader\">\n {{ ctx.i18n.t('sheet.err.row') }}\n </div>\n <div\n v-for=\"col in columns\"\n :key=\"col.id\"\n class=\"dt-head-cell\"\n :class=\"[\n `is-${alignOf(col.def)}`,\n {\n 'is-numeric': isNumericType(col.def.type),\n 'is-key': col.id === keyColumn,\n 'is-pinned-start': col.pinned === 'start',\n 'is-pin-edge': col.pinEdge,\n 'is-resizing': layout.resizing.value?.id === col.id,\n },\n ]\"\n :style=\"col.pinned === 'start' ? { left: `var(${col.offsetVar})` } : undefined\"\n role=\"columnheader\"\n :aria-sort=\"\n sortOf(col.id)?.dir === 'asc' ? 'ascending' : sortOf(col.id)?.dir === 'desc' ? 'descending' : undefined\n \"\n :data-col=\"col.id\"\n >\n <PhLock v-if=\"col.id === keyColumn\" :size=\"12\" class=\"dt-head-lock\" aria-hidden=\"true\" />\n <button\n type=\"button\"\n class=\"dt-head-label\"\n tabindex=\"-1\"\n :data-dt-tip=\"headTip(col)\"\n :aria-describedby=\"col.def.description ? `${uid}-desc-${col.id}` : undefined\"\n @click=\"sheet.sort(col.id, $event.shiftKey)\"\n >\n <span class=\"dt-head-text\">{{ col.def.header }}</span>\n <span v-if=\"col.def.required\" class=\"dt-head-required\" :aria-label=\"requiredLabel\">*</span>\n <span v-if=\"unitOf(col.def)\" class=\"dt-head-unit\">{{ unitOf(col.def) }}</span>\n <span v-if=\"sortOf(col.id)\" class=\"dt-head-sort\" aria-hidden=\"true\">\n <PhArrowUp :size=\"12\" :class=\"{ 'is-desc': sortOf(col.id)!.dir === 'desc' }\" />\n <span v-if=\"sortOf(col.id)!.index\" class=\"dt-head-sort-index\">{{ sortOf(col.id)!.index }}</span>\n </span>\n </button>\n <span v-if=\"col.def.description\" :id=\"`${uid}-desc-${col.id}`\" class=\"dt-sr-only\">\n {{ col.def.description }}\n </span>\n <span class=\"dt-head-sep\" aria-hidden=\"true\" />\n <span\n class=\"dt-resize\"\n aria-hidden=\"true\"\n @mousedown=\"resize(col, $event)\"\n @touchstart.passive=\"resize(col, $event)\"\n >\n <span v-if=\"layout.resizing.value?.id === col.id\" class=\"dt-resize-badge\">\n {{ Math.round(layout.resizing.value!.size) }} px\n </span>\n </span>\n </div>\n <div class=\"dt-head-cell dt-cell-fill\" role=\"presentation\" aria-hidden=\"true\" />\n </div>\n <div class=\"dt-body\" role=\"presentation\" :style=\"{ height: `${totalSize}px` }\">\n <div\n v-for=\"item in virtualRows\"\n :key=\"String(item.key)\"\n class=\"dt-item\"\n :data-index=\"item.index\"\n :style=\"{ transform: `translateY(${item.start - headH}px)` }\"\n >\n <SkeletonRow v-if=\"skeleton\" :index=\"item.index\" :columns=\"columns\" :gutter=\"!phone\" />\n <SheetRow\n v-else\n :row=\"rows[item.index]!\"\n :index=\"item.index\"\n :row-no=\"store.rowNoOf(keyOf(rows[item.index]))\"\n :gutter=\"!phone\"\n :uid=\"uid\"\n :columns=\"columns\"\n :env=\"env\"\n :key-column=\"keyColumn\"\n :read=\"store.read\"\n :original=\"store.original\"\n :can-edit=\"sheet.canEdit\"\n :current=\"store.current\"\n :editor-for=\"sheet.editorFor\"\n :draft=\"store.rowDraft(keyOf(rows[item.index]))\"\n :issues=\"store.rowIssues(keyOf(rows[item.index]))\"\n :is-new=\"store.isNew(keyOf(rows[item.index]))\"\n :row-error=\"store.rowError(keyOf(rows[item.index]))\"\n :active=\"activeIndex === item.index ? active!.columnId : null\"\n :selection=\"selectionFor(item.index)\"\n :handle-at=\"handleFor(item.index)\"\n :fill=\"fillFor(item.index)\"\n :found=\"foundFor(item.index)\"\n :editing=\"editingFor(item.index)\"\n :tip-below=\"item.index === 0\"\n @edit-value=\"(v) => sheet.edit.setValue(v)\"\n @use-suggestion=\"(def, v) => sheet.useSuggestion(rows[item.index], def, v)\"\n />\n </div>\n </div>\n </div>\n <div\n v-if=\"fillLabel\"\n class=\"dt-fill-label\"\n role=\"status\"\n :style=\"{ left: `${fillLabel.left}px`, top: `${fillLabel.top}px` }\"\n >\n {{ fillLabel.text }}\n </div>\n <div v-if=\"$slots.state && !skeleton && rows.length === 0\" class=\"dt-body-state\"><slot name=\"state\" /></div>\n <SheetMenu :sheet=\"sheet\" :entity=\"entity\" :href=\"menuHref\" :read-only=\"readOnly || loading\" />\n </div>\n </ContextMenuTrigger>\n </ContextMenuRoot>\n</template>\n","// Düzenleme oturumu (07 §5): tek düzenlenen hücre; taslak değer burada durur, editör yalnızca düzenlenirken çizilir\n// (sanal kaydırmada kaybolmaz). Onaylayanlar: Enter/Tab, başka hücreye mousedown, ızgara dışına tık; Esc iptal; blur ile\n// onay yoktur. `inCell: false` formül çubuğundan düzenlemedir (hücre editör açmaz). Onayda '' → null.\nimport { shallowRef, type Component } from 'vue'\nimport type { ColumnDef } from '../types/columns'\nimport type { SheetStore } from './useSheetStore'\nimport type { SheetTable } from './useSheetTable'\n\nexport interface EditState<Row extends object> {\n row: Row\n def: ColumnDef<Row>\n value: unknown\n inCell: boolean\n /** Formül çubuğundan yazılan ham metin (çözümlenmiş değerden geri üretilmez: \"2,\" yazarken virgül kaybolmasın). */\n text?: string\n /** `multiselect` editörü yazarak açıldıysa: yazılan harf aramaya gider, değer korunur. */\n seed?: string\n}\n\nexport interface SheetEditingOptions<Row extends object> {\n store: SheetStore<Row>\n canEdit: (row: Row, def: ColumnDef<Row>) => boolean\n parse: (def: ColumnDef<Row>, text: string) => unknown\n}\n\nexport function useSheetEditing<Row extends object>(o: SheetEditingOptions<Row>) {\n const editing = shallowRef<EditState<Row> | null>(null)\n\n /** `replace`: yazarak açılış — içerik yazılanla değiştirilir; yoksa F2 / çift tık — mevcut değer, imleç sonda. */\n const start = (row: Row, def: ColumnDef<Row>, opts: { inCell: boolean; replace?: string }): boolean => {\n if (!o.canEdit(row, def)) return false\n // boolean'ın düzenleme modu yok (07 §5): Space / çift tık çevirir; özel editör verilmişse o açılır.\n if (def.type === 'boolean' && !def.editor) return false\n // Çoklu değerde yazmak chip'leri silmez (06 §7 T11-07): harf arama kutusuna gider.\n if (opts.replace !== undefined && !def.editor && def.type === 'multiselect') {\n editing.value = { row, def, value: o.store.read(row, def), inCell: opts.inCell, seed: opts.replace }\n return true\n }\n const value = opts.replace !== undefined ? o.parse(def, opts.replace) : o.store.read(row, def)\n editing.value = { row, def, value, inCell: opts.inCell, text: opts.replace }\n return true\n }\n const setValue = (value: unknown, text?: string, inCell?: boolean) => {\n const e = editing.value\n if (e) editing.value = { ...e, value, text, inCell: inCell ?? e.inCell }\n }\n const commit = (): boolean => {\n const e = editing.value\n if (!e) return false\n editing.value = null\n o.store.set(e.row, e.def, e.value === '' ? null : e.value)\n return true\n }\n const cancel = () => {\n editing.value = null\n }\n return { editing, start, setValue, commit, cancel }\n}\n\nexport type SheetEditing<Row extends object> = ReturnType<typeof useSheetEditing<Row>>\n\n/** DataSheet'in SheetGrid'e verdiği nesne: durum + niyetler (grid DOM'u, DataSheet kuralları yönetir). */\nexport interface SheetApi<Row extends object> {\n store: SheetStore<Row>\n table: SheetTable<Row>\n edit: SheetEditing<Row>\n canEdit: (row: Row, def: ColumnDef<Row>) => boolean\n editorFor: (def: ColumnDef<Row>) => Component | null\n /** `boolean` hücresinde Space. */\n toggle: (row: Row, def: ColumnDef<Row>) => void\n /** Delete / Backspace: seçimdeki düzenlenebilir hücreleri temizler. */\n clearCells: () => void\n /** ⌘S. */\n save: () => void\n /** F8 / ⇧F8. */\n goToError: (dir: 1 | -1) => void\n /** Pano olayları (07 §7): seçim TSV + HTML; yapıştırma aktif hücreden. İşlendiyse true (olay engellenir). */\n copy: (data: DataTransfer | null) => boolean\n cut: (data: DataTransfer | null) => boolean\n paste: (data: DataTransfer | null) => boolean\n /** Fill handle (07 §8): kaynak satır aralığı + sütun dizini aralığı → hedef satıra kadar. */\n fill: (fromRow: number, toRow: number, cols: [number, number], target: number) => void\n fillLabel: (fromRow: number, toRow: number, cols: [number, number], target: number) => string\n /** ⌘D. */\n fillDown: () => void\n undo: () => void\n redo: () => void\n /** Balondaki \"Use Pumps\". */\n useSuggestion: (row: Row, def: ColumnDef<Row>, value: unknown) => void\n /** Hücre menüsü (07 §9): panoya yaz / panodan oku (`navigator.clipboard`), satır ekle, listeden çıkar (⌘−). */\n copyToClipboard: (cut: boolean) => void\n pasteFromClipboard: () => void\n insertRow: (where: 'above' | 'below') => void\n removeSelectedRows: () => void\n /** Header tıklaması: yerel sıralama (07 §10). */\n sort: (columnId: string, additive: boolean) => void\n /** Sunucuda var olan satırın linki (\"Open product\"); yeni satırda undefined. */\n openHref: (row: Row) => string | undefined\n}\n","// Taslak deposu (07 §18, D11–D13): uygulamanın `rows` dizisine dokunmaz. Katmanlar, okuma sırasıyla:\n// draft Map<rowKey, Map<columnId, value>> — hücre başına, `Map.has` ile (bilinçli null korunur)\n// base Map<rowKey, Row> — kayıt sonrası sunucu satırı (07 §14)\n// rows uygulamanın dizisi + `added` (yeni satırlar `new:n`, sunucu değeri yok, anahtar sütunu zorunlu)\n// Tek okuyucu `read`; render, doğrulama, kopyalama bunu kullanır. Doğrulama satır başına, hücre onaylanınca (07 §5):\n// tip → required → validate → warn; aynı satırın diğer hücreleri de yenilenir (çapraz kural); anahtar tekilliği (07 §9)\n// aynı anahtarı taşıyan tüm satırlarda. Sunucu hataları (`applyResult`) ayrı tutulur; hücre düzenlenince o hücreninki\n// temizlenir. Komut yığını (07 §12): adım = `{ patches, added, removed }`, 100 adım; `apply` toplu yazar.\n// Satır Map'leri her değişimde yeni nesnedir: yalnızca o satır yeniden çizilir.\nimport { computed, shallowReactive, shallowRef, toRaw, toValue, watch, type MaybeRefOrGetter } from 'vue'\nimport { isEmptyValue, optionLabel } from '../core/cells/format'\nimport { TYPE_SPECS } from '../core/cells/specs'\nimport { readPath } from '../core/columns/readPath'\nimport { toDate } from '../core/format'\nimport type { I18n } from '../core/i18n'\nimport type { ColumnDef, OptionDef } from '../types/columns'\nimport type { SheetChangeRow, SheetChanges, SheetRowResult } from '../types/sheet'\n\nexport interface Issue {\n level: 'error' | 'warning'\n message: string\n /** \"“Pump” isn't an option\" için yakın seçenek (balonda \"Use Pumps\"). */\n suggest?: OptionDef\n /** Sunucudan (`applyResult`): hücre düzenlenince temizlenir. */\n server?: boolean\n}\nexport interface Patch {\n key: string\n col: string\n before: unknown\n after: unknown\n}\nexport interface Step {\n patches: Patch[]\n /** Bu adımda eklenen satırlar (undo kaldırır, redo geri koyar). */\n added?: Array<{ key: string; row: object }>\n /** Bu adımda listeden çıkarılan satırlar (undo geri getirir). */\n removed?: string[]\n}\nexport interface Change<Row extends object> {\n row: Row\n def: ColumnDef<Row>\n value: unknown\n}\n/** Yeni satırın anahtar durumu (07 §9): kontrol sürüyor · sunucuda yok (New) · sunucuda var (Update). */\n\nexport interface SheetStoreOptions<Row extends object> {\n rows: MaybeRefOrGetter<Row[]>\n columns: MaybeRefOrGetter<Array<ColumnDef<Row>>>\n rowKey: MaybeRefOrGetter<string>\n keyColumn: MaybeRefOrGetter<string>\n i18n: I18n\n locale: string\n}\n\nconst HISTORY = 100\n\n/** Boş değerler (null / undefined / '' / []) birbirine eşit sayılır; diziler elemanlarıyla. */\nconst same = (a: unknown, b: unknown): boolean =>\n (isEmptyValue(a) && isEmptyValue(b)) ||\n Object.is(a, b) ||\n (Array.isArray(a) && Array.isArray(b) && a.length === b.length && a.every((x, i) => Object.is(x, b[i])))\n\nfunction setPath(obj: Record<string, unknown>, path: string, value: unknown) {\n const keys = path.split('.')\n let o = obj\n for (const k of keys.slice(0, -1)) {\n const next = o[k]\n o[k] = next && typeof next === 'object' ? { ...(next as object) } : {}\n o = o[k] as Record<string, unknown>\n }\n o[keys[keys.length - 1]!] = value\n}\n\nconst fold = (s: string, locale: string) => s.trim().toLocaleLowerCase(locale).replace(/ı|i̇/g, 'i')\n/** Yakın seçenek: aynı başlangıç, içerme ya da ≤ 2 harf farkı. */\nfunction closest(options: OptionDef[], value: string, locale: string): OptionDef | undefined {\n const v = fold(value, locale)\n if (!v) return undefined\n const dist = (a: string, b: string): number => {\n const d = Array.from({ length: b.length + 1 }, (_, i) => i)\n for (let i = 1; i <= a.length; i++) {\n let prev = d[0]!\n d[0] = i\n for (let j = 1; j <= b.length; j++) {\n const tmp = d[j]!\n d[j] = Math.min(d[j]! + 1, d[j - 1]! + 1, prev + (a[i - 1] === b[j - 1] ? 0 : 1))\n prev = tmp\n }\n }\n return d[b.length]!\n }\n return (\n options.find((o) => fold(o.label, locale).startsWith(v) || v.startsWith(fold(o.label, locale))) ??\n options.find((o) => dist(fold(o.label, locale), v) <= 2)\n )\n}\n\nexport function useSheetStore<Row extends object>(o: SheetStoreOptions<Row>) {\n const t = o.i18n.t\n const defs = computed(() => toValue(o.columns))\n const defById = computed(() => new Map(defs.value.map((d) => [d.id as string, d])))\n const keyCol = () => toValue(o.keyColumn)\n const draft = shallowReactive(new Map<string, Map<string, unknown>>())\n const issues = shallowReactive(new Map<string, Map<string, Issue>>())\n /** Sunucu alan hataları ve satır hatası (07 §14). */\n const serverErrors = shallowReactive(new Map<string, Map<string, string>>())\n const rowErrors = shallowReactive(new Map<string, string>())\n /** Sunucu değerleri; `from` kayıt anındaki yüklenmiş satır nesnesi (uygulama satırı yenileyince base düşer). */\n const base = shallowReactive(new Map<string, { row: Row; from: Row | undefined }>())\n const added = shallowRef<Array<{ key: string; row: Row; saved?: boolean }>>([])\n const removed = shallowReactive(new Set<string>())\n /** Her yazmada artar: seçim özeti gibi toplu okuyucular hücre başına bağımlılık kurmadan buna bağlanır. */\n const version = shallowRef(0)\n const undoStack: Step[] = []\n const redoStack: Step[] = []\n const canUndo = shallowRef(false)\n const canRedo = shallowRef(false)\n let newCounter = 0\n\n const keyOf = (row: Row): string => String(readPath(row, toValue(o.rowKey)))\n /** Parti: yüklenen + eklenen satırlar, listeden çıkarılanlar dahil (gutter numarası bu sıradır, 07 §3). */\n const batch = computed<Row[]>(() =>\n added.value.length ? [...toValue(o.rows), ...added.value.map((a) => a.row)] : toValue(o.rows),\n )\n const batchIndex = computed(() => {\n const m = new Map<string, number>()\n batch.value.forEach((r, i) => m.set(keyOf(r), i))\n return m\n })\n /** Gösterilen parti: çıkarılanlar hariç. */\n const allRows = computed<Row[]>(() =>\n removed.size ? batch.value.filter((r) => !removed.has(keyOf(r))) : batch.value,\n )\n const byKey = computed(() => {\n const m = new Map<string, Row>()\n for (const r of batch.value) m.set(keyOf(r), r)\n return m\n })\n const addedByKey = computed(() => new Map(added.value.map((a) => [a.key, a])))\n /** Yeni satır: eklenmiş ve henüz kaydedilmemiş (kaydedilince yüklenmiş sayılır, numarası kalır). */\n const isNew = (key: string) => !!addedByKey.value.get(key) && !addedByKey.value.get(key)!.saved\n const rowNoOf = (key: string) => (batchIndex.value.get(key) ?? -1) + 1\n\n const original = (row: Row, def: ColumnDef<Row>): unknown => {\n const key = keyOf(row)\n const b = base.get(key)\n if (b) return def.accessor ? def.accessor(b.row) : readPath(b.row, def.id as string)\n if (isNew(key)) return undefined\n return def.accessor ? def.accessor(row) : readPath(row, def.id as string)\n }\n const readFrom = (map: Map<string, Map<string, unknown>>, row: Row, def: ColumnDef<Row>): unknown => {\n const d = map.get(keyOf(row))\n const id = def.id as string\n return d?.has(id) ? d.get(id) : original(row, def)\n }\n const read = (row: Row, def: ColumnDef<Row>): unknown => readFrom(draft, row, def)\n /** Bağımlılık kurmadan okur (toplu özetler `version` ile yenilenir). */\n const readUntracked = (row: Row, def: ColumnDef<Row>): unknown => readFrom(toRaw(draft), row, def)\n /** Satırın güncel hali (doğrulama bağlamı, create yükü): base + taslak kopya üstüne; `rows` değişmez. */\n const current = (row: Row): Row => {\n const key = keyOf(row)\n const b = base.get(key)\n const d = draft.get(key)\n if (!b && !d?.size) return row\n const obj = { ...row, ...(b?.row as object) } as Record<string, unknown>\n for (const [col, v] of d ?? []) setPath(obj, col, v)\n return obj as Row\n }\n\n /** Anahtar değeri → o değeri taşıyan satır anahtarları (tekillik, 07 §9); çıkarılanlar sayılmaz. */\n const keyIndex = computed(() => {\n void version.value\n const m = new Map<string, Set<string>>()\n const def = defById.value.get(keyCol())\n if (!def) return m\n for (const row of allRows.value) {\n const v = readUntracked(row, def)\n if (isEmptyValue(v)) continue\n const k = String(v)\n let set = m.get(k)\n if (!set) m.set(k, (set = new Set()))\n set.add(keyOf(row))\n }\n return m\n })\n\n const typeIssue = (def: ColumnDef<Row>, value: unknown): Issue | null => {\n if (isEmptyValue(value)) return null\n const error = (message: string, suggest?: OptionDef): Issue => ({ level: 'error', message, suggest })\n if ((TYPE_SPECS[def.type].numeric || def.type === 'star') && typeof value !== 'number')\n return error(\n typeof value === 'string' && value.trim().startsWith('=') ? t('sheet.noFormulas') : t('sheet.notANumber'),\n )\n if ((def.type === 'date' || def.type === 'datetime') && Number.isNaN(toDate(value as string).getTime()))\n return error(t('sheet.notADate'))\n if (def.type === 'boolean' && typeof value !== 'boolean')\n return error(t('sheet.notAnOption', { value: String(value) }))\n if (def.type === 'select' && !def.options.some((opt) => opt.value === value))\n return error(t('sheet.notAnOption', { value: String(value) }), closest(def.options, String(value), o.locale))\n if (def.type === 'multiselect') {\n const bad = (Array.isArray(value) ? value : [value]).find((v) => !def.options.some((opt) => opt.value === v))\n if (bad !== undefined) return error(t('sheet.notAnOption', { value: String(bad) }))\n }\n return null\n }\n /** `optionEnabled`: satıra göre kapalı seçenek yalnızca değişen hücrede hata (mevcut değer kural değişince değil). */\n const optionIssue = (def: ColumnDef<Row>, value: unknown, ctx: { row: Row; original: unknown }): Issue | null => {\n if ((def.type !== 'select' && def.type !== 'multiselect') || !def.optionEnabled) return null\n if (isEmptyValue(value) || same(value, ctx.original)) return null\n const { options, optionEnabled } = def\n const bad = (Array.isArray(value) ? value : [value]).find((v) => {\n const opt = options.find((o) => o.value === v)\n return opt && !optionEnabled(opt, ctx.row)\n })\n return bad === undefined\n ? null\n : { level: 'error', message: t('sheet.notAnOption', { value: optionLabel(options, bad) }) }\n }\n const duplicateIssue = (key: string, value: unknown): Issue | null => {\n if (isEmptyValue(value)) return null\n const others = keyIndex.value.get(String(value))\n if (!others || others.size < 2) return null\n const other = [...others].find((k) => k !== key)\n return other\n ? { level: 'error', message: t('sheet.duplicateKey', { key: String(value), row: rowNoOf(other) }) }\n : null\n }\n const validateRow = (row: Row) => {\n const key = keyOf(row)\n const isNewRow = isNew(key)\n const cur = current(row)\n const map = new Map<string, Issue>()\n for (const def of defs.value) {\n const value = read(row, def)\n const ctx = { row: cur, isNew: isNewRow, original: original(row, def) }\n const isKey = def.id === keyCol()\n const required = def.required || (isNewRow && isKey)\n const issue =\n typeIssue(def, value) ??\n optionIssue(def, value, ctx) ??\n (required && isEmptyValue(value) ? { level: 'error' as const, message: t('sheet.required') } : null) ??\n // Yüklenmiş satırların anahtarı salt okunur: çift anahtar yalnızca yeni satır varken mümkün (10k indeks boşa kurulmaz).\n (isKey && (isNewRow || added.value.length) ? duplicateIssue(key, value) : null) ??\n (() => {\n const err = def.validate?.(value, ctx)\n if (err) return { level: 'error' as const, message: err }\n const warn = def.warn?.(value, ctx)\n return warn ? { level: 'warning' as const, message: warn } : null\n })()\n if (issue) map.set(def.id as string, issue)\n }\n if (map.size) issues.set(key, map)\n else issues.delete(key)\n }\n /** Anahtar sütunu değişince aynı değeri taşıyan diğer satırlar da yeniden doğrulanır (çift anahtar belirir/kalkar). */\n const revalidateKeys = (values: unknown[]) => {\n for (const v of values) {\n if (isEmptyValue(v)) continue\n for (const k of keyIndex.value.get(String(v)) ?? []) {\n const row = byKey.value.get(k)\n if (row) validateRow(row)\n }\n }\n }\n\n /** Ham yazma: satır başına tek Map kopyası ve tek doğrulama. Yama listesi döner (undo için `before`). */\n const write = (changes: Array<Change<Row>>): Patch[] => {\n const patches: Patch[] = []\n const touched = new Map<string, { row: Row; map: Map<string, unknown> }>()\n const keyValues: unknown[] = []\n for (const c of changes) {\n const key = keyOf(c.row)\n const id = c.def.id as string\n const before = read(c.row, c.def)\n if (same(before, c.value)) continue\n let entry = touched.get(key)\n if (!entry) touched.set(key, (entry = { row: c.row, map: new Map(draft.get(key)) }))\n if (same(c.value, original(c.row, c.def))) entry.map.delete(id)\n else entry.map.set(id, c.value)\n patches.push({ key, col: id, before, after: c.value })\n if (id === keyCol()) keyValues.push(before, c.value)\n // Hücre düzenlenince o hücrenin sunucu hatası temizlenir; satır hatası da düşer (07 §14).\n const se = serverErrors.get(key)\n if (se?.has(id)) {\n const next = new Map(se)\n next.delete(id)\n if (next.size) serverErrors.set(key, next)\n else serverErrors.delete(key)\n }\n rowErrors.delete(key)\n }\n for (const [key, { map }] of touched) {\n if (map.size) draft.set(key, map)\n else draft.delete(key)\n }\n if (patches.length) version.value++\n for (const { row, map } of touched.values()) {\n if (map.size || isNew(keyOf(row))) validateRow(row)\n else issues.delete(keyOf(row))\n }\n if (keyValues.length) revalidateKeys(keyValues)\n return patches\n }\n const syncHistory = () => {\n canUndo.value = undoStack.length > 0\n canRedo.value = redoStack.length > 0\n }\n const record = (step: Step) => {\n undoStack.push(step)\n if (undoStack.length > HISTORY) undoStack.shift()\n redoStack.length = 0\n syncHistory()\n }\n\n /** Tek kullanıcı işlemi = tek undo adımı; boş değişiklik kaydedilmez. */\n const apply = (changes: Array<Change<Row>>, addedRows: Array<{ key: string; row: Row }> = []): Patch[] => {\n const patches = write(changes)\n if (patches.length || addedRows.length) record({ patches, added: addedRows.length ? addedRows : undefined })\n return patches\n }\n const set = (row: Row, def: ColumnDef<Row>, value: unknown) => apply([{ row, def, value }])\n\n /** Yeni satırlar (07 §9): anahtar `new:n`, numara mevcut satırların devamı; anahtar yazılınca doğrulanır. */\n const addRows = (count: number): Array<{ key: string; row: Row }> => {\n const rows = Array.from({ length: count }, () => {\n const key = `new:${++newCounter}`\n const row = {} as Record<string, unknown>\n setPath(row, toValue(o.rowKey), key)\n return { key, row: row as Row }\n })\n added.value = [...added.value, ...rows]\n version.value++\n for (const r of rows) {\n validateRow(r.row)\n }\n return rows\n }\n const dropAdded = (keys: string[]) => {\n const drop = new Set(keys)\n added.value = added.value.filter((a) => !drop.has(a.key))\n for (const k of keys) {\n draft.delete(k)\n issues.delete(k)\n base.delete(k)\n }\n version.value++\n }\n /** Listeden çıkarma (D12): sunucuda silmez; değişiklikleri gönderilmez; tek undo adımı. */\n const removeRows = (keys: string[]) => {\n const keyDef = defById.value.get(keyCol())\n const values = keyDef ? keys.map((k) => byKey.value.get(k)).map((r) => (r ? read(r, keyDef) : null)) : []\n for (const k of keys) removed.add(k)\n version.value++\n record({ patches: [], removed: keys })\n revalidateKeys(values)\n }\n const restoreRows = (keys: string[]) => {\n for (const k of keys) removed.delete(k)\n version.value++\n const keyDef = defById.value.get(keyCol())\n if (keyDef) revalidateKeys(keys.map((k) => byKey.value.get(k)).map((r) => (r ? read(r, keyDef) : null)))\n }\n\n const replay = (step: Step, dir: 'undo' | 'redo') => {\n if (dir === 'undo' && step.added) dropAdded(step.added.map((a) => a.key))\n if (dir === 'redo' && step.added) {\n added.value = [...added.value, ...(step.added as Array<{ key: string; row: Row }>)]\n version.value++\n }\n if (step.removed) {\n if (dir === 'undo') restoreRows(step.removed)\n else {\n for (const k of step.removed) removed.add(k)\n version.value++\n }\n }\n const changes: Array<Change<Row>> = []\n for (const p of step.patches) {\n const row = byKey.value.get(p.key)\n const def = defById.value.get(p.col)\n if (row && def) changes.push({ row, def, value: dir === 'undo' ? p.before : p.after })\n }\n write(changes)\n if (dir === 'redo' && step.added) for (const a of step.added) validateRow(a.row as Row)\n }\n const undo = (): Step | null => {\n const step = undoStack.pop()\n if (!step) return null\n replay(step, 'undo')\n redoStack.push(step)\n syncHistory()\n return step\n }\n const redo = (): Step | null => {\n const step = redoStack.pop()\n if (!step) return null\n replay(step, 'redo')\n undoStack.push(step)\n syncHistory()\n return step\n }\n const clearHistory = () => {\n undoStack.length = 0\n redoStack.length = 0\n syncHistory()\n }\n\n const rowDraft = (key: string) => draft.get(key)\n /** İstemci + sunucu hataları (sunucu hatası olan birkaç satırda birleşik Map). */\n const rowIssues = (key: string): Map<string, Issue> | undefined => {\n const client = issues.get(key)\n const server = serverErrors.get(key)\n if (!server) return client\n const merged = new Map(client)\n for (const [col, message] of server)\n if (!merged.has(col)) merged.set(col, { level: 'error', message, server: true })\n return merged\n }\n const rowError = (key: string) => rowErrors.get(key)\n const hasError = (key: string): boolean => {\n if (serverErrors.has(key) || rowErrors.has(key)) return true\n const m = issues.get(key)\n if (!m) return false\n for (const i of m.values()) if (i.level === 'error') return true\n return false\n }\n const counts = computed(() => {\n let changedCells = 0\n const changedKeys = new Set<string>()\n for (const [k, m] of draft) {\n if (removed.has(k)) continue\n changedCells += m.size\n changedKeys.add(k)\n }\n let errorRows = 0\n let warningRows = 0\n const errorKeys = new Set<string>([...serverErrors.keys(), ...rowErrors.keys()])\n for (const [k, m] of issues) {\n if (removed.has(k)) continue\n let w = false\n for (const i of m.values())\n if (i.level === 'error') errorKeys.add(k)\n else w = true\n if (w) warningRows++\n }\n for (const k of errorKeys) if (!removed.has(k)) errorRows++\n let newRows = 0\n let changedOrNewRows = changedKeys.size\n for (const a of added.value) {\n if (a.saved || removed.has(a.key)) continue\n newRows++\n if (!changedKeys.has(a.key)) changedOrNewRows++\n }\n return { changedCells, changedRows: changedKeys.size, errorRows, warningRows, newRows, changedOrNewRows }\n })\n\n /** Discard: taslak, hatalar, yeni satırlar, çıkarılanlar ve yığın gider; base kalır (kaydedilmiş değerler). */\n const reset = () => {\n draft.clear()\n issues.clear()\n serverErrors.clear()\n rowErrors.clear()\n added.value = []\n removed.clear()\n clearHistory()\n version.value++\n }\n\n /**\n * `@save` yükü (D11, D12, D47): değişmiş + eklenmiş, hatasız, çıkarılmamış satırlar. `values` = değişen alanlar +\n * `required` sütunlar + anahtar (sunucu anahtara göre upsert eder ve zorunlu alanları her satırda doğrular); eklenen\n * satırda boş değerler gitmez.\n */\n const getChanges = (): SheetChanges => {\n const keyDef = defById.value.get(keyCol())\n const always = defs.value.filter((d) => d.required || d.id === keyCol())\n const rows: SheetChangeRow[] = []\n for (const [key, m] of draft) {\n const row = byKey.value.get(key)\n if (!row || removed.has(key) || hasError(key)) continue\n const isAdded = isNew(key)\n const values: Record<string, unknown> = {}\n for (const [id, v] of m) if (!isAdded || !isEmptyValue(v)) values[id] = v\n for (const d of always) {\n const id = d.id as string\n if (id in values) continue\n const v = read(row, d)\n if (!isEmptyValue(v)) values[id] = v\n }\n rows.push({\n clientId: key,\n key: String(keyDef ? read(row, keyDef) : readPath(row, keyCol())),\n values,\n })\n }\n rows.sort((a, b) => rowNoOf(a.clientId) - rowNoOf(b.clientId))\n return { rows }\n }\n\n /** Kayıt sonuçları (07 §14): created/updated → taslak düşer, değerler `row` ya da uygulanmış taslak; error → kalır. */\n const applyResult = (results: Array<SheetRowResult<Row>>) => {\n let created = 0\n let updated = 0\n let errors = 0\n const saved = new Set<string>()\n for (const r of results) {\n const key = r.clientId\n const row = byKey.value.get(key)\n if (!row) continue\n if (r.status === 'error') {\n errors++\n const fe = r.fieldErrors ? new Map(Object.entries(r.fieldErrors)) : null\n if (fe?.size) serverErrors.set(key, fe)\n else serverErrors.delete(key)\n if (r.rowError) rowErrors.set(key, r.rowError)\n else rowErrors.delete(key)\n continue\n }\n if (r.status === 'created') created++\n else updated++\n base.set(key, { row: r.row ?? current(row), from: isNew(key) ? undefined : row })\n draft.delete(key)\n issues.delete(key)\n serverErrors.delete(key)\n rowErrors.delete(key)\n if (addedByKey.value.has(key)) saved.add(key)\n }\n // Tek kopya: sonuç başına kopya 10k kayıtta karesel olurdu.\n if (saved.size) added.value = added.value.map((x) => (saved.has(x.key) ? { ...x, saved: true } : x))\n clearHistory()\n version.value++\n return { created, updated, errors }\n }\n // Uygulama satırları yenileyince (yeni nesneler) o anahtarların base'i düşer; aynı nesneler (eski/gecikmiş dizi) düşürmez.\n watch(\n () => toValue(o.rows),\n (rows) => {\n if (!base.size) return\n const byId = new Map<string, Row>()\n for (const r of rows) byId.set(keyOf(r), r)\n for (const [key, b] of base) {\n const now = byId.get(key)\n if (b.from && now && now !== b.from) base.delete(key)\n }\n version.value++\n },\n )\n\n return {\n keyOf,\n batch,\n allRows,\n rowByKey: (key: string) => byKey.value.get(key),\n rowNoOf,\n isNew,\n isRemoved: (key: string) => removed.has(key),\n read,\n readUntracked,\n original,\n current,\n set,\n apply,\n addRows,\n removeRows,\n undo,\n redo,\n canUndo,\n canRedo,\n clearHistory,\n version,\n rowDraft,\n rowIssues,\n rowError,\n hasError,\n counts,\n reset,\n getChanges,\n applyResult,\n }\n}\n\nexport type SheetStore<Row extends object> = ReturnType<typeof useSheetStore<Row>>\n","// Hücre seçimi (01 · TanStack sınırı, D23): TanStack `cellSelectionFeature`, tek aralık (⌘-tık ile çoklu aralık yok, 07 §6).\n// Aktif hücre = aralığın çapası (roving tabindex 0). Sütun sırası ve görünürlüğü düzenden (useColumnLayout) gelir; satır\n// sırası gösterilen dizidir. DOM'a dokunmaz; odak ve kaydırma SheetGrid'de.\nimport { cellSelectionFeature, tableFeatures, useTable, type ColumnDef as TanstackColumnDef } from '@tanstack/vue-table'\nimport { computed, toValue, type MaybeRefOrGetter } from 'vue'\n\nconst features = tableFeatures({ cellSelectionFeature })\ntype Features = typeof features\n\nexport type Direction = 'up' | 'down' | 'left' | 'right'\n\n/** Gösterilen satır/sütun dizinlerinde dikdörtgen (TanStack `getCellSelectionBounds`). */\nexport interface SheetBounds {\n minRowIndex: number\n maxRowIndex: number\n minColumnIndex: number\n maxColumnIndex: number\n}\n\nexport interface SheetTableOptions<Row extends object> {\n rows: MaybeRefOrGetter<Row[]>\n /** Görünür sütunlar, çizim sırasında. */\n columnIds: MaybeRefOrGetter<string[]>\n rowId: (row: Row) => string\n}\n\nexport function useSheetTable<Row extends object>(o: SheetTableOptions<Row>) {\n const columns = computed<Array<TanstackColumnDef<Features, Row, unknown>>>(() =>\n toValue(o.columnIds).map((id) => ({ id, accessorFn: () => undefined })),\n )\n const table = useTable<Features, Row>({\n features,\n columns,\n data: computed(() => toValue(o.rows)),\n getRowId: o.rowId,\n // Satırlar parça parça gelirken (loading) seçim kaybolmasın; tek aralık (07 §6).\n autoResetCellSelection: false,\n enableMultiCellRangeSelection: false,\n })\n\n const active = computed<{ rowId: string; columnId: string } | null>(() => {\n const ranges = table.atoms.cellSelection.get()\n const a = ranges[ranges.length - 1]\n return a ? { rowId: a.anchorRowId, columnId: a.anchorColumnId } : null\n })\n const bounds = computed<SheetBounds | null>(() => table.getCellSelectionBounds()[0] ?? null)\n /** Aralığın hareket eden ucu (TanStack range focus): ⇧+ok ile genişlerken görünür alana getirilir. */\n const rangeEnd = computed<{ rowId: string; columnId: string } | null>(() => {\n const r = table.atoms.cellSelection.get()[0]\n return r ? { rowId: r.focusRowId, columnId: r.focusColumnId } : null\n })\n const cell = (rowId: string, columnId: string) =>\n table.getCoreRowModel().rowsById[rowId]?.getAllCellsByColumnId()[columnId]\n\n return {\n active,\n bounds,\n rangeEnd,\n focus: (rowId: string, columnId: string) => table.setFocusedCell(rowId, columnId),\n move: (d: Direction) => table.moveCellSelection(d),\n extend: (d: Direction) => table.extendCellSelection(d),\n selectAll: () => table.selectAllCells(),\n /** Gutter tıklaması: satır aralığının tüm hücreleri (07 §6). */\n selectRange: (range: { anchorRowId: string; anchorColumnId: string; focusRowId: string; focusColumnId: string }) =>\n table.selectCellRange(range),\n clear: () => table.resetCellSelection(true),\n /** Fare: mousedown (⇧ ile genişletme, sürükleme başlangıcı) ve sürüklerken mouseover (TanStack handler'ları). */\n startHandler: (rowId: string, columnId: string) => cell(rowId, columnId)?.getSelectionStartHandler(),\n extendHandler: (rowId: string, columnId: string) => cell(rowId, columnId)?.getSelectionExtendHandler(),\n }\n}\n\nexport type SheetTable<Row extends object> = ReturnType<typeof useSheetTable<Row>>\n","<script setup lang=\"ts\" generic=\"Row extends object\">\n// DataSheet (07, brief §8, handoff 06) — Faz 6a–6c: ızgara, editörler, doğrulama, taslak deposu; toolbar'da Find,\n// All / Changed / Errors, Undo/Redo, Add row, Display + Save kontrolleri; formül çubuğu; status bar; açılış ilerlemesi;\n// pano, fill handle, komut yığını; satır partisi (ekle / çıkar, anahtar tekilliği; sunucu durumu bilinmez, D47); yerel\n// sıralama; kayıt akışı (hata dialog'u, `@save`, `saving`, `applyResult`, Partly saved şeridi, Copy errors); ayrılma\n// koruması. İçe/dışa aktarma ve telefon düzeni (6d) sonraki fazda. Veri çekmez, kaydetmez (D18): yalnızca `@save` yayar.\nimport {\n PhArrowUUpLeft,\n PhArrowUUpRight,\n PhCaretDown,\n PhCaretUp,\n PhCheck,\n PhCircleNotch,\n PhCopy,\n PhLock,\n PhDownloadSimple,\n PhExport,\n PhLink,\n PhMonitor,\n PhPlus,\n PhWarning,\n PhWarningCircle,\n} from '@phosphor-icons/vue'\nimport {\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuPortal,\n DropdownMenuRoot,\n DropdownMenuSub,\n DropdownMenuSubContent,\n DropdownMenuSubTrigger,\n DropdownMenuTrigger,\n ToggleGroupItem,\n ToggleGroupRoot,\n} from 'reka-ui'\nimport {\n computed,\n getCurrentInstance,\n nextTick,\n onBeforeUnmount,\n onMounted,\n provide,\n ref,\n shallowRef,\n type Component,\n useTemplateRef,\n watch,\n} from 'vue'\nimport { comparator } from '../core/cells/compare'\nimport { formatCell, isEmptyValue, type FormatEnv } from '../core/cells/format'\nimport { RemoteLabels } from '../core/cells/remoteLabels'\nimport { TYPE_SPECS, typeLabelKey } from '../core/cells/specs'\nimport { readPath } from '../core/columns/readPath'\nimport { useColumnLayout } from '../core/columns/useColumnLayout'\nimport { plainText } from '../core/export/cells'\nimport { exportFile } from '../core/export/write'\nimport { getFormat } from '../core/format'\nimport { useDelegatedTooltip } from '../core/grid/useDelegatedTooltip'\nimport { FIND_KBD, REDO_KBD, SAVE_KBD, UNDO_KBD } from '../core/interaction/kbd'\nimport { useDataTableContext } from '../core/plugin'\nimport { usePreferences } from '../core/preferences/usePreferences'\nimport StateMessage from '../core/states/StateMessage.vue'\nimport DisplayPopover from '../core/toolbar/DisplayPopover.vue'\nimport type { ColumnsDraft } from '../core/toolbar/ColumnsDialog.vue'\nimport SearchBox from '../core/toolbar/SearchBox.vue'\nimport ConfirmDialog from '../core/ui/ConfirmDialog.vue'\nimport type { ColumnDef, ColumnType } from '../types/columns'\nimport type { Density, Plural, TableId } from '../types/core'\nimport type { SortRule } from '../types/query'\nimport type {\n ParsedWorkbook,\n Progress,\n SheetChanges,\n SheetFilterMode,\n SheetRowResult,\n SheetStatus,\n} from '../types/sheet'\nimport { matrixFromClipboard, parseTsv, toHtml, toTsv } from './clipboard'\nimport NumberCell from './editors/NumberCell.vue'\nimport OptionCell from './editors/OptionCell.vue'\nimport TextCell from './editors/TextCell.vue'\nimport DateCell from './editors/DateCell.vue'\nimport MultiCell from './editors/MultiCell.vue'\nimport { SHEET_EDITOR_KEY } from './editors/context'\nimport { fillValues } from './fill'\nimport ImportDialog, { type ImportPayload } from './ImportDialog.vue'\nimport { readWorkbook } from './import/read'\nimport { inferDecimal, inputText, parseInput, type ParseEnv } from './parse'\nimport SaveErrorsDialog, { type ErrorRowItem } from './SaveErrorsDialog.vue'\nimport SheetGrid from './SheetGrid.vue'\nimport { useSheetEditing, type SheetApi } from './useSheetEditing'\nimport { useSheetStore, type Change, type Step } from './useSheetStore'\nimport { useSheetTable } from './useSheetTable'\n\nconst props = withDefaults(\n defineProps<{\n tableId: TableId\n columns: Array<ColumnDef<Row>>\n rows: Row[]\n rowKey?: string\n /** Verilmezse tercihten (Display › Density), o da yoksa compact (02 · Yoğunluk). */\n density?: Density\n entityName?: Plural\n /** Upsert anahtarı olan sütun (ör. \"sku\"). Yüklenmiş satırlarda salt okunur; `rowKey`'den ayrıdır. */\n keyColumn: string\n /** Uygulama satırları yüklerken; sayaç verilirse \"Loading… 6,200 of 10,000\". Düzenleme false olunca açılır. */\n loading?: Progress\n /** `@save` sonrası uygulama kaydederken: grid salt okunur, ilerleme şeridi (07 §14). */\n saving?: Progress\n /** Add row ile oluşan satırın başlangıç değerleri. */\n newRowDefaults?: () => Partial<Row>\n /** Import: dosyayı uygulama ayrıştırır ve ham satırları verir (07 §13). Verilmezse paketin okuyucusu (.xlsx, .csv; D46). */\n parseFile?: (file: File) => Promise<ParsedWorkbook>\n /** Import düğmesi (D46). Varsayılan açık. */\n importable?: boolean\n /** Export menüsü (D46). Varsayılan açık; `false` gizler (ör. yetki). */\n exportable?: boolean\n /** Aşılırsa ilk `maxRows` satır kullanılır ve şerit uyarır (07 §15); yapıştırma ve ekleme bu sınırı aşamaz. */\n maxRows?: number\n /** Bu genişliğin altında veya yalnızca dokunmatikte salt okunur (D14); karar açılışta. */\n readOnlyBelow?: number\n }>(),\n {\n rowKey: 'id',\n loading: false,\n saving: false,\n maxRows: 10_000,\n readOnlyBelow: 768,\n importable: true,\n exportable: true,\n },\n)\nconst emit = defineEmits<{\n /** Save: doğrulama geçen değişmiş + yeni satırlar. Uygulama kaydeder, `saving` verir, `applyResult` çağırır. */\n save: [changes: SheetChanges]\n /** Export: değerler güncel (kaydedilmemiş değişiklikler dahil). Dinlenirse paket dosya yazmaz (D46). */\n export: [payload: { format: 'csv' | 'xlsx'; scope: 'all' | 'visible'; columns: string[]; rows: Row[] }]\n}>()\ndefineSlots<{ empty?: () => unknown }>()\n\nconst ctx = useDataTableContext()\nconst { i18n } = ctx\nconst fmt = getFormat(ctx.locale)\nconst entity = computed<Plural>(() => props.entityName ?? { one: props.tableId, other: props.tableId })\nconst listensExport = 'onExport' in (getCurrentInstance()?.vnode.props ?? {})\nconst readFile = (file: File) => (props.parseFile ? props.parseFile(file) : readWorkbook(file, i18n))\n\nconst pref = usePreferences(() => props.tableId, ctx.preferences, {\n density: props.density ?? 'compact',\n verticalLines: true,\n pageSize: 0,\n defaultViewId: null,\n})\nconst density = computed<Density>(() => props.density ?? pref.prefs.density)\n\nconst overLimit = computed(() => props.rows.length > props.maxRows)\nconst loadedRows = computed(() => (overLimit.value ? props.rows.slice(0, props.maxRows) : props.rows))\nconst loadingNow = computed(() => props.loading !== false)\nconst savingNow = computed(() => props.saving !== false)\nconst progress = computed(() => {\n const p = loadingNow.value ? props.loading : props.saving\n return typeof p === 'object' ? p : null\n})\nconst percent = computed(() =>\n progress.value && progress.value.total > 0 ? Math.round((100 * progress.value.done) / progress.value.total) : null,\n)\n\n// Sütunlar (07 §3): anahtar 128 px sola sabit (mono), birincil ad sola sabit ve esnek; sıra sabit, genişlik oturumluk.\n// Telefon / yalnızca dokunmatik: salt okunur, karar açılışta (D14, 07 §17): anahtar 104 px sabit, kalanlar kayar.\nconst readOnlyDevice =\n typeof matchMedia === 'function' &&\n (matchMedia(`(max-width: ${props.readOnlyBelow - 1}px)`).matches || !matchMedia('(any-pointer: fine)').matches)\nconst sheetColumns = computed<Array<ColumnDef<Row>>>(() =>\n props.columns.map((d) => (d.id === props.keyColumn ? { ...d, width: readOnlyDevice ? 104 : 128 } : d)),\n)\nconst fixedStart = computed(() =>\n sheetColumns.value\n .filter((d) => d.id === props.keyColumn || (d.primary && !readOnlyDevice))\n .map((d) => d.id as string),\n)\nconst defById = computed(() => new Map(sheetColumns.value.map((d) => [d.id as string, d])))\nconst keyDef = computed(() => defById.value.get(props.keyColumn))\nconst primaryDef = computed(() => sheetColumns.value.find((d) => d.primary))\nconst store = useSheetStore<Row>({\n rows: loadedRows,\n columns: sheetColumns,\n rowKey: () => props.rowKey,\n keyColumn: () => props.keyColumn,\n i18n,\n locale: ctx.locale,\n})\n\n// Gösterim sırası (07 §10–11): parti sırası ya da header tıklamasında alınan sıralama anlık görüntüsü (düzenlenen satır\n// imlecin altından kaçmaz); eklenen satır yerine konur; All / Changed / Errors görünümü ve çıkarılanlar süzülür.\nconst sortRules = ref<SortRule[]>([])\nconst order = shallowRef<string[] | null>(null)\nconst view = ref<SheetFilterMode>('all')\nconst viewKeys = shallowRef(new Set<string>())\nconst matchesView = (key: string) =>\n view.value === 'changed'\n ? !!store.rowDraft(key)?.size || store.isNew(key)\n : view.value === 'errors'\n ? store.hasError(key)\n : true\nconst refreshView = (union: boolean) => {\n const next = union ? new Set(viewKeys.value) : new Set<string>()\n for (const r of store.batch.value) {\n const k = store.keyOf(r)\n if (matchesView(k)) next.add(k)\n }\n viewKeys.value = next\n}\n/** Görünüm değişimi eşzamanlı uygulanır: hemen ardından gelen `goToError` doğru satır listesini görür. */\nconst setView = (v: SheetFilterMode) => {\n view.value = v\n refreshView(false)\n}\n// Görünümde kalma kuralı: son hatayı düzelttiğin satır görünümden çıkana kadar yerinde kalır; yeni uyanlar eklenir.\nwatch(store.version, () => {\n if (view.value !== 'all') refreshView(true)\n})\nconst orderedBatch = computed<Row[]>(() => {\n const batch = store.batch.value\n const o = order.value\n if (!o) return batch\n const seen = new Set(o)\n const rows: Row[] = []\n for (const k of o) {\n const r = store.rowByKey(k)\n if (r) rows.push(r)\n }\n for (const r of batch) if (!seen.has(store.keyOf(r))) rows.push(r)\n return rows\n})\n/** Gösterilen satırlar: sıra + görünüm + çıkarılanlar. */\nconst rowsAll = computed<Row[]>(() => {\n const all = view.value === 'all'\n const keys = viewKeys.value\n return orderedBatch.value.filter((r) => {\n const k = store.keyOf(r)\n return !store.isRemoved(k) && (all || keys.has(k))\n })\n})\nconst layout = useColumnLayout<Row>({\n columns: sheetColumns,\n rows: rowsAll,\n rowKey: () => props.rowKey,\n fixedStart,\n flexLastStart: true,\n})\nconst table = useSheetTable<Row>({\n rows: rowsAll,\n columnIds: () => layout.columns.value.map((c) => c.id),\n rowId: store.keyOf,\n})\nconst indexByKey = computed(() => {\n const m = new Map<string, number>()\n rowsAll.value.forEach((r, i) => m.set(store.keyOf(r), i))\n return m\n})\nconst visibleCols = computed(() => layout.columns.value)\n\nconst readOnlyNow = computed(() => loadingNow.value || savingNow.value || readOnlyDevice)\n\n// Editörler filtre değer girişleriyle aynı aileden (07 §5); `boolean` editör açmaz (Space). ajax/user/object/array için\n// yalnızca özel editör (`ColumnDef.editor`).\nconst EDITORS: Partial<Record<ColumnType, Component>> = {\n string: TextCell,\n text: TextCell,\n uppercase: TextCell,\n lowercase: TextCell,\n email: TextCell,\n url: TextCell,\n phone: TextCell,\n id: TextCell,\n color: TextCell,\n int: NumberCell,\n float: NumberCell,\n percentage: NumberCell,\n currency: NumberCell,\n star: NumberCell,\n select: OptionCell,\n multiselect: MultiCell,\n date: DateCell,\n datetime: DateCell,\n}\nconst editorFor = (def: ColumnDef<Row>): Component | null => def.editor ?? EDITORS[def.type] ?? null\n/** Sütunlar varsayılan salt okunur; anahtar sütun yüklenmiş satırlarda her zaman (yeni satırda açık); yüklenirken, kaydederken ve telefonda hiçbiri. */\nconst canEdit = (row: Row, def: ColumnDef<Row>): boolean => {\n if (readOnlyNow.value) return false\n const isNew = store.isNew(store.keyOf(row))\n if (def.id === props.keyColumn) return isNew\n if (def.type !== 'boolean' && !editorFor(def)) return false\n return typeof def.editable === 'function' ? def.editable(store.current(row), { isNew }) : def.editable === true\n}\n\nconst parseEnv = (locale = ctx.locale): ParseEnv => ({\n locale,\n today: new Date(),\n todayWord: i18n.t('date.today'),\n yesWord: i18n.t('common.yes'),\n noWord: i18n.t('common.no'),\n})\nconst edit = useSheetEditing<Row>({ store, canEdit, parse: (def, text) => parseInput(def, text, parseEnv()) })\nprovide(SHEET_EDITOR_KEY, { seed: () => edit.editing.value?.seed })\nconst grid = useTemplateRef<InstanceType<typeof SheetGrid>>('grid')\nconst counts = store.counts\nconst fmtEnv: FormatEnv = { fmt, i18n, today: new Date(), labels: new RemoteLabels() }\n\n/** Aralığı seçer ve odaklar (yapıştırma, doldurma, undo sonrası). */\nconst selectCells = (r1: number, c1: number, r2: number, c2: number) => {\n const rows = rowsAll.value\n const cols = visibleCols.value\n const a = rows[r1]\n const b = rows[r2]\n if (!a || !b || !cols[c1] || !cols[c2]) return\n table.selectRange({\n anchorRowId: store.keyOf(a),\n anchorColumnId: cols[c1]!.id,\n focusRowId: store.keyOf(b),\n focusColumnId: cols[c2]!.id,\n })\n grid.value?.focusActive()\n}\nconst focusCell = (r: number, columnId: string) => {\n const row = rowsAll.value[Math.max(0, Math.min(rowsAll.value.length - 1, r))]\n if (!row) return\n table.focus(store.keyOf(row), columnId)\n grid.value?.focusActive()\n}\n/** Seçimdeki (ya da aktif) hücreler. */\nconst selectedCells = (): Array<{ r: number; c: number }> => {\n const b = table.bounds.value\n if (!b) return []\n const out: Array<{ r: number; c: number }> = []\n for (let r = b.minRowIndex; r <= b.maxRowIndex; r++)\n for (let c = b.minColumnIndex; c <= b.maxColumnIndex; c++) out.push({ r, c })\n return out\n}\n\nconst toggle = (row: Row, def: ColumnDef<Row>) => store.set(row, def, !store.read(row, def))\n/** Delete / ⌘X: seçimdeki düzenlenebilir hücreler boşalır, tek adım. */\nconst clearSelected = () => {\n const changes: Array<Change<Row>> = []\n for (const { r, c } of selectedCells()) {\n const row = rowsAll.value[r]\n const def = visibleCols.value[c]?.def\n if (row && def && canEdit(row, def)) changes.push({ row, def, value: null })\n }\n store.apply(changes)\n}\n\n// Hatalar (07 §11, §14): gösterim sırasında; görünüm gizliyorsa toast \"Next error is hidden by filters · Show it\".\nconst errorKeysInOrder = computed(() => {\n void store.version.value\n return orderedBatch.value.map((r) => store.keyOf(r)).filter((k) => !store.isRemoved(k) && store.hasError(k))\n})\nconst goToError = (dir: 1 | -1) => {\n const rows = rowsAll.value\n const n = rows.length\n const a = table.active.value\n const from = a ? (indexByKey.value.get(a.rowId) ?? -1) : -1\n for (let s = 1; s <= n; s++) {\n const i = (((from + dir * s) % n) + n) % n\n const key = store.keyOf(rows[i]!)\n if (!store.hasError(key)) continue\n const issues = store.rowIssues(key)\n const col =\n visibleCols.value.find((c) => issues?.get(c.id)?.level === 'error') ??\n (store.rowError(key) ? visibleCols.value.find((c) => c.id === props.keyColumn) : undefined)\n if (!col) continue\n table.focus(key, col.id)\n grid.value?.focusActive()\n return\n }\n if (errorKeysInOrder.value.length && view.value !== 'all')\n showToast({\n text: i18n.t('sheet.nextErrorHidden'),\n action: {\n label: i18n.t('sheet.showIt'),\n run: () => {\n setView('all')\n goToError(dir)\n },\n },\n })\n}\n\n// Pano (07 §7): görüntülenen biçimde TSV + HTML; para kodu ve \"—\" yok, tarihler ISO, listeler `; ` ile (geri yapıştırılabilir).\nconst copyText = (def: ColumnDef<Row>, row: Row, value: unknown): string => plainText(def, row, value, fmtEnv)\nconst copyMatrix = (): string[][] | null => {\n const b = table.bounds.value\n if (!b) return null\n const out: string[][] = []\n for (let r = b.minRowIndex; r <= b.maxRowIndex; r++) {\n const row = rowsAll.value[r]\n if (!row) continue\n const line: string[] = []\n for (let c = b.minColumnIndex; c <= b.maxColumnIndex; c++) {\n const def = visibleCols.value[c]!.def\n line.push(copyText(def, row, store.read(row, def)))\n }\n out.push(line)\n }\n return out\n}\nconst copy = (data: DataTransfer | null): boolean => {\n const m = copyMatrix()\n if (!m || !data) return false\n data.setData('text/plain', toTsv(m))\n data.setData('text/html', toHtml(m))\n return true\n}\nconst cut = (data: DataTransfer | null): boolean => {\n if (!copy(data)) return false\n if (!readOnlyNow.value) clearSelected()\n return true\n}\n/** Hücre menüsü › Copy / Cut: `navigator.clipboard` (TSV + HTML; yalnızca metin destekleniyorsa TSV). */\nconst copyToClipboard = (cutAfter: boolean) => {\n const m = copyMatrix()\n const clip = typeof navigator !== 'undefined' ? navigator.clipboard : undefined\n if (!m || !clip) return\n const tsv = toTsv(m)\n const write =\n typeof ClipboardItem === 'function' && clip.write\n ? clip.write([\n new ClipboardItem({\n 'text/plain': new Blob([tsv], { type: 'text/plain' }),\n 'text/html': new Blob([toHtml(m)], { type: 'text/html' }),\n }),\n ])\n : clip.writeText(tsv)\n void write.catch(() => clip.writeText(tsv)).catch(() => {})\n if (cutAfter && !readOnlyNow.value) clearSelected()\n}\nconst pasteMatrix = (matrix: string[][]): boolean => {\n const a = table.active.value\n const width = Math.max(0, ...matrix.map((l) => l.length))\n if (!a || !matrix.length || !width || readOnlyNow.value) return false\n const cols = visibleCols.value\n const startRow = indexByKey.value.get(a.rowId)\n const startCol = cols.findIndex((c) => c.id === a.columnId)\n if (startRow === undefined || startCol < 0) return false\n const b = table.bounds.value\n const targets: Array<{ r: number; c: number; text: string }> = []\n if (\n matrix.length === 1 &&\n width === 1 &&\n b &&\n (b.maxRowIndex > b.minRowIndex || b.maxColumnIndex > b.minColumnIndex)\n ) {\n // Tek değer + aralık: değer tüm aralığa (07 §7).\n for (const { r, c } of selectedCells()) targets.push({ r, c, text: matrix[0]![0]! })\n } else {\n matrix.forEach((line, i) =>\n line.forEach((text, j) => {\n if (startCol + j < cols.length) targets.push({ r: startRow + i, c: startCol + j, text })\n }),\n )\n }\n const lastRow = Math.max(...targets.map((t) => t.r))\n const overflow = lastRow - rowsAll.value.length + 1\n if (overflow > 0 && store.allRows.value.length + overflow > props.maxRows) {\n showToast({\n text: i18n.t('sheet.limitPaste', {\n count: fmt.int(store.allRows.value.length + overflow),\n max: fmt.int(props.maxRows),\n }),\n })\n return true\n }\n // Son satırın altına taşanlar yeni satır olur; anahtar boşsa \"Required\" (07 §7).\n const addedRows = overflow > 0 ? store.addRows(overflow) : []\n if (addedRows.length && order.value) order.value = [...order.value, ...addedRows.map((x) => x.key)]\n const rows = rowsAll.value\n // Sayılar panonun yerel ayarıyla: sütun bazında çıkarım, belirsizse uygulama locale'i.\n const localeByCol = new Map<number, string>()\n for (const c of new Set(targets.map((t) => t.c))) {\n const def = cols[c]!.def\n if (!TYPE_SPECS[def.type].numeric) continue\n const dec = inferDecimal(targets.filter((t) => t.c === c).map((t) => t.text))\n localeByCol.set(c, dec === ',' ? 'de' : dec === '.' ? 'en' : ctx.locale)\n }\n const changes: Array<Change<Row>> = []\n for (const t of targets) {\n const row = rows[t.r]\n const def = cols[t.c]?.def\n if (!row || !def || !canEdit(row, def)) continue\n changes.push({ row, def, value: parseInput(def, t.text, parseEnv(localeByCol.get(t.c))) })\n }\n store.apply(changes, addedRows)\n const minR = Math.min(...targets.map((t) => t.r))\n const minC = Math.min(...targets.map((t) => t.c))\n const maxC = Math.max(...targets.map((t) => t.c))\n selectCells(minR, minC, lastRow, maxC)\n // Toast: seçenek olmayan değerler (\"2 values aren't options\") ve diğer hatalar ayrı sayılır; Review ilk sorunlu hücre.\n const issues = targets\n .map((t) => {\n const row = rows[t.r]\n const issue = row && store.rowIssues(store.keyOf(row))?.get(cols[t.c]!.id)\n return issue?.level === 'error'\n ? { ...t, option: cols[t.c]!.def.type === 'select' || cols[t.c]!.def.type === 'multiselect' }\n : null\n })\n .filter((x): x is NonNullable<typeof x> => x !== null)\n const options = issues.filter((i) => i.option).length\n const others = issues.length - options\n const dims = { rows: lastRow - minR + 1, cols: maxC - minC + 1 }\n const first = issues[0]\n showToast({\n text: i18n.t('sheet.pasted', { rows: fmt.int(dims.rows), cols: fmt.int(dims.cols) }),\n issues:\n [\n options ? i18n.t('sheet.pasteIssues', { count: options }) : '',\n others ? i18n.t('sheet.pasteErrors', { count: others }) : '',\n ]\n .filter(Boolean)\n .join(' · ') || undefined,\n review: first ? () => selectCells(first.r, first.c, first.r, first.c) : undefined,\n undo: true,\n })\n polite.value = i18n.t('sr.pasted', dims)\n return true\n}\nconst paste = (data: DataTransfer | null): boolean => pasteMatrix(matrixFromClipboard(data))\n/** Hücre menüsü › Paste: `readText` yedeği (07 §7). */\nconst pasteFromClipboard = () => {\n void navigator.clipboard\n ?.readText()\n .then((text) => pasteMatrix(parseTsv(text)))\n .catch(() => {})\n}\n\n// Doldurma (07 §8): kaynak satır aralığı, hedef satıra kadar; seri ya da kopya, read-only atlanır, tek adım.\nconst fillPlan = (fromRow: number, toRow: number, cols: [number, number], target: number) => {\n const rows = rowsAll.value\n const up = target < fromRow\n const count = up ? fromRow - target : target - toRow\n const changes: Array<Change<Row>> = []\n for (let c = cols[0]; c <= cols[1]; c++) {\n const def = visibleCols.value[c]?.def\n if (!def) continue\n const source = rows.slice(fromRow, toRow + 1).map((r) => store.read(r, def))\n const values = fillValues(source, count, up)\n for (let k = 0; k < count; k++) {\n const row = rows[up ? fromRow - 1 - k : toRow + 1 + k]\n if (row && canEdit(row, def)) changes.push({ row, def, value: values[k] })\n }\n }\n return { changes, count }\n}\nconst fill = (fromRow: number, toRow: number, cols: [number, number], target: number) => {\n const { changes } = fillPlan(fromRow, toRow, cols, target)\n store.apply(changes)\n selectCells(Math.min(fromRow, target), cols[0], Math.max(toRow, target), cols[1])\n}\nconst fillLabel = (fromRow: number, toRow: number, cols: [number, number], target: number): string => {\n const { changes, count } = fillPlan(fromRow, toRow, cols, target)\n const first = changes[0]\n const value = first ? formatCell(first.def, first.row, first.value, fmtEnv) : ''\n return i18n.t('sheet.fillPreview', { count: count * (cols[1] - cols[0] + 1), value })\n}\nconst fillDown = () => {\n const b = table.bounds.value\n if (!b || b.maxRowIndex === b.minRowIndex) return\n fill(b.minRowIndex, b.minRowIndex, [b.minColumnIndex, b.maxColumnIndex], b.maxRowIndex)\n}\n\n// Geri al / yinele (07 §12): seçim ve aktif hücre o adımın yerine taşınır.\nconst afterStep = (step: Step | null) => {\n if (!step) return\n // Listeden çıkarma geri alındı: geri gelen satıra odak (toast'taki Undo odağı ızgaradan almıştı).\n if (step.removed?.length && !step.patches.length) {\n const i = indexByKey.value.get(step.removed[0]!)\n if (i !== undefined) focusCell(i, table.active.value?.columnId ?? visibleCols.value[0]!.id)\n return\n }\n if (!step.patches.length) return\n const idx = visibleCols.value.map((c) => c.id)\n let r1 = Infinity\n let r2 = -1\n let c1 = Infinity\n let c2 = -1\n for (const p of step.patches) {\n const r = indexByKey.value.get(p.key)\n const c = idx.indexOf(p.col)\n if (r === undefined || c < 0) continue\n r1 = Math.min(r1, r)\n r2 = Math.max(r2, r)\n c1 = Math.min(c1, c)\n c2 = Math.max(c2, c)\n }\n if (r2 >= 0) selectCells(r1, c1, r2, c2)\n}\nconst undo = () => {\n if (readOnlyNow.value) return\n edit.cancel()\n afterStep(store.undo())\n}\nconst redo = () => {\n if (readOnlyNow.value) return\n edit.cancel()\n afterStep(store.redo())\n}\nconst useSuggestion = (row: Row, def: ColumnDef<Row>, value: unknown) => store.set(row, def, value)\n\n// Satır partisi (07 §9, D12): Add row / Insert row above-below (newRowDefaults, odak anahtar hücresinde, düzenleme açık);\n// Remove from list (⌘−): nötr, sunucuda silmez, toast + Undo.\nconst addRow = (at?: number) => {\n if (readOnlyNow.value) return\n if (store.allRows.value.length + 1 > props.maxRows) {\n showToast({\n text: i18n.t('sheet.limitPaste', { count: fmt.int(store.allRows.value.length + 1), max: fmt.int(props.maxRows) }),\n })\n return\n }\n edit.commit()\n const [added] = store.addRows(1)\n if (!added) return\n const defaults = props.newRowDefaults?.() ?? {}\n const changes: Array<Change<Row>> = []\n for (const [id, value] of Object.entries(defaults)) {\n const def = defById.value.get(id)\n if (def && !isEmptyValue(value)) changes.push({ row: added.row, def, value })\n }\n store.apply(changes, [added])\n if (at !== undefined) {\n const keys = order.value ?? store.batch.value.map((r) => store.keyOf(r)).filter((k) => k !== added.key)\n const pos = Math.max(0, Math.min(keys.length, at))\n order.value = [...keys.slice(0, pos), added.key, ...keys.slice(pos)]\n } else if (order.value) order.value = [...order.value, added.key]\n if (view.value !== 'all') viewKeys.value = new Set([...viewKeys.value, added.key])\n table.focus(added.key, props.keyColumn)\n // Yeni satır görünür alana kayar (sona eklenince 5.000 satır aşağıda olabilir); sanal liste yeni sayıyı bir sonraki\n // render'da öğrendiğinden nextTick. focusActive editör açıkken kaydırmaz.\n void nextTick(() => grid.value?.scrollToIndex(rowsAll.value.findIndex((r) => store.keyOf(r) === added.key)))\n grid.value?.focusActive()\n if (keyDef.value) edit.start(added.row, keyDef.value, { inCell: true })\n}\nconst insertRow = (where: 'above' | 'below') => {\n const a = table.active.value\n const i = a ? orderedBatch.value.findIndex((r) => store.keyOf(r) === a.rowId) : -1\n addRow(i < 0 ? undefined : where === 'above' ? i : i + 1)\n}\nconst removeSelectedRows = () => {\n if (readOnlyNow.value) return\n const b = table.bounds.value\n if (!b) return\n edit.cancel()\n const rows = rowsAll.value.slice(b.minRowIndex, b.maxRowIndex + 1)\n const keys = rows.map((r) => store.keyOf(r))\n if (!keys.length) return\n store.removeRows(keys)\n showToast({\n text:\n keys.length === 1\n ? i18n.t('sheet.removed', { count: 1, row: store.rowNoOf(keys[0]!), entity: entity.value })\n : i18n.t('sheet.removed', { count: keys.length, entity: entity.value }),\n undo: true,\n })\n focusCell(b.minRowIndex, table.active.value?.columnId ?? visibleCols.value[0]!.id)\n}\n\n// Yerel sıralama (07 §10): asc → desc → kapalı, ⇧ ile ikincil (en fazla 3); anlık görüntü, gutter numaraları değişmez.\nconst sort = (columnId: string, additive: boolean) => {\n const def = defById.value.get(columnId)\n if (!def || !(def.sortable ?? TYPE_SPECS[def.type].sortable)) return\n const current = sortRules.value\n const existing = current.find((s) => s.column === columnId)\n const next: SortRule | null = !existing\n ? { column: columnId, dir: 'asc' }\n : existing.dir === 'asc'\n ? { column: columnId, dir: 'desc' }\n : null\n const rest = current.filter((s) => s.column !== columnId)\n sortRules.value = additive\n ? next\n ? existing\n ? current.map((s) => (s.column === columnId ? next : s))\n : [...rest, next].slice(-3)\n : rest\n : next\n ? [next]\n : []\n if (!sortRules.value.length) {\n order.value = null\n return\n }\n const cmps = sortRules.value.map((s) => ({\n def: defById.value.get(s.column)!,\n cmp: comparator(defById.value.get(s.column)!, ctx.locale),\n sign: s.dir === 'desc' ? -1 : 1,\n }))\n order.value = [...store.batch.value]\n .sort((a, b) => {\n for (const { def: d, cmp, sign } of cmps) {\n const r = cmp(store.read(a, d), store.read(b, d)) * sign\n if (r) return r\n }\n return store.rowNoOf(store.keyOf(a)) - store.rowNoOf(store.keyOf(b))\n })\n .map((r) => store.keyOf(r))\n}\nconst sortMap = computed(() => {\n const m = new Map<string, { dir: 'asc' | 'desc'; index: number | null }>()\n sortRules.value.forEach((s, i) => m.set(s.column, { dir: s.dir, index: sortRules.value.length > 1 ? i + 1 : null }))\n return m\n})\n\n// Kayıt akışı (07 §14): hatalı satır varsa dialog; `@save` yükü; uygulama `saving` verir; `applyResult` sonuçları işler;\n// bitişte status bar sonucu ya da Partly saved şeridi (görünüm Errors, aktif hücre ilk hatada).\nconst errorDialogOpen = ref(false)\nconst errorItems = computed<ErrorRowItem[]>(() =>\n errorKeysInOrder.value\n .filter((k) => !!store.rowDraft(k)?.size || store.isNew(k))\n .map((k) => {\n const row = store.rowByKey(k)!\n const issues = store.rowIssues(k)\n const first = issues ? [...issues.values()].find((i) => i.level === 'error') : undefined\n return {\n rowNo: store.rowNoOf(k),\n key: keyDef.value ? inputText(keyDef.value, store.read(row, keyDef.value)) : k,\n message: first?.message ?? store.rowError(k) ?? '',\n }\n }),\n)\nconst saveTotals = shallowRef({ created: 0, updated: 0, errors: 0 })\nconst savedSummary = shallowRef<{ count: number; created: number; updated: number } | null>(null)\nconst partly = shallowRef<{ failed: number; saved: number } | null>(null)\nconst emitSave = () => {\n saveTotals.value = { created: 0, updated: 0, errors: 0 }\n savedSummary.value = null\n partly.value = null\n emit('save', store.getChanges())\n}\nconst save = () => {\n if (readOnlyNow.value) return\n edit.commit()\n if (!counts.value.changedCells && !counts.value.newRows) return\n if (errorItems.value.length) {\n errorDialogOpen.value = true\n return\n }\n emitSave()\n}\nconst fixFirst = () => {\n setView('errors')\n goToError(1)\n}\nconst finishSave = () => {\n const t = saveTotals.value\n if (!t.created && !t.updated && !t.errors) return\n if (t.errors) {\n partly.value = { failed: t.errors, saved: t.created + t.updated }\n assertive.value = i18n.t('sheet.partly.title', { count: fmt.int(t.errors) })\n setView('errors')\n goToError(1)\n } else {\n savedSummary.value = { count: t.created + t.updated, created: t.created, updated: t.updated }\n polite.value = i18n.t('sheet.saved', { count: fmt.int(t.created + t.updated) })\n }\n saveTotals.value = { created: 0, updated: 0, errors: 0 }\n}\nlet resultVersion = -1\nconst applyResult = (results: Array<SheetRowResult<Row>>) => {\n const r = store.applyResult(results)\n resultVersion = store.version.value\n const t = saveTotals.value\n saveTotals.value = { created: t.created + r.created, updated: t.updated + r.updated, errors: t.errors + r.errors }\n if (!savingNow.value) finishSave()\n}\nwatch(savingNow, (now) => {\n if (!now) finishSave()\n})\n// Sonraki düzenlemede sonuç metni gider (applyResult'ın kendi sürüm artışı sayılmaz); hata kalmayınca şerit kapanır.\nwatch(store.version, (v) => {\n if (v !== resultVersion) savedSummary.value = null\n if (partly.value && !counts.value.errorRows) partly.value = null\n})\nconst partlyIndex = computed(() => {\n const a = table.active.value\n const i = a ? errorKeysInOrder.value.indexOf(a.rowId) : -1\n return i < 0 ? 0 : i + 1\n})\n/** Copy errors (07 §14): TSV, başlık Row · anahtar sütunu · Column · Message. */\nconst copyErrors = () => {\n const lines: string[][] = [\n [\n i18n.t('sheet.err.row'),\n keyDef.value?.header ?? props.keyColumn,\n i18n.t('sheet.err.column'),\n i18n.t('sheet.err.message'),\n ],\n ]\n for (const k of errorKeysInOrder.value) {\n const row = store.rowByKey(k)!\n const keyText = keyDef.value ? inputText(keyDef.value, store.read(row, keyDef.value)) : k\n const rowErr = store.rowError(k)\n if (rowErr) lines.push([String(store.rowNoOf(k)), keyText, '', rowErr])\n for (const [col, issue] of store.rowIssues(k) ?? [])\n if (issue.level === 'error')\n lines.push([String(store.rowNoOf(k)), keyText, defById.value.get(col)?.header ?? col, issue.message])\n }\n void navigator.clipboard?.writeText(toTsv(lines)).catch(() => {})\n}\nconst openHref = (row: Row): string | undefined => {\n if (store.isNew(store.keyOf(row))) return undefined\n return keyDef.value?.href?.(row) ?? primaryDef.value?.href?.(row)\n}\n\n// Import (07 §13): listede olan anahtar o satırı günceller, olmayan (Add … checkbox'ı açıksa) satır olarak eklenir; tek undo adımı.\nconst importOpen = ref(false)\nconst keyIndexSet = computed(() => {\n void store.version.value\n const set = new Set<string>()\n const def = keyDef.value\n if (!def) return set\n for (const r of store.allRows.value) {\n const v = store.readUntracked(r, def)\n if (!isEmptyValue(v)) set.add(String(v))\n }\n return set\n})\nconst inList = (key: string) => keyIndexSet.value.has(key)\nconst applyImport = (payload: ImportPayload) => {\n if (readOnlyNow.value || !keyDef.value) return\n edit.commit()\n const def = keyDef.value\n const byKeyValue = new Map<string, Row>()\n for (const r of store.allRows.value) {\n const v = store.readUntracked(r, def)\n if (!isEmptyValue(v)) byKeyValue.set(String(v), r)\n }\n // Yeni satırlar önce sayılır ve tek `addRows` çağrısıyla eklenir: satır satır eklemek her seferinde tüm partiyi\n // yeniden doğruluyordu (10k'da karesel). Sınır başlangıçtaki satır sayısına göre (eklenen satır iki kez sayılmaz).\n const start = store.allRows.value.length\n const need = new Set<string>()\n for (const item of payload.rows) {\n if (byKeyValue.has(item.key) || need.has(item.key)) continue\n if (!payload.addNew) continue\n if (start + need.size + 1 > props.maxRows) break\n need.add(item.key)\n }\n const fresh = need.size ? store.addRows(need.size) : []\n const freshByKey = new Map([...need].map((k, i) => [k, fresh[i]!]))\n const changes: Array<Change<Row>> = []\n const addedRows: Array<{ key: string; row: Row }> = []\n let updated = 0\n let news = 0\n for (const item of payload.rows) {\n let row = byKeyValue.get(item.key)\n if (!row) {\n if (!payload.addNew) continue\n const a = freshByKey.get(item.key)\n if (!a) break // sınır\n row = a.row\n addedRows.push(a)\n byKeyValue.set(item.key, row)\n changes.push({ row, def, value: item.key })\n news++\n } else updated++\n for (const [id, value] of Object.entries(item.values)) {\n const d = defById.value.get(id)\n if (d && canEdit(row, d)) changes.push({ row, def: d, value })\n }\n }\n store.apply(changes, addedRows)\n if (addedRows.length && order.value) order.value = [...order.value, ...addedRows.map((a) => a.key)]\n showToast({\n text: i18n.t('import.done', {\n count: fmt.int(payload.rows.length),\n updated: fmt.int(updated),\n news: fmt.int(news),\n }),\n undo: true,\n })\n // Odak ızgaraya, ilk alınan satırın anahtar hücresine (dialog kapanınca odak Import düğmesine dönerdi).\n const firstKey = payload.rows[0]?.key\n const firstRow = firstKey ? byKeyValue.get(firstKey) : undefined\n const i = firstRow ? indexByKey.value.get(store.keyOf(firstRow)) : undefined\n if (i !== undefined) focusCell(i, props.keyColumn)\n}\n/** Export (07 §2): All / Visible › CSV / Excel; değerler güncel (taslak uygulanmış). `@export` yoksa dosyayı paket yazar (D46). */\nconst exportRows = (format: 'csv' | 'xlsx', scope: 'all' | 'visible') => {\n edit.commit()\n const rows = (scope === 'all' ? store.allRows.value : rowsAll.value).map((r) => store.current(r))\n if (listensExport) return emit('export', { format, scope, columns: visibleCols.value.map((c) => c.id), rows })\n void exportFile({\n format,\n columns: visibleCols.value.map((c) => c.def),\n rows,\n read: (row, def) => (def.accessor ? def.accessor(row) : readPath(row, def.id as string)),\n env: fmtEnv,\n name: entity.value.other,\n })\n}\nconst exportLabel = (scope: 'all' | 'visible') =>\n i18n.t(scope === 'all' ? 'sheet.exportAll' : 'sheet.exportVisible', {\n count: fmt.int(scope === 'all' ? store.allRows.value.length : rowsAll.value.length),\n })\nconst copyLink = () => void navigator.clipboard?.writeText(location.href).catch(() => {})\n\nconst sheet: SheetApi<Row> = {\n store,\n table,\n edit,\n canEdit,\n editorFor,\n toggle,\n clearCells: clearSelected,\n save,\n goToError,\n copy,\n cut,\n paste,\n fill,\n fillLabel,\n fillDown,\n undo,\n redo,\n useSuggestion,\n copyToClipboard,\n pasteFromClipboard,\n insertRow,\n removeSelectedRows,\n sort,\n openHref,\n}\n\n// Izgara dışına tık onaylar (07 §5): formül çubuğu ve portallı editör katmanları (`dt-sheet-layer`) dışarı sayılmaz.\nconst onDocPointerdown = (e: PointerEvent) => {\n if (!edit.editing.value) return\n const t = e.target as Element | null\n if (t?.closest('.dt-cell.is-editing, .dt-formula, .dt-sheet-layer')) return\n edit.commit()\n}\n// Ayrılma koruması (07 §14): değişiklik varken tarayıcı uyarısı; yönlendirici dialog'u uygulamanın (`isDirty()`).\nconst isDirty = () => counts.value.changedCells > 0 || counts.value.newRows > 0\nconst onBeforeUnload = (e: BeforeUnloadEvent) => {\n if (!isDirty()) return\n e.preventDefault()\n e.returnValue = ''\n}\nonMounted(() => {\n document.addEventListener('pointerdown', onDocPointerdown, true)\n window.addEventListener('beforeunload', onBeforeUnload)\n})\nonBeforeUnmount(() => {\n document.removeEventListener('pointerdown', onDocPointerdown, true)\n window.removeEventListener('beforeunload', onBeforeUnload)\n clearTimeout(toastTimer)\n})\n\n// ⌘S / ⌘F odak sheet içindeyken (07 §2); ızgara kendi işlediyse (defaultPrevented) tekrar etmez.\nconst findBox = useTemplateRef<InstanceType<typeof SearchBox>>('findBox')\nconst onRootKeydown = (e: KeyboardEvent) => {\n if (e.defaultPrevented || !(e.metaKey || e.ctrlKey)) return\n const k = e.key.toLowerCase()\n if (k === 's') {\n e.preventDefault()\n save()\n } else if (k === 'f' && !loadingNow.value) {\n e.preventDefault()\n findBox.value?.focus()\n }\n}\n\n// Find in grid (07 §2): görünür sütunlarda görüntülenen metin; eşleşmeler vurgulanır, satır gizlenmez; Enter / ⇧Enter gezer.\nconst fold = (s: string) => s.toLocaleLowerCase(ctx.locale)\nconst findText = ref('')\nconst findIndex = ref(0)\nconst matches = computed(() => {\n const q = fold(findText.value.trim())\n if (!q) return null\n void store.version.value\n const map = new Map<string, Set<string>>()\n const list: Array<{ r: number; c: number }> = []\n const rows = rowsAll.value\n const cols = visibleCols.value\n for (let r = 0; r < rows.length; r++) {\n const row = rows[r]!\n for (let c = 0; c < cols.length; c++) {\n const def = cols[c]!.def\n const v = store.readUntracked(row, def)\n if (isEmptyValue(v) || !fold(formatCell(def, row, v, fmtEnv)).includes(q)) continue\n const key = store.keyOf(row)\n let set = map.get(key)\n if (!set) map.set(key, (set = new Set()))\n set.add(def.id as string)\n list.push({ r, c })\n }\n }\n return { map, list }\n})\nconst goToMatch = (i: number) => {\n const m = matches.value?.list[i]\n if (!m) return\n findIndex.value = i\n const row = rowsAll.value[m.r]!\n table.focus(store.keyOf(row), visibleCols.value[m.c]!.id)\n grid.value?.scrollToIndex(m.r)\n}\nwatch(\n () => matches.value?.list.length ?? 0,\n () => goToMatch(0),\n)\nconst findStep = (dir: 1 | -1) => {\n const n = matches.value?.list.length ?? 0\n if (n) goToMatch((((findIndex.value + dir) % n) + n) % n)\n}\nconst onFindKeydown = (e: KeyboardEvent) => {\n if (e.key === 'Enter') {\n e.preventDefault()\n findStep(e.shiftKey ? -1 : 1)\n } else if (e.key === 'Escape' && !findText.value) {\n e.preventDefault()\n grid.value?.focusActive()\n }\n}\nconst findCount = computed(() =>\n matches.value\n ? i18n.t('sheet.findCount', {\n index: matches.value.list.length ? findIndex.value + 1 : 0,\n total: matches.value.list.length,\n })\n : '',\n)\n\n// All / Changed / Errors sayaçları (07 §11).\nconst viewCounts = computed(() => ({\n all: store.allRows.value.length,\n changed: counts.value.changedOrNewRows,\n errors: counts.value.errorRows,\n}))\n\n// Formül çubuğu (07 §2): ad kutusu, fx, değer (buraya yazmak hücreyi düzenler), ipucu.\nconst activeRow = computed(() => {\n const a = table.active.value\n return a ? (store.rowByKey(a.rowId) ?? null) : null\n})\nconst activeDef = computed(() => {\n const a = table.active.value\n return a ? (defById.value.get(a.columnId) ?? null) : null\n})\nconst rangeDims = computed(() => {\n const b = table.bounds.value\n if (!b) return null\n const rows = b.maxRowIndex - b.minRowIndex + 1\n const cols = b.maxColumnIndex - b.minColumnIndex + 1\n return rows * cols > 1 ? { rows, cols } : null\n})\nconst rangeText = computed(() => (rangeDims.value ? i18n.t('sheet.cells', rangeDims.value) : null))\nconst nameKey = computed(() =>\n activeRow.value && keyDef.value ? inputText(keyDef.value, store.read(activeRow.value, keyDef.value)) : '',\n)\nconst formulaText = computed(() => {\n const e = edit.editing.value\n if (e) return e.text ?? inputText(e.def, e.value)\n return activeRow.value && activeDef.value\n ? inputText(activeDef.value, store.read(activeRow.value, activeDef.value))\n : ''\n})\nconst formulaEditable = computed(\n () =>\n !!activeRow.value &&\n !!activeDef.value &&\n activeDef.value.type !== 'boolean' &&\n canEdit(activeRow.value, activeDef.value),\n)\nconst onFormulaInput = (e: Event) => {\n const text = (e.target as HTMLInputElement).value\n const row = activeRow.value\n const def = activeDef.value\n if (!row || !def || !formulaEditable.value) return\n if (!edit.editing.value && !edit.start(row, def, { inCell: false })) return\n edit.setValue(parseInput(def, text, parseEnv()), text, false)\n}\nconst onFormulaKeydown = (e: KeyboardEvent) => {\n if (e.key === 'Enter') {\n e.preventDefault()\n if (edit.commit()) table.move('down')\n grid.value?.focusActive()\n } else if (e.key === 'Escape') {\n e.preventDefault()\n edit.cancel()\n grid.value?.focusActive()\n }\n}\nconst hint = computed(() => {\n const d = activeDef.value\n if (!d) return ''\n const parts = [i18n.t(typeLabelKey(d.type))]\n if (d.type === 'currency' && typeof d.currency === 'string') parts.push(d.currency)\n if (d.required) parts.push(i18n.t('sheet.required').toLocaleLowerCase(ctx.locale))\n if (d.hint) parts.push(d.hint)\n return parts.join(' · ')\n})\nconst valueAria = computed(() =>\n activeDef.value ? i18n.t('sheet.valueAria', { column: activeDef.value.header, key: nameKey.value }) : '',\n)\n\n// Status bar seçim özeti (07 §2): Count = boş olmayan; Sum / Average yalnızca sayısal hücre varsa; tek hücrede gizli.\nconst summary = computed(() => {\n void store.version.value\n const b = table.bounds.value\n if (!b || !rangeDims.value) return null\n let count = 0\n let sum = 0\n let numeric = 0\n for (let r = b.minRowIndex; r <= b.maxRowIndex; r++) {\n const row = rowsAll.value[r]\n if (!row) continue\n for (let c = b.minColumnIndex; c <= b.maxColumnIndex; c++) {\n const def = visibleCols.value[c]!.def\n const v = store.readUntracked(row, def)\n if (isEmptyValue(v)) continue\n count++\n if (TYPE_SPECS[def.type].numeric && typeof v === 'number') {\n sum += v\n numeric++\n }\n }\n }\n return { count, sum: numeric ? fmt.decimal(sum, 2) : null, avg: numeric ? fmt.decimal(sum / numeric, 2) : null }\n})\n\nconst status = computed<SheetStatus>(() => ({\n phase: loadingNow.value\n ? 'loading'\n : savingNow.value\n ? 'saving'\n : partly.value\n ? 'partly-saved'\n : savedSummary.value\n ? 'saved'\n : 'ready',\n ...counts.value,\n}))\nconst changesText = computed(() =>\n counts.value.changedCells\n ? i18n.t('sheet.changes', { cells: fmt.int(counts.value.changedCells), rows: fmt.int(counts.value.changedRows) })\n : i18n.t('sheet.noChanges'),\n)\nconst saveTip = `${i18n.t('sheet.save')} · ${SAVE_KBD}`\nconst undoTip = `${i18n.t('common.undo')} (${UNDO_KBD})`\nconst redoTip = `${i18n.t('common.redo')} (${REDO_KBD})`\nconst canSave = computed(() => !readOnlyNow.value && (counts.value.changedCells > 0 || counts.value.newRows > 0))\n\n// Toast (06 §8): yapıştırma sonucu, sınır uyarısı, listeden çıkarma, gizli hata; Review / Show it / Undo.\ninterface Toast {\n text: string\n issues?: string\n review?: () => void\n action?: { label: string; run: () => void }\n undo?: boolean\n}\nconst toast = shallowRef<Toast | null>(null)\nlet toastTimer: ReturnType<typeof setTimeout> | undefined\nconst showToast = (t: Toast) => {\n toast.value = t\n clearTimeout(toastTimer)\n toastTimer = setTimeout(() => (toast.value = null), 6000)\n}\nconst toastUndo = () => {\n toast.value = null\n undo()\n}\nconst toastAction = () => {\n const run = toast.value?.action?.run\n toast.value = null\n run?.()\n}\nconst polite = ref('')\nconst assertive = ref('')\n// Yükleme / kayıt ilerlemesi her %25'te duyurulur (08 §5).\nlet announcedQuarter = -1\nwatch(percent, (p) => {\n if (p === null) {\n announcedQuarter = -1\n return\n }\n const q = Math.floor(p / 25)\n if (q === announcedQuarter || p === 0) return\n announcedQuarter = q\n polite.value = i18n.t(loadingNow.value ? 'sr.loadingPercent' : 'sr.savingPercent', { percent: q * 25 })\n})\n\nconst discardOpen = ref(false)\nconst discard = () => {\n edit.cancel()\n store.reset()\n order.value = null\n sortRules.value = []\n partly.value = null\n savedSummary.value = null\n grid.value?.focusActive()\n}\n\nconst displayProps = computed(() => ({\n density: density.value,\n verticalLines: pref.prefs.verticalLines,\n columns: layout.panel.value,\n counts: layout.counts.value,\n persistent: pref.persistent,\n}))\nconst displayOn = {\n 'update:density': (d: Density) => pref.set({ density: d }),\n 'update:verticalLines': (on: boolean) => pref.set({ verticalLines: on }),\n 'columns-save': (d: ColumnsDraft) => layout.arrange(d),\n // Display › Reset: tercihler + sütun düzeni tanımlara (sheet'te görünüm yok).\n reset: () => {\n pref.reset()\n layout.reset()\n },\n}\n\nconst rootEl = ref<HTMLElement | null>(null)\nconst tooltip = useDelegatedTooltip(rootEl)\n\ndefineExpose({\n status,\n isDirty,\n getChanges: store.getChanges,\n applyResult,\n reset: discard,\n undo,\n redo,\n goToNextError: () => goToError(1),\n})\n</script>\n\n<template>\n <div\n ref=\"rootEl\"\n class=\"dt dt-sheet\"\n :class=\"{ 'is-phone': readOnlyDevice }\"\n :data-density=\"density\"\n @keydown=\"onRootKeydown\"\n >\n <div v-if=\"readOnlyDevice\" class=\"dt-sheet-readonly\" role=\"note\">\n <PhMonitor :size=\"20\" aria-hidden=\"true\" />\n <div class=\"dt-sheet-readonly-text\">\n <strong>{{ i18n.t('sheet.readOnly.title') }}</strong>\n <span>{{ i18n.t('sheet.readOnly.body', { entity }) }}</span>\n <button type=\"button\" class=\"dt-btn has-icon\" @click=\"copyLink\">\n <PhLink :size=\"16\" aria-hidden=\"true\" />\n {{ i18n.t('common.copyLink') }}\n </button>\n </div>\n </div>\n <div class=\"dt-toolbar dt-sheet-toolbar\" role=\"toolbar\">\n <div v-if=\"loadingNow || savingNow\" class=\"dt-progress-strip\">\n <strong>\n {{\n loadingNow\n ? i18n.t('sheet.loading', { entity })\n : progress\n ? i18n.t('sheet.saving', { sent: fmt.int(progress.done), total: fmt.int(progress.total) })\n : i18n.t('sheet.savingIndeterminate')\n }}\n </strong>\n <span v-if=\"loadingNow && progress\" class=\"dt-progress-count\">\n {{ i18n.t('sheet.loadingCount', { loaded: fmt.int(progress.done), total: fmt.int(progress.total) }) }}\n </span>\n <div\n class=\"dt-progress\"\n :class=\"{ 'is-indeterminate': percent === null }\"\n role=\"progressbar\"\n aria-valuemin=\"0\"\n aria-valuemax=\"100\"\n :aria-valuenow=\"percent ?? undefined\"\n >\n <div class=\"dt-progress-fill\" :style=\"percent !== null ? { width: `${percent}%` } : undefined\" />\n </div>\n </div>\n <div v-else-if=\"readOnlyDevice\" class=\"dt-find\" @keydown=\"onFindKeydown\">\n <SearchBox\n ref=\"findBox\"\n :model-value=\"findText\"\n :placeholder=\"i18n.t('sheet.find')\"\n :kbd=\"FIND_KBD\"\n @update:model-value=\"(v) => (findText = v)\"\n />\n <span v-if=\"findCount\" class=\"dt-find-count\" role=\"status\">{{ findCount }}</span>\n </div>\n <template v-else>\n <div class=\"dt-find\" @keydown=\"onFindKeydown\">\n <SearchBox\n ref=\"findBox\"\n :model-value=\"findText\"\n :placeholder=\"i18n.t('sheet.find')\"\n :kbd=\"FIND_KBD\"\n @update:model-value=\"(v) => (findText = v)\"\n />\n <span v-if=\"findCount\" class=\"dt-find-count\" role=\"status\">{{ findCount }}</span>\n </div>\n <span class=\"dt-toolbar-sep\" aria-hidden=\"true\" />\n <ToggleGroupRoot\n class=\"dt-seg dt-sheet-views\"\n type=\"single\"\n :model-value=\"view\"\n :aria-label=\"i18n.t('sheet.showRows')\"\n @update:model-value=\"(v) => v && setView(v as SheetFilterMode)\"\n >\n <ToggleGroupItem class=\"dt-seg-item\" value=\"all\">\n {{ i18n.t('sheet.all') }}\n <span class=\"dt-seg-count\">{{ fmt.int(viewCounts.all) }}</span>\n </ToggleGroupItem>\n <ToggleGroupItem class=\"dt-seg-item\" value=\"changed\">\n {{ i18n.t('sheet.changed') }}\n <span class=\"dt-seg-count\">{{ fmt.int(viewCounts.changed) }}</span>\n </ToggleGroupItem>\n <ToggleGroupItem class=\"dt-seg-item\" :class=\"{ 'is-errors': viewCounts.errors > 0 }\" value=\"errors\">\n {{ i18n.t('sheet.errors') }}\n <span class=\"dt-seg-count\">{{ fmt.int(viewCounts.errors) }}</span>\n </ToggleGroupItem>\n </ToggleGroupRoot>\n <button\n type=\"button\"\n class=\"dt-btn dt-sheet-undo\"\n :aria-disabled=\"store.canUndo.value ? undefined : 'true'\"\n :aria-label=\"undoTip\"\n :data-dt-tip=\"undoTip\"\n @click=\"store.canUndo.value && undo()\"\n >\n <PhArrowUUpLeft :size=\"16\" aria-hidden=\"true\" />\n </button>\n <button\n type=\"button\"\n class=\"dt-btn dt-sheet-undo\"\n :aria-disabled=\"store.canRedo.value ? undefined : 'true'\"\n :aria-label=\"redoTip\"\n :data-dt-tip=\"redoTip\"\n @click=\"store.canRedo.value && redo()\"\n >\n <PhArrowUUpRight :size=\"16\" aria-hidden=\"true\" />\n </button>\n <span class=\"dt-toolbar-sep\" aria-hidden=\"true\" />\n <button type=\"button\" class=\"dt-btn dt-btn-ghost has-icon dt-sheet-add\" @click=\"addRow()\">\n <PhPlus :size=\"16\" aria-hidden=\"true\" />\n {{ i18n.t('sheet.addRow') }}\n </button>\n <button\n v-if=\"importable\"\n type=\"button\"\n class=\"dt-btn dt-btn-ghost has-icon dt-sheet-import\"\n @click=\"importOpen = true\"\n >\n <PhDownloadSimple :size=\"16\" aria-hidden=\"true\" />\n {{ i18n.t('sheet.import') }}\n </button>\n <DropdownMenuRoot v-if=\"exportable\">\n <DropdownMenuTrigger as-child>\n <button type=\"button\" class=\"dt-btn dt-btn-ghost has-icon dt-sheet-export\">\n <PhExport :size=\"16\" aria-hidden=\"true\" />\n {{ i18n.t('sheet.export') }}\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuPortal>\n <DropdownMenuContent class=\"dt-menu\" align=\"start\" :side-offset=\"4\">\n <DropdownMenuSub v-for=\"scope in ['all', 'visible'] as const\" :key=\"scope\">\n <DropdownMenuSubTrigger class=\"dt-menu-item\">{{ exportLabel(scope) }}</DropdownMenuSubTrigger>\n <DropdownMenuPortal>\n <DropdownMenuSubContent class=\"dt-menu\" :side-offset=\"4\">\n <DropdownMenuItem class=\"dt-menu-item\" @select=\"exportRows('xlsx', scope)\">\n {{ i18n.t('toolbar.xlsx') }}\n </DropdownMenuItem>\n <DropdownMenuItem class=\"dt-menu-item\" @select=\"exportRows('csv', scope)\">\n {{ i18n.t('toolbar.csv') }}\n </DropdownMenuItem>\n </DropdownMenuSubContent>\n </DropdownMenuPortal>\n </DropdownMenuSub>\n </DropdownMenuContent>\n </DropdownMenuPortal>\n </DropdownMenuRoot>\n <DisplayPopover v-bind=\"displayProps\" v-on=\"displayOn\" />\n </template>\n <span class=\"dt-toolbar-spacer\" />\n <template v-if=\"readOnlyDevice\" />\n <span v-else-if=\"!savingNow\" class=\"dt-sheet-changes\" :class=\"{ 'is-empty': !counts.changedCells }\">\n <span v-if=\"counts.changedCells\" class=\"dt-sheet-dot\" aria-hidden=\"true\" />\n {{ changesText }}\n <template v-if=\"counts.newRows\">· {{ i18n.t('sheet.newShort', { count: counts.newRows }) }}</template>\n </span>\n <button\n v-if=\"!readOnlyDevice\"\n type=\"button\"\n class=\"dt-btn dt-btn-ghost\"\n :disabled=\"savingNow || (!counts.changedCells && !counts.newRows)\"\n @click=\"discardOpen = true\"\n >\n {{ i18n.t('sheet.discard') }}\n </button>\n <button\n v-if=\"!readOnlyDevice\"\n type=\"button\"\n class=\"dt-btn dt-btn-primary has-icon dt-sheet-save\"\n :disabled=\"!savingNow && !canSave\"\n :aria-disabled=\"savingNow ? 'true' : undefined\"\n :data-dt-tip=\"savingNow ? undefined : saveTip\"\n @click=\"!savingNow && save()\"\n >\n <PhCircleNotch v-if=\"savingNow\" :size=\"16\" class=\"dt-spin\" aria-hidden=\"true\" />\n <PhCheck v-else :size=\"16\" aria-hidden=\"true\" />\n {{ savingNow ? i18n.t('sheet.savingButton') : i18n.t('sheet.save') }}\n </button>\n </div>\n\n <div v-if=\"partly\" class=\"dt-sheet-partly\" role=\"alert\">\n <PhWarningCircle :size=\"16\" aria-hidden=\"true\" />\n <span>\n <strong>{{ i18n.t('sheet.partly.title', { count: fmt.int(partly.failed) }) }}</strong>\n {{ i18n.t('sheet.partly.body', { count: fmt.int(partly.saved) }) }}\n </span>\n <span class=\"dt-partly-spacer\" />\n <span class=\"dt-partly-nav\">\n <button type=\"button\" class=\"dt-partly-btn\" :aria-label=\"i18n.t('sheet.prevError')\" @click=\"goToError(-1)\">\n <PhCaretUp :size=\"14\" aria-hidden=\"true\" />\n </button>\n <span>{{ i18n.t('sheet.findCount', { index: partlyIndex, total: errorKeysInOrder.length }) }}</span>\n <button type=\"button\" class=\"dt-partly-btn\" :aria-label=\"i18n.t('sheet.nextError')\" @click=\"goToError(1)\">\n <PhCaretDown :size=\"14\" aria-hidden=\"true\" />\n </button>\n </span>\n <span class=\"dt-partly-sep\" aria-hidden=\"true\" />\n <button type=\"button\" class=\"dt-partly-copy\" @click=\"copyErrors\">\n <PhCopy :size=\"14\" aria-hidden=\"true\" />\n {{ i18n.t('sheet.copyErrors') }}\n </button>\n </div>\n <div v-if=\"overLimit\" class=\"dt-strip dt-sheet-strip\" role=\"status\">\n <PhWarning :size=\"16\" aria-hidden=\"true\" />\n <span>{{ i18n.t('sheet.firstN', { max: fmt.int(maxRows), entity }) }}</span>\n </div>\n\n <div v-if=\"!readOnlyDevice\" class=\"dt-formula\">\n <div class=\"dt-formula-name\">\n <template v-if=\"rangeText\">{{ rangeText }}</template>\n <template v-else-if=\"activeDef\">\n <span class=\"dt-mono\">{{ nameKey }}</span>\n <span class=\"dt-formula-col\">· {{ activeDef.header }}</span>\n </template>\n </div>\n <span class=\"dt-formula-fx\" aria-hidden=\"true\">fx</span>\n <input\n class=\"dt-formula-value\"\n type=\"text\"\n :value=\"formulaText\"\n :readonly=\"!formulaEditable\"\n :aria-label=\"valueAria\"\n autocomplete=\"off\"\n @input=\"onFormulaInput\"\n @keydown=\"onFormulaKeydown\"\n />\n <span v-if=\"savingNow\" class=\"dt-formula-hint\">\n <PhLock :size=\"12\" aria-hidden=\"true\" />\n {{ i18n.t('sheet.savingReadOnly') }}\n </span>\n <span v-else-if=\"hint\" class=\"dt-formula-hint\">{{ hint }}</span>\n </div>\n\n <SheetGrid\n ref=\"grid\"\n :sheet=\"sheet\"\n :layout=\"layout\"\n :rows=\"rowsAll\"\n :density=\"density\"\n :label=\"entity.other\"\n :entity=\"entity\"\n :loading=\"loadingNow\"\n :skeleton=\"loadingNow\"\n :read-only=\"savingNow\"\n :vertical-lines=\"pref.prefs.verticalLines\"\n :key-column=\"keyColumn\"\n :found=\"matches?.map ?? null\"\n :sort=\"sortMap\"\n :phone=\"readOnlyDevice\"\n >\n <template v-if=\"!loadingNow && rowsAll.length === 0\" #state>\n <slot name=\"empty\">\n <StateMessage kind=\"empty\" :title=\"i18n.t('state.emptyTitle', { entity })\" />\n </slot>\n </template>\n </SheetGrid>\n\n <div v-if=\"readOnlyDevice\" class=\"dt-sheet-footer\" role=\"status\">\n <span>{{ i18n.t('sheet.readOnly.total', { count: fmt.int(store.allRows.value.length), entity }) }}</span>\n <span aria-hidden=\"true\">·</span>\n <span class=\"dt-sheet-footer-badge\">\n <PhLock :size=\"14\" aria-hidden=\"true\" />\n {{ i18n.t('sheet.readOnly.badge') }}\n </span>\n </div>\n <div v-else class=\"dt-status\" role=\"status\" :aria-label=\"i18n.t('sheet.statusAria')\">\n <span class=\"dt-status-rows\">\n {{\n loadingNow ? i18n.t('common.loading') : i18n.t('sheet.rows', { count: fmt.int(store.allRows.value.length) })\n }}\n </span>\n <template v-if=\"!loadingNow\">\n <span v-if=\"savedSummary\" class=\"dt-status-saved\">\n <PhCheck :size=\"14\" aria-hidden=\"true\" />\n <strong>{{ i18n.t('sheet.saved', { count: fmt.int(savedSummary.count) }) }}</strong>\n <span>\n ·\n {{\n i18n.t('sheet.savedDetail', {\n created: fmt.int(savedSummary.created),\n updated: fmt.int(savedSummary.updated),\n })\n }}\n </span>\n </span>\n <span v-else-if=\"counts.changedCells\" class=\"dt-status-changes\">\n <span class=\"dt-mark is-changed\" aria-hidden=\"true\" />\n {{ changesText }}\n </span>\n <span v-else class=\"dt-status-muted\">{{ changesText }}</span>\n <span v-if=\"counts.newRows\" class=\"dt-status-new\">\n {{ i18n.t('sheet.newRows', { count: counts.newRows }) }}\n </span>\n <button v-if=\"counts.errorRows\" type=\"button\" class=\"dt-status-errors\" @click=\"goToError(1)\">\n <span class=\"dt-mark is-error\" aria-hidden=\"true\" />\n {{ i18n.t('sheet.errorsGoTo', { count: counts.errorRows }) }}\n </button>\n <span v-if=\"summary\" class=\"dt-status-summary\" :aria-label=\"i18n.t('sheet.selectionSummary')\">\n <span>\n {{ i18n.t('sheet.agg.count') }}\n <b>{{ fmt.int(summary.count) }}</b>\n </span>\n <span v-if=\"summary.sum !== null\">\n {{ i18n.t('sheet.agg.sum') }}\n <b>{{ summary.sum }}</b>\n </span>\n <span v-if=\"summary.avg !== null\">\n {{ i18n.t('sheet.agg.avg') }}\n <b>{{ summary.avg }}</b>\n </span>\n </span>\n </template>\n </div>\n\n <div v-if=\"toast\" class=\"dt-toast dt-sheet-toast\" role=\"status\">\n <strong>{{ toast.text }}</strong>\n <template v-if=\"toast.issues\">\n <span aria-hidden=\"true\">·</span>\n <span class=\"dt-toast-warn\">{{ toast.issues }}</span>\n <button v-if=\"toast.review\" type=\"button\" class=\"dt-toast-link\" @click=\"toast.review()\">\n {{ i18n.t('sheet.review') }}\n </button>\n </template>\n <button v-if=\"toast.action\" type=\"button\" class=\"dt-toast-link\" @click=\"toastAction\">\n {{ toast.action.label }}\n </button>\n <template v-if=\"toast.undo\">\n <span class=\"dt-toast-sep\" aria-hidden=\"true\" />\n <button type=\"button\" class=\"dt-toast-undo\" @click=\"toastUndo\">\n {{ i18n.t('common.undo') }}\n <kbd class=\"dt-kbd\">{{ UNDO_KBD }}</kbd>\n </button>\n </template>\n </div>\n <span class=\"dt-sr-only\" aria-live=\"polite\">{{ polite }}</span>\n <span class=\"dt-sr-only\" aria-live=\"assertive\">{{ assertive }}</span>\n <div\n v-show=\"tooltip.open.value\"\n class=\"dt-tip\"\n :class=\"{ 'is-multi': tooltip.text.value.includes('\\n') }\"\n role=\"tooltip\"\n :style=\"tooltip.style.value\"\n >\n {{ tooltip.text.value }}\n </div>\n <ConfirmDialog\n v-model:open=\"discardOpen\"\n :title=\"i18n.t('sheet.discard.title', { cells: fmt.int(counts.changedCells), rows: fmt.int(counts.changedRows) })\"\n :body=\"i18n.t('sheet.discard.body')\"\n :confirm-label=\"i18n.t('sheet.leave.discard')\"\n :cancel-label=\"i18n.t('sheet.discard.keep')\"\n danger\n @confirm=\"discard\"\n />\n <ImportDialog\n v-if=\"importable && importOpen\"\n v-model:open=\"importOpen\"\n :parse-file=\"readFile\"\n :columns=\"sheetColumns\"\n :key-column=\"keyColumn\"\n :entity=\"entity\"\n :max-rows=\"maxRows\"\n :row-count=\"store.allRows.value.length\"\n :in-list=\"inList\"\n :parse-env=\"parseEnv\"\n :fmt-env=\"fmtEnv\"\n @apply=\"applyImport\"\n />\n <SaveErrorsDialog\n v-if=\"errorDialogOpen\"\n v-model:open=\"errorDialogOpen\"\n :errors=\"errorItems\"\n :ok-rows=\"store.getChanges().rows.length\"\n @fix=\"fixFirst\"\n @save=\"emitSave\"\n />\n </div>\n</template>\n","<script setup lang=\"ts\" generic=\"Row extends object\">\n// DataSheet (07, brief §8, handoff 06) — Faz 6a–6c: ızgara, editörler, doğrulama, taslak deposu; toolbar'da Find,\n// All / Changed / Errors, Undo/Redo, Add row, Display + Save kontrolleri; formül çubuğu; status bar; açılış ilerlemesi;\n// pano, fill handle, komut yığını; satır partisi (ekle / çıkar, anahtar tekilliği; sunucu durumu bilinmez, D47); yerel\n// sıralama; kayıt akışı (hata dialog'u, `@save`, `saving`, `applyResult`, Partly saved şeridi, Copy errors); ayrılma\n// koruması. İçe/dışa aktarma ve telefon düzeni (6d) sonraki fazda. Veri çekmez, kaydetmez (D18): yalnızca `@save` yayar.\nimport {\n PhArrowUUpLeft,\n PhArrowUUpRight,\n PhCaretDown,\n PhCaretUp,\n PhCheck,\n PhCircleNotch,\n PhCopy,\n PhLock,\n PhDownloadSimple,\n PhExport,\n PhLink,\n PhMonitor,\n PhPlus,\n PhWarning,\n PhWarningCircle,\n} from '@phosphor-icons/vue'\nimport {\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuPortal,\n DropdownMenuRoot,\n DropdownMenuSub,\n DropdownMenuSubContent,\n DropdownMenuSubTrigger,\n DropdownMenuTrigger,\n ToggleGroupItem,\n ToggleGroupRoot,\n} from 'reka-ui'\nimport {\n computed,\n getCurrentInstance,\n nextTick,\n onBeforeUnmount,\n onMounted,\n provide,\n ref,\n shallowRef,\n type Component,\n useTemplateRef,\n watch,\n} from 'vue'\nimport { comparator } from '../core/cells/compare'\nimport { formatCell, isEmptyValue, type FormatEnv } from '../core/cells/format'\nimport { RemoteLabels } from '../core/cells/remoteLabels'\nimport { TYPE_SPECS, typeLabelKey } from '../core/cells/specs'\nimport { readPath } from '../core/columns/readPath'\nimport { useColumnLayout } from '../core/columns/useColumnLayout'\nimport { plainText } from '../core/export/cells'\nimport { exportFile } from '../core/export/write'\nimport { getFormat } from '../core/format'\nimport { useDelegatedTooltip } from '../core/grid/useDelegatedTooltip'\nimport { FIND_KBD, REDO_KBD, SAVE_KBD, UNDO_KBD } from '../core/interaction/kbd'\nimport { useDataTableContext } from '../core/plugin'\nimport { usePreferences } from '../core/preferences/usePreferences'\nimport StateMessage from '../core/states/StateMessage.vue'\nimport DisplayPopover from '../core/toolbar/DisplayPopover.vue'\nimport type { ColumnsDraft } from '../core/toolbar/ColumnsDialog.vue'\nimport SearchBox from '../core/toolbar/SearchBox.vue'\nimport ConfirmDialog from '../core/ui/ConfirmDialog.vue'\nimport type { ColumnDef, ColumnType } from '../types/columns'\nimport type { Density, Plural, TableId } from '../types/core'\nimport type { SortRule } from '../types/query'\nimport type {\n ParsedWorkbook,\n Progress,\n SheetChanges,\n SheetFilterMode,\n SheetRowResult,\n SheetStatus,\n} from '../types/sheet'\nimport { matrixFromClipboard, parseTsv, toHtml, toTsv } from './clipboard'\nimport NumberCell from './editors/NumberCell.vue'\nimport OptionCell from './editors/OptionCell.vue'\nimport TextCell from './editors/TextCell.vue'\nimport DateCell from './editors/DateCell.vue'\nimport MultiCell from './editors/MultiCell.vue'\nimport { SHEET_EDITOR_KEY } from './editors/context'\nimport { fillValues } from './fill'\nimport ImportDialog, { type ImportPayload } from './ImportDialog.vue'\nimport { readWorkbook } from './import/read'\nimport { inferDecimal, inputText, parseInput, type ParseEnv } from './parse'\nimport SaveErrorsDialog, { type ErrorRowItem } from './SaveErrorsDialog.vue'\nimport SheetGrid from './SheetGrid.vue'\nimport { useSheetEditing, type SheetApi } from './useSheetEditing'\nimport { useSheetStore, type Change, type Step } from './useSheetStore'\nimport { useSheetTable } from './useSheetTable'\n\nconst props = withDefaults(\n defineProps<{\n tableId: TableId\n columns: Array<ColumnDef<Row>>\n rows: Row[]\n rowKey?: string\n /** Verilmezse tercihten (Display › Density), o da yoksa compact (02 · Yoğunluk). */\n density?: Density\n entityName?: Plural\n /** Upsert anahtarı olan sütun (ör. \"sku\"). Yüklenmiş satırlarda salt okunur; `rowKey`'den ayrıdır. */\n keyColumn: string\n /** Uygulama satırları yüklerken; sayaç verilirse \"Loading… 6,200 of 10,000\". Düzenleme false olunca açılır. */\n loading?: Progress\n /** `@save` sonrası uygulama kaydederken: grid salt okunur, ilerleme şeridi (07 §14). */\n saving?: Progress\n /** Add row ile oluşan satırın başlangıç değerleri. */\n newRowDefaults?: () => Partial<Row>\n /** Import: dosyayı uygulama ayrıştırır ve ham satırları verir (07 §13). Verilmezse paketin okuyucusu (.xlsx, .csv; D46). */\n parseFile?: (file: File) => Promise<ParsedWorkbook>\n /** Import düğmesi (D46). Varsayılan açık. */\n importable?: boolean\n /** Export menüsü (D46). Varsayılan açık; `false` gizler (ör. yetki). */\n exportable?: boolean\n /** Aşılırsa ilk `maxRows` satır kullanılır ve şerit uyarır (07 §15); yapıştırma ve ekleme bu sınırı aşamaz. */\n maxRows?: number\n /** Bu genişliğin altında veya yalnızca dokunmatikte salt okunur (D14); karar açılışta. */\n readOnlyBelow?: number\n }>(),\n {\n rowKey: 'id',\n loading: false,\n saving: false,\n maxRows: 10_000,\n readOnlyBelow: 768,\n importable: true,\n exportable: true,\n },\n)\nconst emit = defineEmits<{\n /** Save: doğrulama geçen değişmiş + yeni satırlar. Uygulama kaydeder, `saving` verir, `applyResult` çağırır. */\n save: [changes: SheetChanges]\n /** Export: değerler güncel (kaydedilmemiş değişiklikler dahil). Dinlenirse paket dosya yazmaz (D46). */\n export: [payload: { format: 'csv' | 'xlsx'; scope: 'all' | 'visible'; columns: string[]; rows: Row[] }]\n}>()\ndefineSlots<{ empty?: () => unknown }>()\n\nconst ctx = useDataTableContext()\nconst { i18n } = ctx\nconst fmt = getFormat(ctx.locale)\nconst entity = computed<Plural>(() => props.entityName ?? { one: props.tableId, other: props.tableId })\nconst listensExport = 'onExport' in (getCurrentInstance()?.vnode.props ?? {})\nconst readFile = (file: File) => (props.parseFile ? props.parseFile(file) : readWorkbook(file, i18n))\n\nconst pref = usePreferences(() => props.tableId, ctx.preferences, {\n density: props.density ?? 'compact',\n verticalLines: true,\n pageSize: 0,\n defaultViewId: null,\n})\nconst density = computed<Density>(() => props.density ?? pref.prefs.density)\n\nconst overLimit = computed(() => props.rows.length > props.maxRows)\nconst loadedRows = computed(() => (overLimit.value ? props.rows.slice(0, props.maxRows) : props.rows))\nconst loadingNow = computed(() => props.loading !== false)\nconst savingNow = computed(() => props.saving !== false)\nconst progress = computed(() => {\n const p = loadingNow.value ? props.loading : props.saving\n return typeof p === 'object' ? p : null\n})\nconst percent = computed(() =>\n progress.value && progress.value.total > 0 ? Math.round((100 * progress.value.done) / progress.value.total) : null,\n)\n\n// Sütunlar (07 §3): anahtar 128 px sola sabit (mono), birincil ad sola sabit ve esnek; sıra sabit, genişlik oturumluk.\n// Telefon / yalnızca dokunmatik: salt okunur, karar açılışta (D14, 07 §17): anahtar 104 px sabit, kalanlar kayar.\nconst readOnlyDevice =\n typeof matchMedia === 'function' &&\n (matchMedia(`(max-width: ${props.readOnlyBelow - 1}px)`).matches || !matchMedia('(any-pointer: fine)').matches)\nconst sheetColumns = computed<Array<ColumnDef<Row>>>(() =>\n props.columns.map((d) => (d.id === props.keyColumn ? { ...d, width: readOnlyDevice ? 104 : 128 } : d)),\n)\nconst fixedStart = computed(() =>\n sheetColumns.value\n .filter((d) => d.id === props.keyColumn || (d.primary && !readOnlyDevice))\n .map((d) => d.id as string),\n)\nconst defById = computed(() => new Map(sheetColumns.value.map((d) => [d.id as string, d])))\nconst keyDef = computed(() => defById.value.get(props.keyColumn))\nconst primaryDef = computed(() => sheetColumns.value.find((d) => d.primary))\nconst store = useSheetStore<Row>({\n rows: loadedRows,\n columns: sheetColumns,\n rowKey: () => props.rowKey,\n keyColumn: () => props.keyColumn,\n i18n,\n locale: ctx.locale,\n})\n\n// Gösterim sırası (07 §10–11): parti sırası ya da header tıklamasında alınan sıralama anlık görüntüsü (düzenlenen satır\n// imlecin altından kaçmaz); eklenen satır yerine konur; All / Changed / Errors görünümü ve çıkarılanlar süzülür.\nconst sortRules = ref<SortRule[]>([])\nconst order = shallowRef<string[] | null>(null)\nconst view = ref<SheetFilterMode>('all')\nconst viewKeys = shallowRef(new Set<string>())\nconst matchesView = (key: string) =>\n view.value === 'changed'\n ? !!store.rowDraft(key)?.size || store.isNew(key)\n : view.value === 'errors'\n ? store.hasError(key)\n : true\nconst refreshView = (union: boolean) => {\n const next = union ? new Set(viewKeys.value) : new Set<string>()\n for (const r of store.batch.value) {\n const k = store.keyOf(r)\n if (matchesView(k)) next.add(k)\n }\n viewKeys.value = next\n}\n/** Görünüm değişimi eşzamanlı uygulanır: hemen ardından gelen `goToError` doğru satır listesini görür. */\nconst setView = (v: SheetFilterMode) => {\n view.value = v\n refreshView(false)\n}\n// Görünümde kalma kuralı: son hatayı düzelttiğin satır görünümden çıkana kadar yerinde kalır; yeni uyanlar eklenir.\nwatch(store.version, () => {\n if (view.value !== 'all') refreshView(true)\n})\nconst orderedBatch = computed<Row[]>(() => {\n const batch = store.batch.value\n const o = order.value\n if (!o) return batch\n const seen = new Set(o)\n const rows: Row[] = []\n for (const k of o) {\n const r = store.rowByKey(k)\n if (r) rows.push(r)\n }\n for (const r of batch) if (!seen.has(store.keyOf(r))) rows.push(r)\n return rows\n})\n/** Gösterilen satırlar: sıra + görünüm + çıkarılanlar. */\nconst rowsAll = computed<Row[]>(() => {\n const all = view.value === 'all'\n const keys = viewKeys.value\n return orderedBatch.value.filter((r) => {\n const k = store.keyOf(r)\n return !store.isRemoved(k) && (all || keys.has(k))\n })\n})\nconst layout = useColumnLayout<Row>({\n columns: sheetColumns,\n rows: rowsAll,\n rowKey: () => props.rowKey,\n fixedStart,\n flexLastStart: true,\n})\nconst table = useSheetTable<Row>({\n rows: rowsAll,\n columnIds: () => layout.columns.value.map((c) => c.id),\n rowId: store.keyOf,\n})\nconst indexByKey = computed(() => {\n const m = new Map<string, number>()\n rowsAll.value.forEach((r, i) => m.set(store.keyOf(r), i))\n return m\n})\nconst visibleCols = computed(() => layout.columns.value)\n\nconst readOnlyNow = computed(() => loadingNow.value || savingNow.value || readOnlyDevice)\n\n// Editörler filtre değer girişleriyle aynı aileden (07 §5); `boolean` editör açmaz (Space). ajax/user/object/array için\n// yalnızca özel editör (`ColumnDef.editor`).\nconst EDITORS: Partial<Record<ColumnType, Component>> = {\n string: TextCell,\n text: TextCell,\n uppercase: TextCell,\n lowercase: TextCell,\n email: TextCell,\n url: TextCell,\n phone: TextCell,\n id: TextCell,\n color: TextCell,\n int: NumberCell,\n float: NumberCell,\n percentage: NumberCell,\n currency: NumberCell,\n star: NumberCell,\n select: OptionCell,\n multiselect: MultiCell,\n date: DateCell,\n datetime: DateCell,\n}\nconst editorFor = (def: ColumnDef<Row>): Component | null => def.editor ?? EDITORS[def.type] ?? null\n/** Sütunlar varsayılan salt okunur; anahtar sütun yüklenmiş satırlarda her zaman (yeni satırda açık); yüklenirken, kaydederken ve telefonda hiçbiri. */\nconst canEdit = (row: Row, def: ColumnDef<Row>): boolean => {\n if (readOnlyNow.value) return false\n const isNew = store.isNew(store.keyOf(row))\n if (def.id === props.keyColumn) return isNew\n if (def.type !== 'boolean' && !editorFor(def)) return false\n return typeof def.editable === 'function' ? def.editable(store.current(row), { isNew }) : def.editable === true\n}\n\nconst parseEnv = (locale = ctx.locale): ParseEnv => ({\n locale,\n today: new Date(),\n todayWord: i18n.t('date.today'),\n yesWord: i18n.t('common.yes'),\n noWord: i18n.t('common.no'),\n})\nconst edit = useSheetEditing<Row>({ store, canEdit, parse: (def, text) => parseInput(def, text, parseEnv()) })\nprovide(SHEET_EDITOR_KEY, { seed: () => edit.editing.value?.seed })\nconst grid = useTemplateRef<InstanceType<typeof SheetGrid>>('grid')\nconst counts = store.counts\nconst fmtEnv: FormatEnv = { fmt, i18n, today: new Date(), labels: new RemoteLabels() }\n\n/** Aralığı seçer ve odaklar (yapıştırma, doldurma, undo sonrası). */\nconst selectCells = (r1: number, c1: number, r2: number, c2: number) => {\n const rows = rowsAll.value\n const cols = visibleCols.value\n const a = rows[r1]\n const b = rows[r2]\n if (!a || !b || !cols[c1] || !cols[c2]) return\n table.selectRange({\n anchorRowId: store.keyOf(a),\n anchorColumnId: cols[c1]!.id,\n focusRowId: store.keyOf(b),\n focusColumnId: cols[c2]!.id,\n })\n grid.value?.focusActive()\n}\nconst focusCell = (r: number, columnId: string) => {\n const row = rowsAll.value[Math.max(0, Math.min(rowsAll.value.length - 1, r))]\n if (!row) return\n table.focus(store.keyOf(row), columnId)\n grid.value?.focusActive()\n}\n/** Seçimdeki (ya da aktif) hücreler. */\nconst selectedCells = (): Array<{ r: number; c: number }> => {\n const b = table.bounds.value\n if (!b) return []\n const out: Array<{ r: number; c: number }> = []\n for (let r = b.minRowIndex; r <= b.maxRowIndex; r++)\n for (let c = b.minColumnIndex; c <= b.maxColumnIndex; c++) out.push({ r, c })\n return out\n}\n\nconst toggle = (row: Row, def: ColumnDef<Row>) => store.set(row, def, !store.read(row, def))\n/** Delete / ⌘X: seçimdeki düzenlenebilir hücreler boşalır, tek adım. */\nconst clearSelected = () => {\n const changes: Array<Change<Row>> = []\n for (const { r, c } of selectedCells()) {\n const row = rowsAll.value[r]\n const def = visibleCols.value[c]?.def\n if (row && def && canEdit(row, def)) changes.push({ row, def, value: null })\n }\n store.apply(changes)\n}\n\n// Hatalar (07 §11, §14): gösterim sırasında; görünüm gizliyorsa toast \"Next error is hidden by filters · Show it\".\nconst errorKeysInOrder = computed(() => {\n void store.version.value\n return orderedBatch.value.map((r) => store.keyOf(r)).filter((k) => !store.isRemoved(k) && store.hasError(k))\n})\nconst goToError = (dir: 1 | -1) => {\n const rows = rowsAll.value\n const n = rows.length\n const a = table.active.value\n const from = a ? (indexByKey.value.get(a.rowId) ?? -1) : -1\n for (let s = 1; s <= n; s++) {\n const i = (((from + dir * s) % n) + n) % n\n const key = store.keyOf(rows[i]!)\n if (!store.hasError(key)) continue\n const issues = store.rowIssues(key)\n const col =\n visibleCols.value.find((c) => issues?.get(c.id)?.level === 'error') ??\n (store.rowError(key) ? visibleCols.value.find((c) => c.id === props.keyColumn) : undefined)\n if (!col) continue\n table.focus(key, col.id)\n grid.value?.focusActive()\n return\n }\n if (errorKeysInOrder.value.length && view.value !== 'all')\n showToast({\n text: i18n.t('sheet.nextErrorHidden'),\n action: {\n label: i18n.t('sheet.showIt'),\n run: () => {\n setView('all')\n goToError(dir)\n },\n },\n })\n}\n\n// Pano (07 §7): görüntülenen biçimde TSV + HTML; para kodu ve \"—\" yok, tarihler ISO, listeler `; ` ile (geri yapıştırılabilir).\nconst copyText = (def: ColumnDef<Row>, row: Row, value: unknown): string => plainText(def, row, value, fmtEnv)\nconst copyMatrix = (): string[][] | null => {\n const b = table.bounds.value\n if (!b) return null\n const out: string[][] = []\n for (let r = b.minRowIndex; r <= b.maxRowIndex; r++) {\n const row = rowsAll.value[r]\n if (!row) continue\n const line: string[] = []\n for (let c = b.minColumnIndex; c <= b.maxColumnIndex; c++) {\n const def = visibleCols.value[c]!.def\n line.push(copyText(def, row, store.read(row, def)))\n }\n out.push(line)\n }\n return out\n}\nconst copy = (data: DataTransfer | null): boolean => {\n const m = copyMatrix()\n if (!m || !data) return false\n data.setData('text/plain', toTsv(m))\n data.setData('text/html', toHtml(m))\n return true\n}\nconst cut = (data: DataTransfer | null): boolean => {\n if (!copy(data)) return false\n if (!readOnlyNow.value) clearSelected()\n return true\n}\n/** Hücre menüsü › Copy / Cut: `navigator.clipboard` (TSV + HTML; yalnızca metin destekleniyorsa TSV). */\nconst copyToClipboard = (cutAfter: boolean) => {\n const m = copyMatrix()\n const clip = typeof navigator !== 'undefined' ? navigator.clipboard : undefined\n if (!m || !clip) return\n const tsv = toTsv(m)\n const write =\n typeof ClipboardItem === 'function' && clip.write\n ? clip.write([\n new ClipboardItem({\n 'text/plain': new Blob([tsv], { type: 'text/plain' }),\n 'text/html': new Blob([toHtml(m)], { type: 'text/html' }),\n }),\n ])\n : clip.writeText(tsv)\n void write.catch(() => clip.writeText(tsv)).catch(() => {})\n if (cutAfter && !readOnlyNow.value) clearSelected()\n}\nconst pasteMatrix = (matrix: string[][]): boolean => {\n const a = table.active.value\n const width = Math.max(0, ...matrix.map((l) => l.length))\n if (!a || !matrix.length || !width || readOnlyNow.value) return false\n const cols = visibleCols.value\n const startRow = indexByKey.value.get(a.rowId)\n const startCol = cols.findIndex((c) => c.id === a.columnId)\n if (startRow === undefined || startCol < 0) return false\n const b = table.bounds.value\n const targets: Array<{ r: number; c: number; text: string }> = []\n if (\n matrix.length === 1 &&\n width === 1 &&\n b &&\n (b.maxRowIndex > b.minRowIndex || b.maxColumnIndex > b.minColumnIndex)\n ) {\n // Tek değer + aralık: değer tüm aralığa (07 §7).\n for (const { r, c } of selectedCells()) targets.push({ r, c, text: matrix[0]![0]! })\n } else {\n matrix.forEach((line, i) =>\n line.forEach((text, j) => {\n if (startCol + j < cols.length) targets.push({ r: startRow + i, c: startCol + j, text })\n }),\n )\n }\n const lastRow = Math.max(...targets.map((t) => t.r))\n const overflow = lastRow - rowsAll.value.length + 1\n if (overflow > 0 && store.allRows.value.length + overflow > props.maxRows) {\n showToast({\n text: i18n.t('sheet.limitPaste', {\n count: fmt.int(store.allRows.value.length + overflow),\n max: fmt.int(props.maxRows),\n }),\n })\n return true\n }\n // Son satırın altına taşanlar yeni satır olur; anahtar boşsa \"Required\" (07 §7).\n const addedRows = overflow > 0 ? store.addRows(overflow) : []\n if (addedRows.length && order.value) order.value = [...order.value, ...addedRows.map((x) => x.key)]\n const rows = rowsAll.value\n // Sayılar panonun yerel ayarıyla: sütun bazında çıkarım, belirsizse uygulama locale'i.\n const localeByCol = new Map<number, string>()\n for (const c of new Set(targets.map((t) => t.c))) {\n const def = cols[c]!.def\n if (!TYPE_SPECS[def.type].numeric) continue\n const dec = inferDecimal(targets.filter((t) => t.c === c).map((t) => t.text))\n localeByCol.set(c, dec === ',' ? 'de' : dec === '.' ? 'en' : ctx.locale)\n }\n const changes: Array<Change<Row>> = []\n for (const t of targets) {\n const row = rows[t.r]\n const def = cols[t.c]?.def\n if (!row || !def || !canEdit(row, def)) continue\n changes.push({ row, def, value: parseInput(def, t.text, parseEnv(localeByCol.get(t.c))) })\n }\n store.apply(changes, addedRows)\n const minR = Math.min(...targets.map((t) => t.r))\n const minC = Math.min(...targets.map((t) => t.c))\n const maxC = Math.max(...targets.map((t) => t.c))\n selectCells(minR, minC, lastRow, maxC)\n // Toast: seçenek olmayan değerler (\"2 values aren't options\") ve diğer hatalar ayrı sayılır; Review ilk sorunlu hücre.\n const issues = targets\n .map((t) => {\n const row = rows[t.r]\n const issue = row && store.rowIssues(store.keyOf(row))?.get(cols[t.c]!.id)\n return issue?.level === 'error'\n ? { ...t, option: cols[t.c]!.def.type === 'select' || cols[t.c]!.def.type === 'multiselect' }\n : null\n })\n .filter((x): x is NonNullable<typeof x> => x !== null)\n const options = issues.filter((i) => i.option).length\n const others = issues.length - options\n const dims = { rows: lastRow - minR + 1, cols: maxC - minC + 1 }\n const first = issues[0]\n showToast({\n text: i18n.t('sheet.pasted', { rows: fmt.int(dims.rows), cols: fmt.int(dims.cols) }),\n issues:\n [\n options ? i18n.t('sheet.pasteIssues', { count: options }) : '',\n others ? i18n.t('sheet.pasteErrors', { count: others }) : '',\n ]\n .filter(Boolean)\n .join(' · ') || undefined,\n review: first ? () => selectCells(first.r, first.c, first.r, first.c) : undefined,\n undo: true,\n })\n polite.value = i18n.t('sr.pasted', dims)\n return true\n}\nconst paste = (data: DataTransfer | null): boolean => pasteMatrix(matrixFromClipboard(data))\n/** Hücre menüsü › Paste: `readText` yedeği (07 §7). */\nconst pasteFromClipboard = () => {\n void navigator.clipboard\n ?.readText()\n .then((text) => pasteMatrix(parseTsv(text)))\n .catch(() => {})\n}\n\n// Doldurma (07 §8): kaynak satır aralığı, hedef satıra kadar; seri ya da kopya, read-only atlanır, tek adım.\nconst fillPlan = (fromRow: number, toRow: number, cols: [number, number], target: number) => {\n const rows = rowsAll.value\n const up = target < fromRow\n const count = up ? fromRow - target : target - toRow\n const changes: Array<Change<Row>> = []\n for (let c = cols[0]; c <= cols[1]; c++) {\n const def = visibleCols.value[c]?.def\n if (!def) continue\n const source = rows.slice(fromRow, toRow + 1).map((r) => store.read(r, def))\n const values = fillValues(source, count, up)\n for (let k = 0; k < count; k++) {\n const row = rows[up ? fromRow - 1 - k : toRow + 1 + k]\n if (row && canEdit(row, def)) changes.push({ row, def, value: values[k] })\n }\n }\n return { changes, count }\n}\nconst fill = (fromRow: number, toRow: number, cols: [number, number], target: number) => {\n const { changes } = fillPlan(fromRow, toRow, cols, target)\n store.apply(changes)\n selectCells(Math.min(fromRow, target), cols[0], Math.max(toRow, target), cols[1])\n}\nconst fillLabel = (fromRow: number, toRow: number, cols: [number, number], target: number): string => {\n const { changes, count } = fillPlan(fromRow, toRow, cols, target)\n const first = changes[0]\n const value = first ? formatCell(first.def, first.row, first.value, fmtEnv) : ''\n return i18n.t('sheet.fillPreview', { count: count * (cols[1] - cols[0] + 1), value })\n}\nconst fillDown = () => {\n const b = table.bounds.value\n if (!b || b.maxRowIndex === b.minRowIndex) return\n fill(b.minRowIndex, b.minRowIndex, [b.minColumnIndex, b.maxColumnIndex], b.maxRowIndex)\n}\n\n// Geri al / yinele (07 §12): seçim ve aktif hücre o adımın yerine taşınır.\nconst afterStep = (step: Step | null) => {\n if (!step) return\n // Listeden çıkarma geri alındı: geri gelen satıra odak (toast'taki Undo odağı ızgaradan almıştı).\n if (step.removed?.length && !step.patches.length) {\n const i = indexByKey.value.get(step.removed[0]!)\n if (i !== undefined) focusCell(i, table.active.value?.columnId ?? visibleCols.value[0]!.id)\n return\n }\n if (!step.patches.length) return\n const idx = visibleCols.value.map((c) => c.id)\n let r1 = Infinity\n let r2 = -1\n let c1 = Infinity\n let c2 = -1\n for (const p of step.patches) {\n const r = indexByKey.value.get(p.key)\n const c = idx.indexOf(p.col)\n if (r === undefined || c < 0) continue\n r1 = Math.min(r1, r)\n r2 = Math.max(r2, r)\n c1 = Math.min(c1, c)\n c2 = Math.max(c2, c)\n }\n if (r2 >= 0) selectCells(r1, c1, r2, c2)\n}\nconst undo = () => {\n if (readOnlyNow.value) return\n edit.cancel()\n afterStep(store.undo())\n}\nconst redo = () => {\n if (readOnlyNow.value) return\n edit.cancel()\n afterStep(store.redo())\n}\nconst useSuggestion = (row: Row, def: ColumnDef<Row>, value: unknown) => store.set(row, def, value)\n\n// Satır partisi (07 §9, D12): Add row / Insert row above-below (newRowDefaults, odak anahtar hücresinde, düzenleme açık);\n// Remove from list (⌘−): nötr, sunucuda silmez, toast + Undo.\nconst addRow = (at?: number) => {\n if (readOnlyNow.value) return\n if (store.allRows.value.length + 1 > props.maxRows) {\n showToast({\n text: i18n.t('sheet.limitPaste', { count: fmt.int(store.allRows.value.length + 1), max: fmt.int(props.maxRows) }),\n })\n return\n }\n edit.commit()\n const [added] = store.addRows(1)\n if (!added) return\n const defaults = props.newRowDefaults?.() ?? {}\n const changes: Array<Change<Row>> = []\n for (const [id, value] of Object.entries(defaults)) {\n const def = defById.value.get(id)\n if (def && !isEmptyValue(value)) changes.push({ row: added.row, def, value })\n }\n store.apply(changes, [added])\n if (at !== undefined) {\n const keys = order.value ?? store.batch.value.map((r) => store.keyOf(r)).filter((k) => k !== added.key)\n const pos = Math.max(0, Math.min(keys.length, at))\n order.value = [...keys.slice(0, pos), added.key, ...keys.slice(pos)]\n } else if (order.value) order.value = [...order.value, added.key]\n if (view.value !== 'all') viewKeys.value = new Set([...viewKeys.value, added.key])\n table.focus(added.key, props.keyColumn)\n // Yeni satır görünür alana kayar (sona eklenince 5.000 satır aşağıda olabilir); sanal liste yeni sayıyı bir sonraki\n // render'da öğrendiğinden nextTick. focusActive editör açıkken kaydırmaz.\n void nextTick(() => grid.value?.scrollToIndex(rowsAll.value.findIndex((r) => store.keyOf(r) === added.key)))\n grid.value?.focusActive()\n if (keyDef.value) edit.start(added.row, keyDef.value, { inCell: true })\n}\nconst insertRow = (where: 'above' | 'below') => {\n const a = table.active.value\n const i = a ? orderedBatch.value.findIndex((r) => store.keyOf(r) === a.rowId) : -1\n addRow(i < 0 ? undefined : where === 'above' ? i : i + 1)\n}\nconst removeSelectedRows = () => {\n if (readOnlyNow.value) return\n const b = table.bounds.value\n if (!b) return\n edit.cancel()\n const rows = rowsAll.value.slice(b.minRowIndex, b.maxRowIndex + 1)\n const keys = rows.map((r) => store.keyOf(r))\n if (!keys.length) return\n store.removeRows(keys)\n showToast({\n text:\n keys.length === 1\n ? i18n.t('sheet.removed', { count: 1, row: store.rowNoOf(keys[0]!), entity: entity.value })\n : i18n.t('sheet.removed', { count: keys.length, entity: entity.value }),\n undo: true,\n })\n focusCell(b.minRowIndex, table.active.value?.columnId ?? visibleCols.value[0]!.id)\n}\n\n// Yerel sıralama (07 §10): asc → desc → kapalı, ⇧ ile ikincil (en fazla 3); anlık görüntü, gutter numaraları değişmez.\nconst sort = (columnId: string, additive: boolean) => {\n const def = defById.value.get(columnId)\n if (!def || !(def.sortable ?? TYPE_SPECS[def.type].sortable)) return\n const current = sortRules.value\n const existing = current.find((s) => s.column === columnId)\n const next: SortRule | null = !existing\n ? { column: columnId, dir: 'asc' }\n : existing.dir === 'asc'\n ? { column: columnId, dir: 'desc' }\n : null\n const rest = current.filter((s) => s.column !== columnId)\n sortRules.value = additive\n ? next\n ? existing\n ? current.map((s) => (s.column === columnId ? next : s))\n : [...rest, next].slice(-3)\n : rest\n : next\n ? [next]\n : []\n if (!sortRules.value.length) {\n order.value = null\n return\n }\n const cmps = sortRules.value.map((s) => ({\n def: defById.value.get(s.column)!,\n cmp: comparator(defById.value.get(s.column)!, ctx.locale),\n sign: s.dir === 'desc' ? -1 : 1,\n }))\n order.value = [...store.batch.value]\n .sort((a, b) => {\n for (const { def: d, cmp, sign } of cmps) {\n const r = cmp(store.read(a, d), store.read(b, d)) * sign\n if (r) return r\n }\n return store.rowNoOf(store.keyOf(a)) - store.rowNoOf(store.keyOf(b))\n })\n .map((r) => store.keyOf(r))\n}\nconst sortMap = computed(() => {\n const m = new Map<string, { dir: 'asc' | 'desc'; index: number | null }>()\n sortRules.value.forEach((s, i) => m.set(s.column, { dir: s.dir, index: sortRules.value.length > 1 ? i + 1 : null }))\n return m\n})\n\n// Kayıt akışı (07 §14): hatalı satır varsa dialog; `@save` yükü; uygulama `saving` verir; `applyResult` sonuçları işler;\n// bitişte status bar sonucu ya da Partly saved şeridi (görünüm Errors, aktif hücre ilk hatada).\nconst errorDialogOpen = ref(false)\nconst errorItems = computed<ErrorRowItem[]>(() =>\n errorKeysInOrder.value\n .filter((k) => !!store.rowDraft(k)?.size || store.isNew(k))\n .map((k) => {\n const row = store.rowByKey(k)!\n const issues = store.rowIssues(k)\n const first = issues ? [...issues.values()].find((i) => i.level === 'error') : undefined\n return {\n rowNo: store.rowNoOf(k),\n key: keyDef.value ? inputText(keyDef.value, store.read(row, keyDef.value)) : k,\n message: first?.message ?? store.rowError(k) ?? '',\n }\n }),\n)\nconst saveTotals = shallowRef({ created: 0, updated: 0, errors: 0 })\nconst savedSummary = shallowRef<{ count: number; created: number; updated: number } | null>(null)\nconst partly = shallowRef<{ failed: number; saved: number } | null>(null)\nconst emitSave = () => {\n saveTotals.value = { created: 0, updated: 0, errors: 0 }\n savedSummary.value = null\n partly.value = null\n emit('save', store.getChanges())\n}\nconst save = () => {\n if (readOnlyNow.value) return\n edit.commit()\n if (!counts.value.changedCells && !counts.value.newRows) return\n if (errorItems.value.length) {\n errorDialogOpen.value = true\n return\n }\n emitSave()\n}\nconst fixFirst = () => {\n setView('errors')\n goToError(1)\n}\nconst finishSave = () => {\n const t = saveTotals.value\n if (!t.created && !t.updated && !t.errors) return\n if (t.errors) {\n partly.value = { failed: t.errors, saved: t.created + t.updated }\n assertive.value = i18n.t('sheet.partly.title', { count: fmt.int(t.errors) })\n setView('errors')\n goToError(1)\n } else {\n savedSummary.value = { count: t.created + t.updated, created: t.created, updated: t.updated }\n polite.value = i18n.t('sheet.saved', { count: fmt.int(t.created + t.updated) })\n }\n saveTotals.value = { created: 0, updated: 0, errors: 0 }\n}\nlet resultVersion = -1\nconst applyResult = (results: Array<SheetRowResult<Row>>) => {\n const r = store.applyResult(results)\n resultVersion = store.version.value\n const t = saveTotals.value\n saveTotals.value = { created: t.created + r.created, updated: t.updated + r.updated, errors: t.errors + r.errors }\n if (!savingNow.value) finishSave()\n}\nwatch(savingNow, (now) => {\n if (!now) finishSave()\n})\n// Sonraki düzenlemede sonuç metni gider (applyResult'ın kendi sürüm artışı sayılmaz); hata kalmayınca şerit kapanır.\nwatch(store.version, (v) => {\n if (v !== resultVersion) savedSummary.value = null\n if (partly.value && !counts.value.errorRows) partly.value = null\n})\nconst partlyIndex = computed(() => {\n const a = table.active.value\n const i = a ? errorKeysInOrder.value.indexOf(a.rowId) : -1\n return i < 0 ? 0 : i + 1\n})\n/** Copy errors (07 §14): TSV, başlık Row · anahtar sütunu · Column · Message. */\nconst copyErrors = () => {\n const lines: string[][] = [\n [\n i18n.t('sheet.err.row'),\n keyDef.value?.header ?? props.keyColumn,\n i18n.t('sheet.err.column'),\n i18n.t('sheet.err.message'),\n ],\n ]\n for (const k of errorKeysInOrder.value) {\n const row = store.rowByKey(k)!\n const keyText = keyDef.value ? inputText(keyDef.value, store.read(row, keyDef.value)) : k\n const rowErr = store.rowError(k)\n if (rowErr) lines.push([String(store.rowNoOf(k)), keyText, '', rowErr])\n for (const [col, issue] of store.rowIssues(k) ?? [])\n if (issue.level === 'error')\n lines.push([String(store.rowNoOf(k)), keyText, defById.value.get(col)?.header ?? col, issue.message])\n }\n void navigator.clipboard?.writeText(toTsv(lines)).catch(() => {})\n}\nconst openHref = (row: Row): string | undefined => {\n if (store.isNew(store.keyOf(row))) return undefined\n return keyDef.value?.href?.(row) ?? primaryDef.value?.href?.(row)\n}\n\n// Import (07 §13): listede olan anahtar o satırı günceller, olmayan (Add … checkbox'ı açıksa) satır olarak eklenir; tek undo adımı.\nconst importOpen = ref(false)\nconst keyIndexSet = computed(() => {\n void store.version.value\n const set = new Set<string>()\n const def = keyDef.value\n if (!def) return set\n for (const r of store.allRows.value) {\n const v = store.readUntracked(r, def)\n if (!isEmptyValue(v)) set.add(String(v))\n }\n return set\n})\nconst inList = (key: string) => keyIndexSet.value.has(key)\nconst applyImport = (payload: ImportPayload) => {\n if (readOnlyNow.value || !keyDef.value) return\n edit.commit()\n const def = keyDef.value\n const byKeyValue = new Map<string, Row>()\n for (const r of store.allRows.value) {\n const v = store.readUntracked(r, def)\n if (!isEmptyValue(v)) byKeyValue.set(String(v), r)\n }\n // Yeni satırlar önce sayılır ve tek `addRows` çağrısıyla eklenir: satır satır eklemek her seferinde tüm partiyi\n // yeniden doğruluyordu (10k'da karesel). Sınır başlangıçtaki satır sayısına göre (eklenen satır iki kez sayılmaz).\n const start = store.allRows.value.length\n const need = new Set<string>()\n for (const item of payload.rows) {\n if (byKeyValue.has(item.key) || need.has(item.key)) continue\n if (!payload.addNew) continue\n if (start + need.size + 1 > props.maxRows) break\n need.add(item.key)\n }\n const fresh = need.size ? store.addRows(need.size) : []\n const freshByKey = new Map([...need].map((k, i) => [k, fresh[i]!]))\n const changes: Array<Change<Row>> = []\n const addedRows: Array<{ key: string; row: Row }> = []\n let updated = 0\n let news = 0\n for (const item of payload.rows) {\n let row = byKeyValue.get(item.key)\n if (!row) {\n if (!payload.addNew) continue\n const a = freshByKey.get(item.key)\n if (!a) break // sınır\n row = a.row\n addedRows.push(a)\n byKeyValue.set(item.key, row)\n changes.push({ row, def, value: item.key })\n news++\n } else updated++\n for (const [id, value] of Object.entries(item.values)) {\n const d = defById.value.get(id)\n if (d && canEdit(row, d)) changes.push({ row, def: d, value })\n }\n }\n store.apply(changes, addedRows)\n if (addedRows.length && order.value) order.value = [...order.value, ...addedRows.map((a) => a.key)]\n showToast({\n text: i18n.t('import.done', {\n count: fmt.int(payload.rows.length),\n updated: fmt.int(updated),\n news: fmt.int(news),\n }),\n undo: true,\n })\n // Odak ızgaraya, ilk alınan satırın anahtar hücresine (dialog kapanınca odak Import düğmesine dönerdi).\n const firstKey = payload.rows[0]?.key\n const firstRow = firstKey ? byKeyValue.get(firstKey) : undefined\n const i = firstRow ? indexByKey.value.get(store.keyOf(firstRow)) : undefined\n if (i !== undefined) focusCell(i, props.keyColumn)\n}\n/** Export (07 §2): All / Visible › CSV / Excel; değerler güncel (taslak uygulanmış). `@export` yoksa dosyayı paket yazar (D46). */\nconst exportRows = (format: 'csv' | 'xlsx', scope: 'all' | 'visible') => {\n edit.commit()\n const rows = (scope === 'all' ? store.allRows.value : rowsAll.value).map((r) => store.current(r))\n if (listensExport) return emit('export', { format, scope, columns: visibleCols.value.map((c) => c.id), rows })\n void exportFile({\n format,\n columns: visibleCols.value.map((c) => c.def),\n rows,\n read: (row, def) => (def.accessor ? def.accessor(row) : readPath(row, def.id as string)),\n env: fmtEnv,\n name: entity.value.other,\n })\n}\nconst exportLabel = (scope: 'all' | 'visible') =>\n i18n.t(scope === 'all' ? 'sheet.exportAll' : 'sheet.exportVisible', {\n count: fmt.int(scope === 'all' ? store.allRows.value.length : rowsAll.value.length),\n })\nconst copyLink = () => void navigator.clipboard?.writeText(location.href).catch(() => {})\n\nconst sheet: SheetApi<Row> = {\n store,\n table,\n edit,\n canEdit,\n editorFor,\n toggle,\n clearCells: clearSelected,\n save,\n goToError,\n copy,\n cut,\n paste,\n fill,\n fillLabel,\n fillDown,\n undo,\n redo,\n useSuggestion,\n copyToClipboard,\n pasteFromClipboard,\n insertRow,\n removeSelectedRows,\n sort,\n openHref,\n}\n\n// Izgara dışına tık onaylar (07 §5): formül çubuğu ve portallı editör katmanları (`dt-sheet-layer`) dışarı sayılmaz.\nconst onDocPointerdown = (e: PointerEvent) => {\n if (!edit.editing.value) return\n const t = e.target as Element | null\n if (t?.closest('.dt-cell.is-editing, .dt-formula, .dt-sheet-layer')) return\n edit.commit()\n}\n// Ayrılma koruması (07 §14): değişiklik varken tarayıcı uyarısı; yönlendirici dialog'u uygulamanın (`isDirty()`).\nconst isDirty = () => counts.value.changedCells > 0 || counts.value.newRows > 0\nconst onBeforeUnload = (e: BeforeUnloadEvent) => {\n if (!isDirty()) return\n e.preventDefault()\n e.returnValue = ''\n}\nonMounted(() => {\n document.addEventListener('pointerdown', onDocPointerdown, true)\n window.addEventListener('beforeunload', onBeforeUnload)\n})\nonBeforeUnmount(() => {\n document.removeEventListener('pointerdown', onDocPointerdown, true)\n window.removeEventListener('beforeunload', onBeforeUnload)\n clearTimeout(toastTimer)\n})\n\n// ⌘S / ⌘F odak sheet içindeyken (07 §2); ızgara kendi işlediyse (defaultPrevented) tekrar etmez.\nconst findBox = useTemplateRef<InstanceType<typeof SearchBox>>('findBox')\nconst onRootKeydown = (e: KeyboardEvent) => {\n if (e.defaultPrevented || !(e.metaKey || e.ctrlKey)) return\n const k = e.key.toLowerCase()\n if (k === 's') {\n e.preventDefault()\n save()\n } else if (k === 'f' && !loadingNow.value) {\n e.preventDefault()\n findBox.value?.focus()\n }\n}\n\n// Find in grid (07 §2): görünür sütunlarda görüntülenen metin; eşleşmeler vurgulanır, satır gizlenmez; Enter / ⇧Enter gezer.\nconst fold = (s: string) => s.toLocaleLowerCase(ctx.locale)\nconst findText = ref('')\nconst findIndex = ref(0)\nconst matches = computed(() => {\n const q = fold(findText.value.trim())\n if (!q) return null\n void store.version.value\n const map = new Map<string, Set<string>>()\n const list: Array<{ r: number; c: number }> = []\n const rows = rowsAll.value\n const cols = visibleCols.value\n for (let r = 0; r < rows.length; r++) {\n const row = rows[r]!\n for (let c = 0; c < cols.length; c++) {\n const def = cols[c]!.def\n const v = store.readUntracked(row, def)\n if (isEmptyValue(v) || !fold(formatCell(def, row, v, fmtEnv)).includes(q)) continue\n const key = store.keyOf(row)\n let set = map.get(key)\n if (!set) map.set(key, (set = new Set()))\n set.add(def.id as string)\n list.push({ r, c })\n }\n }\n return { map, list }\n})\nconst goToMatch = (i: number) => {\n const m = matches.value?.list[i]\n if (!m) return\n findIndex.value = i\n const row = rowsAll.value[m.r]!\n table.focus(store.keyOf(row), visibleCols.value[m.c]!.id)\n grid.value?.scrollToIndex(m.r)\n}\nwatch(\n () => matches.value?.list.length ?? 0,\n () => goToMatch(0),\n)\nconst findStep = (dir: 1 | -1) => {\n const n = matches.value?.list.length ?? 0\n if (n) goToMatch((((findIndex.value + dir) % n) + n) % n)\n}\nconst onFindKeydown = (e: KeyboardEvent) => {\n if (e.key === 'Enter') {\n e.preventDefault()\n findStep(e.shiftKey ? -1 : 1)\n } else if (e.key === 'Escape' && !findText.value) {\n e.preventDefault()\n grid.value?.focusActive()\n }\n}\nconst findCount = computed(() =>\n matches.value\n ? i18n.t('sheet.findCount', {\n index: matches.value.list.length ? findIndex.value + 1 : 0,\n total: matches.value.list.length,\n })\n : '',\n)\n\n// All / Changed / Errors sayaçları (07 §11).\nconst viewCounts = computed(() => ({\n all: store.allRows.value.length,\n changed: counts.value.changedOrNewRows,\n errors: counts.value.errorRows,\n}))\n\n// Formül çubuğu (07 §2): ad kutusu, fx, değer (buraya yazmak hücreyi düzenler), ipucu.\nconst activeRow = computed(() => {\n const a = table.active.value\n return a ? (store.rowByKey(a.rowId) ?? null) : null\n})\nconst activeDef = computed(() => {\n const a = table.active.value\n return a ? (defById.value.get(a.columnId) ?? null) : null\n})\nconst rangeDims = computed(() => {\n const b = table.bounds.value\n if (!b) return null\n const rows = b.maxRowIndex - b.minRowIndex + 1\n const cols = b.maxColumnIndex - b.minColumnIndex + 1\n return rows * cols > 1 ? { rows, cols } : null\n})\nconst rangeText = computed(() => (rangeDims.value ? i18n.t('sheet.cells', rangeDims.value) : null))\nconst nameKey = computed(() =>\n activeRow.value && keyDef.value ? inputText(keyDef.value, store.read(activeRow.value, keyDef.value)) : '',\n)\nconst formulaText = computed(() => {\n const e = edit.editing.value\n if (e) return e.text ?? inputText(e.def, e.value)\n return activeRow.value && activeDef.value\n ? inputText(activeDef.value, store.read(activeRow.value, activeDef.value))\n : ''\n})\nconst formulaEditable = computed(\n () =>\n !!activeRow.value &&\n !!activeDef.value &&\n activeDef.value.type !== 'boolean' &&\n canEdit(activeRow.value, activeDef.value),\n)\nconst onFormulaInput = (e: Event) => {\n const text = (e.target as HTMLInputElement).value\n const row = activeRow.value\n const def = activeDef.value\n if (!row || !def || !formulaEditable.value) return\n if (!edit.editing.value && !edit.start(row, def, { inCell: false })) return\n edit.setValue(parseInput(def, text, parseEnv()), text, false)\n}\nconst onFormulaKeydown = (e: KeyboardEvent) => {\n if (e.key === 'Enter') {\n e.preventDefault()\n if (edit.commit()) table.move('down')\n grid.value?.focusActive()\n } else if (e.key === 'Escape') {\n e.preventDefault()\n edit.cancel()\n grid.value?.focusActive()\n }\n}\nconst hint = computed(() => {\n const d = activeDef.value\n if (!d) return ''\n const parts = [i18n.t(typeLabelKey(d.type))]\n if (d.type === 'currency' && typeof d.currency === 'string') parts.push(d.currency)\n if (d.required) parts.push(i18n.t('sheet.required').toLocaleLowerCase(ctx.locale))\n if (d.hint) parts.push(d.hint)\n return parts.join(' · ')\n})\nconst valueAria = computed(() =>\n activeDef.value ? i18n.t('sheet.valueAria', { column: activeDef.value.header, key: nameKey.value }) : '',\n)\n\n// Status bar seçim özeti (07 §2): Count = boş olmayan; Sum / Average yalnızca sayısal hücre varsa; tek hücrede gizli.\nconst summary = computed(() => {\n void store.version.value\n const b = table.bounds.value\n if (!b || !rangeDims.value) return null\n let count = 0\n let sum = 0\n let numeric = 0\n for (let r = b.minRowIndex; r <= b.maxRowIndex; r++) {\n const row = rowsAll.value[r]\n if (!row) continue\n for (let c = b.minColumnIndex; c <= b.maxColumnIndex; c++) {\n const def = visibleCols.value[c]!.def\n const v = store.readUntracked(row, def)\n if (isEmptyValue(v)) continue\n count++\n if (TYPE_SPECS[def.type].numeric && typeof v === 'number') {\n sum += v\n numeric++\n }\n }\n }\n return { count, sum: numeric ? fmt.decimal(sum, 2) : null, avg: numeric ? fmt.decimal(sum / numeric, 2) : null }\n})\n\nconst status = computed<SheetStatus>(() => ({\n phase: loadingNow.value\n ? 'loading'\n : savingNow.value\n ? 'saving'\n : partly.value\n ? 'partly-saved'\n : savedSummary.value\n ? 'saved'\n : 'ready',\n ...counts.value,\n}))\nconst changesText = computed(() =>\n counts.value.changedCells\n ? i18n.t('sheet.changes', { cells: fmt.int(counts.value.changedCells), rows: fmt.int(counts.value.changedRows) })\n : i18n.t('sheet.noChanges'),\n)\nconst saveTip = `${i18n.t('sheet.save')} · ${SAVE_KBD}`\nconst undoTip = `${i18n.t('common.undo')} (${UNDO_KBD})`\nconst redoTip = `${i18n.t('common.redo')} (${REDO_KBD})`\nconst canSave = computed(() => !readOnlyNow.value && (counts.value.changedCells > 0 || counts.value.newRows > 0))\n\n// Toast (06 §8): yapıştırma sonucu, sınır uyarısı, listeden çıkarma, gizli hata; Review / Show it / Undo.\ninterface Toast {\n text: string\n issues?: string\n review?: () => void\n action?: { label: string; run: () => void }\n undo?: boolean\n}\nconst toast = shallowRef<Toast | null>(null)\nlet toastTimer: ReturnType<typeof setTimeout> | undefined\nconst showToast = (t: Toast) => {\n toast.value = t\n clearTimeout(toastTimer)\n toastTimer = setTimeout(() => (toast.value = null), 6000)\n}\nconst toastUndo = () => {\n toast.value = null\n undo()\n}\nconst toastAction = () => {\n const run = toast.value?.action?.run\n toast.value = null\n run?.()\n}\nconst polite = ref('')\nconst assertive = ref('')\n// Yükleme / kayıt ilerlemesi her %25'te duyurulur (08 §5).\nlet announcedQuarter = -1\nwatch(percent, (p) => {\n if (p === null) {\n announcedQuarter = -1\n return\n }\n const q = Math.floor(p / 25)\n if (q === announcedQuarter || p === 0) return\n announcedQuarter = q\n polite.value = i18n.t(loadingNow.value ? 'sr.loadingPercent' : 'sr.savingPercent', { percent: q * 25 })\n})\n\nconst discardOpen = ref(false)\nconst discard = () => {\n edit.cancel()\n store.reset()\n order.value = null\n sortRules.value = []\n partly.value = null\n savedSummary.value = null\n grid.value?.focusActive()\n}\n\nconst displayProps = computed(() => ({\n density: density.value,\n verticalLines: pref.prefs.verticalLines,\n columns: layout.panel.value,\n counts: layout.counts.value,\n persistent: pref.persistent,\n}))\nconst displayOn = {\n 'update:density': (d: Density) => pref.set({ density: d }),\n 'update:verticalLines': (on: boolean) => pref.set({ verticalLines: on }),\n 'columns-save': (d: ColumnsDraft) => layout.arrange(d),\n // Display › Reset: tercihler + sütun düzeni tanımlara (sheet'te görünüm yok).\n reset: () => {\n pref.reset()\n layout.reset()\n },\n}\n\nconst rootEl = ref<HTMLElement | null>(null)\nconst tooltip = useDelegatedTooltip(rootEl)\n\ndefineExpose({\n status,\n isDirty,\n getChanges: store.getChanges,\n applyResult,\n reset: discard,\n undo,\n redo,\n goToNextError: () => goToError(1),\n})\n</script>\n\n<template>\n <div\n ref=\"rootEl\"\n class=\"dt dt-sheet\"\n :class=\"{ 'is-phone': readOnlyDevice }\"\n :data-density=\"density\"\n @keydown=\"onRootKeydown\"\n >\n <div v-if=\"readOnlyDevice\" class=\"dt-sheet-readonly\" role=\"note\">\n <PhMonitor :size=\"20\" aria-hidden=\"true\" />\n <div class=\"dt-sheet-readonly-text\">\n <strong>{{ i18n.t('sheet.readOnly.title') }}</strong>\n <span>{{ i18n.t('sheet.readOnly.body', { entity }) }}</span>\n <button type=\"button\" class=\"dt-btn has-icon\" @click=\"copyLink\">\n <PhLink :size=\"16\" aria-hidden=\"true\" />\n {{ i18n.t('common.copyLink') }}\n </button>\n </div>\n </div>\n <div class=\"dt-toolbar dt-sheet-toolbar\" role=\"toolbar\">\n <div v-if=\"loadingNow || savingNow\" class=\"dt-progress-strip\">\n <strong>\n {{\n loadingNow\n ? i18n.t('sheet.loading', { entity })\n : progress\n ? i18n.t('sheet.saving', { sent: fmt.int(progress.done), total: fmt.int(progress.total) })\n : i18n.t('sheet.savingIndeterminate')\n }}\n </strong>\n <span v-if=\"loadingNow && progress\" class=\"dt-progress-count\">\n {{ i18n.t('sheet.loadingCount', { loaded: fmt.int(progress.done), total: fmt.int(progress.total) }) }}\n </span>\n <div\n class=\"dt-progress\"\n :class=\"{ 'is-indeterminate': percent === null }\"\n role=\"progressbar\"\n aria-valuemin=\"0\"\n aria-valuemax=\"100\"\n :aria-valuenow=\"percent ?? undefined\"\n >\n <div class=\"dt-progress-fill\" :style=\"percent !== null ? { width: `${percent}%` } : undefined\" />\n </div>\n </div>\n <div v-else-if=\"readOnlyDevice\" class=\"dt-find\" @keydown=\"onFindKeydown\">\n <SearchBox\n ref=\"findBox\"\n :model-value=\"findText\"\n :placeholder=\"i18n.t('sheet.find')\"\n :kbd=\"FIND_KBD\"\n @update:model-value=\"(v) => (findText = v)\"\n />\n <span v-if=\"findCount\" class=\"dt-find-count\" role=\"status\">{{ findCount }}</span>\n </div>\n <template v-else>\n <div class=\"dt-find\" @keydown=\"onFindKeydown\">\n <SearchBox\n ref=\"findBox\"\n :model-value=\"findText\"\n :placeholder=\"i18n.t('sheet.find')\"\n :kbd=\"FIND_KBD\"\n @update:model-value=\"(v) => (findText = v)\"\n />\n <span v-if=\"findCount\" class=\"dt-find-count\" role=\"status\">{{ findCount }}</span>\n </div>\n <span class=\"dt-toolbar-sep\" aria-hidden=\"true\" />\n <ToggleGroupRoot\n class=\"dt-seg dt-sheet-views\"\n type=\"single\"\n :model-value=\"view\"\n :aria-label=\"i18n.t('sheet.showRows')\"\n @update:model-value=\"(v) => v && setView(v as SheetFilterMode)\"\n >\n <ToggleGroupItem class=\"dt-seg-item\" value=\"all\">\n {{ i18n.t('sheet.all') }}\n <span class=\"dt-seg-count\">{{ fmt.int(viewCounts.all) }}</span>\n </ToggleGroupItem>\n <ToggleGroupItem class=\"dt-seg-item\" value=\"changed\">\n {{ i18n.t('sheet.changed') }}\n <span class=\"dt-seg-count\">{{ fmt.int(viewCounts.changed) }}</span>\n </ToggleGroupItem>\n <ToggleGroupItem class=\"dt-seg-item\" :class=\"{ 'is-errors': viewCounts.errors > 0 }\" value=\"errors\">\n {{ i18n.t('sheet.errors') }}\n <span class=\"dt-seg-count\">{{ fmt.int(viewCounts.errors) }}</span>\n </ToggleGroupItem>\n </ToggleGroupRoot>\n <button\n type=\"button\"\n class=\"dt-btn dt-sheet-undo\"\n :aria-disabled=\"store.canUndo.value ? undefined : 'true'\"\n :aria-label=\"undoTip\"\n :data-dt-tip=\"undoTip\"\n @click=\"store.canUndo.value && undo()\"\n >\n <PhArrowUUpLeft :size=\"16\" aria-hidden=\"true\" />\n </button>\n <button\n type=\"button\"\n class=\"dt-btn dt-sheet-undo\"\n :aria-disabled=\"store.canRedo.value ? undefined : 'true'\"\n :aria-label=\"redoTip\"\n :data-dt-tip=\"redoTip\"\n @click=\"store.canRedo.value && redo()\"\n >\n <PhArrowUUpRight :size=\"16\" aria-hidden=\"true\" />\n </button>\n <span class=\"dt-toolbar-sep\" aria-hidden=\"true\" />\n <button type=\"button\" class=\"dt-btn dt-btn-ghost has-icon dt-sheet-add\" @click=\"addRow()\">\n <PhPlus :size=\"16\" aria-hidden=\"true\" />\n {{ i18n.t('sheet.addRow') }}\n </button>\n <button\n v-if=\"importable\"\n type=\"button\"\n class=\"dt-btn dt-btn-ghost has-icon dt-sheet-import\"\n @click=\"importOpen = true\"\n >\n <PhDownloadSimple :size=\"16\" aria-hidden=\"true\" />\n {{ i18n.t('sheet.import') }}\n </button>\n <DropdownMenuRoot v-if=\"exportable\">\n <DropdownMenuTrigger as-child>\n <button type=\"button\" class=\"dt-btn dt-btn-ghost has-icon dt-sheet-export\">\n <PhExport :size=\"16\" aria-hidden=\"true\" />\n {{ i18n.t('sheet.export') }}\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuPortal>\n <DropdownMenuContent class=\"dt-menu\" align=\"start\" :side-offset=\"4\">\n <DropdownMenuSub v-for=\"scope in ['all', 'visible'] as const\" :key=\"scope\">\n <DropdownMenuSubTrigger class=\"dt-menu-item\">{{ exportLabel(scope) }}</DropdownMenuSubTrigger>\n <DropdownMenuPortal>\n <DropdownMenuSubContent class=\"dt-menu\" :side-offset=\"4\">\n <DropdownMenuItem class=\"dt-menu-item\" @select=\"exportRows('xlsx', scope)\">\n {{ i18n.t('toolbar.xlsx') }}\n </DropdownMenuItem>\n <DropdownMenuItem class=\"dt-menu-item\" @select=\"exportRows('csv', scope)\">\n {{ i18n.t('toolbar.csv') }}\n </DropdownMenuItem>\n </DropdownMenuSubContent>\n </DropdownMenuPortal>\n </DropdownMenuSub>\n </DropdownMenuContent>\n </DropdownMenuPortal>\n </DropdownMenuRoot>\n <DisplayPopover v-bind=\"displayProps\" v-on=\"displayOn\" />\n </template>\n <span class=\"dt-toolbar-spacer\" />\n <template v-if=\"readOnlyDevice\" />\n <span v-else-if=\"!savingNow\" class=\"dt-sheet-changes\" :class=\"{ 'is-empty': !counts.changedCells }\">\n <span v-if=\"counts.changedCells\" class=\"dt-sheet-dot\" aria-hidden=\"true\" />\n {{ changesText }}\n <template v-if=\"counts.newRows\">· {{ i18n.t('sheet.newShort', { count: counts.newRows }) }}</template>\n </span>\n <button\n v-if=\"!readOnlyDevice\"\n type=\"button\"\n class=\"dt-btn dt-btn-ghost\"\n :disabled=\"savingNow || (!counts.changedCells && !counts.newRows)\"\n @click=\"discardOpen = true\"\n >\n {{ i18n.t('sheet.discard') }}\n </button>\n <button\n v-if=\"!readOnlyDevice\"\n type=\"button\"\n class=\"dt-btn dt-btn-primary has-icon dt-sheet-save\"\n :disabled=\"!savingNow && !canSave\"\n :aria-disabled=\"savingNow ? 'true' : undefined\"\n :data-dt-tip=\"savingNow ? undefined : saveTip\"\n @click=\"!savingNow && save()\"\n >\n <PhCircleNotch v-if=\"savingNow\" :size=\"16\" class=\"dt-spin\" aria-hidden=\"true\" />\n <PhCheck v-else :size=\"16\" aria-hidden=\"true\" />\n {{ savingNow ? i18n.t('sheet.savingButton') : i18n.t('sheet.save') }}\n </button>\n </div>\n\n <div v-if=\"partly\" class=\"dt-sheet-partly\" role=\"alert\">\n <PhWarningCircle :size=\"16\" aria-hidden=\"true\" />\n <span>\n <strong>{{ i18n.t('sheet.partly.title', { count: fmt.int(partly.failed) }) }}</strong>\n {{ i18n.t('sheet.partly.body', { count: fmt.int(partly.saved) }) }}\n </span>\n <span class=\"dt-partly-spacer\" />\n <span class=\"dt-partly-nav\">\n <button type=\"button\" class=\"dt-partly-btn\" :aria-label=\"i18n.t('sheet.prevError')\" @click=\"goToError(-1)\">\n <PhCaretUp :size=\"14\" aria-hidden=\"true\" />\n </button>\n <span>{{ i18n.t('sheet.findCount', { index: partlyIndex, total: errorKeysInOrder.length }) }}</span>\n <button type=\"button\" class=\"dt-partly-btn\" :aria-label=\"i18n.t('sheet.nextError')\" @click=\"goToError(1)\">\n <PhCaretDown :size=\"14\" aria-hidden=\"true\" />\n </button>\n </span>\n <span class=\"dt-partly-sep\" aria-hidden=\"true\" />\n <button type=\"button\" class=\"dt-partly-copy\" @click=\"copyErrors\">\n <PhCopy :size=\"14\" aria-hidden=\"true\" />\n {{ i18n.t('sheet.copyErrors') }}\n </button>\n </div>\n <div v-if=\"overLimit\" class=\"dt-strip dt-sheet-strip\" role=\"status\">\n <PhWarning :size=\"16\" aria-hidden=\"true\" />\n <span>{{ i18n.t('sheet.firstN', { max: fmt.int(maxRows), entity }) }}</span>\n </div>\n\n <div v-if=\"!readOnlyDevice\" class=\"dt-formula\">\n <div class=\"dt-formula-name\">\n <template v-if=\"rangeText\">{{ rangeText }}</template>\n <template v-else-if=\"activeDef\">\n <span class=\"dt-mono\">{{ nameKey }}</span>\n <span class=\"dt-formula-col\">· {{ activeDef.header }}</span>\n </template>\n </div>\n <span class=\"dt-formula-fx\" aria-hidden=\"true\">fx</span>\n <input\n class=\"dt-formula-value\"\n type=\"text\"\n :value=\"formulaText\"\n :readonly=\"!formulaEditable\"\n :aria-label=\"valueAria\"\n autocomplete=\"off\"\n @input=\"onFormulaInput\"\n @keydown=\"onFormulaKeydown\"\n />\n <span v-if=\"savingNow\" class=\"dt-formula-hint\">\n <PhLock :size=\"12\" aria-hidden=\"true\" />\n {{ i18n.t('sheet.savingReadOnly') }}\n </span>\n <span v-else-if=\"hint\" class=\"dt-formula-hint\">{{ hint }}</span>\n </div>\n\n <SheetGrid\n ref=\"grid\"\n :sheet=\"sheet\"\n :layout=\"layout\"\n :rows=\"rowsAll\"\n :density=\"density\"\n :label=\"entity.other\"\n :entity=\"entity\"\n :loading=\"loadingNow\"\n :skeleton=\"loadingNow\"\n :read-only=\"savingNow\"\n :vertical-lines=\"pref.prefs.verticalLines\"\n :key-column=\"keyColumn\"\n :found=\"matches?.map ?? null\"\n :sort=\"sortMap\"\n :phone=\"readOnlyDevice\"\n >\n <template v-if=\"!loadingNow && rowsAll.length === 0\" #state>\n <slot name=\"empty\">\n <StateMessage kind=\"empty\" :title=\"i18n.t('state.emptyTitle', { entity })\" />\n </slot>\n </template>\n </SheetGrid>\n\n <div v-if=\"readOnlyDevice\" class=\"dt-sheet-footer\" role=\"status\">\n <span>{{ i18n.t('sheet.readOnly.total', { count: fmt.int(store.allRows.value.length), entity }) }}</span>\n <span aria-hidden=\"true\">·</span>\n <span class=\"dt-sheet-footer-badge\">\n <PhLock :size=\"14\" aria-hidden=\"true\" />\n {{ i18n.t('sheet.readOnly.badge') }}\n </span>\n </div>\n <div v-else class=\"dt-status\" role=\"status\" :aria-label=\"i18n.t('sheet.statusAria')\">\n <span class=\"dt-status-rows\">\n {{\n loadingNow ? i18n.t('common.loading') : i18n.t('sheet.rows', { count: fmt.int(store.allRows.value.length) })\n }}\n </span>\n <template v-if=\"!loadingNow\">\n <span v-if=\"savedSummary\" class=\"dt-status-saved\">\n <PhCheck :size=\"14\" aria-hidden=\"true\" />\n <strong>{{ i18n.t('sheet.saved', { count: fmt.int(savedSummary.count) }) }}</strong>\n <span>\n ·\n {{\n i18n.t('sheet.savedDetail', {\n created: fmt.int(savedSummary.created),\n updated: fmt.int(savedSummary.updated),\n })\n }}\n </span>\n </span>\n <span v-else-if=\"counts.changedCells\" class=\"dt-status-changes\">\n <span class=\"dt-mark is-changed\" aria-hidden=\"true\" />\n {{ changesText }}\n </span>\n <span v-else class=\"dt-status-muted\">{{ changesText }}</span>\n <span v-if=\"counts.newRows\" class=\"dt-status-new\">\n {{ i18n.t('sheet.newRows', { count: counts.newRows }) }}\n </span>\n <button v-if=\"counts.errorRows\" type=\"button\" class=\"dt-status-errors\" @click=\"goToError(1)\">\n <span class=\"dt-mark is-error\" aria-hidden=\"true\" />\n {{ i18n.t('sheet.errorsGoTo', { count: counts.errorRows }) }}\n </button>\n <span v-if=\"summary\" class=\"dt-status-summary\" :aria-label=\"i18n.t('sheet.selectionSummary')\">\n <span>\n {{ i18n.t('sheet.agg.count') }}\n <b>{{ fmt.int(summary.count) }}</b>\n </span>\n <span v-if=\"summary.sum !== null\">\n {{ i18n.t('sheet.agg.sum') }}\n <b>{{ summary.sum }}</b>\n </span>\n <span v-if=\"summary.avg !== null\">\n {{ i18n.t('sheet.agg.avg') }}\n <b>{{ summary.avg }}</b>\n </span>\n </span>\n </template>\n </div>\n\n <div v-if=\"toast\" class=\"dt-toast dt-sheet-toast\" role=\"status\">\n <strong>{{ toast.text }}</strong>\n <template v-if=\"toast.issues\">\n <span aria-hidden=\"true\">·</span>\n <span class=\"dt-toast-warn\">{{ toast.issues }}</span>\n <button v-if=\"toast.review\" type=\"button\" class=\"dt-toast-link\" @click=\"toast.review()\">\n {{ i18n.t('sheet.review') }}\n </button>\n </template>\n <button v-if=\"toast.action\" type=\"button\" class=\"dt-toast-link\" @click=\"toastAction\">\n {{ toast.action.label }}\n </button>\n <template v-if=\"toast.undo\">\n <span class=\"dt-toast-sep\" aria-hidden=\"true\" />\n <button type=\"button\" class=\"dt-toast-undo\" @click=\"toastUndo\">\n {{ i18n.t('common.undo') }}\n <kbd class=\"dt-kbd\">{{ UNDO_KBD }}</kbd>\n </button>\n </template>\n </div>\n <span class=\"dt-sr-only\" aria-live=\"polite\">{{ polite }}</span>\n <span class=\"dt-sr-only\" aria-live=\"assertive\">{{ assertive }}</span>\n <div\n v-show=\"tooltip.open.value\"\n class=\"dt-tip\"\n :class=\"{ 'is-multi': tooltip.text.value.includes('\\n') }\"\n role=\"tooltip\"\n :style=\"tooltip.style.value\"\n >\n {{ tooltip.text.value }}\n </div>\n <ConfirmDialog\n v-model:open=\"discardOpen\"\n :title=\"i18n.t('sheet.discard.title', { cells: fmt.int(counts.changedCells), rows: fmt.int(counts.changedRows) })\"\n :body=\"i18n.t('sheet.discard.body')\"\n :confirm-label=\"i18n.t('sheet.leave.discard')\"\n :cancel-label=\"i18n.t('sheet.discard.keep')\"\n danger\n @confirm=\"discard\"\n />\n <ImportDialog\n v-if=\"importable && importOpen\"\n v-model:open=\"importOpen\"\n :parse-file=\"readFile\"\n :columns=\"sheetColumns\"\n :key-column=\"keyColumn\"\n :entity=\"entity\"\n :max-rows=\"maxRows\"\n :row-count=\"store.allRows.value.length\"\n :in-list=\"inList\"\n :parse-env=\"parseEnv\"\n :fmt-env=\"fmtEnv\"\n @apply=\"applyImport\"\n />\n <SaveErrorsDialog\n v-if=\"errorDialogOpen\"\n v-model:open=\"errorDialogOpen\"\n :errors=\"errorItems\"\n :ok-rows=\"store.getChanges().rows.length\"\n @fix=\"fixFirst\"\n @save=\"emitSave\"\n />\n </div>\n</template>\n"],"mappings":"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"}