{"version":3,"sources":["../src/lib/utils.ts","../src/hooks/use-is-mobile.ts","../src/components/ui/sheet.tsx","../src/components/ui/tooltip.tsx","../src/components/ui/avatar.tsx","../src/components/ui/button.tsx","../src/components/ui/dropdown-menu.tsx","../src/components/ui/separator.tsx","../src/components/layout/admin-layout-context.tsx","../src/components/layout/admin-header.tsx","../src/components/layout/admin-sidebar.tsx","../src/components/layout/admin-container.tsx","../src/components/layout/admin-layout.tsx","../src/components/layout/mobile-container.tsx","../src/components/theme/admin-theme-provider.tsx","../src/components/page/admin-page.tsx","../src/lib/format.ts","../src/components/ui/input.tsx","../src/components/ui/label.tsx","../src/components/ui/switch.tsx","../src/components/ui/popover.tsx","../src/components/select/admin-select.tsx","../src/components/upload/admin-image-upload.tsx","../src/components/form/admin-form-field.tsx","../src/components/form/use-admin-form.ts","../src/components/input/admin-input.tsx","../src/components/input/admin-textarea.tsx","../src/components/input/admin-date-input.tsx","../src/components/ui/calendar.tsx","../src/components/input/admin-date-picker.tsx","../src/components/filter/admin-filter.tsx","../src/components/filter/keyword-filter.tsx","../src/components/filter/date-range-filter.tsx","../src/components/ui/checkbox.tsx","../src/components/filter/admin-checkbox-filter.tsx","../src/components/filter/admin-filter-fields.tsx","../src/components/table/admin-table-toolbar.tsx","../src/components/table/admin-pagination.tsx","../src/components/table/admin-table.tsx","../src/components/ui/dialog.tsx","../src/components/modal/admin-modal.tsx","../src/components/modal/admin-drawer.tsx","../src/components/modal/confirm-dialog.tsx","../src/components/modal/confirm-toast.tsx","../src/components/modal/confirm-modal.tsx","../src/components/ui/tabs.tsx","../src/components/tabs/admin-tabs.tsx","../src/components/steps/admin-steps.tsx","../src/components/steps/admin-wizard.tsx","../src/components/transfer/admin-transfer.tsx","../src/components/image/admin-image.tsx","../src/components/descriptions/admin-descriptions.tsx","../src/components/badge/badge.tsx","../src/hooks/use-dirty-check.ts","../src/hooks/use-page-search-state.ts"],"names":["jsx","jsxs","Separator","useState","Fragment","useMemo","Label","AdminSelect","_a","_b","useEffect","ChevronDown","forwardRef","AdminImageUpload","useRef","useImperativeHandle","X","Loader2","DialogPrimitive","useId","e","AdminDateInput","createContext","useContext","ChevronRight","ymd","formatDate","selectClass","Check","window","ChevronLeft","ROW_HEIGHT","table","DialogPrimitive2","XIcon","ICON_SIZE","Search","ZoomIn","DialogPrimitive3","SIZE","Badge"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAYO,SAAS,MAAM,MAAA,EAAsB;AAC1C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC7B;ACCO,SAAS,WAAA,CAAY,aAAa,GAAA,EAAK;AAE5C,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,QAAA;AAAA,IAC9B;AAAA,GACF;AAEA,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,MAAM,MAAA,CAAO,UAAA,CAAW,CAAA,YAAA,EAAe,UAAA,GAAa,CAAC,CAAA,GAAA,CAAK,CAAA;AAChE,IAAA,MAAM,QAAA,GAAW,MAAM,WAAA,CAAY,GAAA,CAAI,OAAO,CAAA;AAC9C,IAAA,QAAA,EAAS;AACT,IAAA,GAAA,CAAI,gBAAA,CAAiB,UAAU,QAAQ,CAAA;AACvC,IAAA,OAAO,MAAM,GAAA,CAAI,mBAAA,CAAoB,QAAA,EAAU,QAAQ,CAAA;AAAA,EACzD,CAAA,EAAG,CAAC,UAAU,CAAC,CAAA;AAEf,EAAA,OAAO,CAAC,CAAC,QAAA;AACX;ACRA,SAAS,MAAM,KAAA,EAAmD;AAChE,EAAA,uBAAO,GAAA,CAAgB,cAAA,CAAA,IAAA,EAAf,cAAA,CAAA,EAAoB,WAAA,EAAU,WAAY,KAAA,CAAO,CAAA;AAC3D;AAEA,SAAS,aACP,KAAA,EACA;AACA,EAAA,uBAAO,GAAA,CAAgB,cAAA,CAAA,OAAA,EAAf,cAAA,CAAA,EAAuB,WAAA,EAAU,mBAAoB,KAAA,CAAO,CAAA;AACtE;AAEA,SAAS,WAAW,KAAA,EAAoD;AACtE,EAAA,uBAAO,GAAA,CAAgB,cAAA,CAAA,KAAA,EAAf,cAAA,CAAA,EAAqB,WAAA,EAAU,iBAAkB,KAAA,CAAO,CAAA;AAClE;AAEA,SAAS,aAAa,EAAA,EAG4B;AAH5B,EAAA,IAAA,EAAA,GAAA,EAAA,EACpB;AAAA,IAAA;AAAA,GArCF,GAoCsB,EAAA,EAEjB,KAAA,GAAA,SAAA,CAFiB,EAAA,EAEjB;AAAA,IADH;AAAA,GAAA,CAAA;AAGA,EAAA,uBACE,GAAA;AAAA,IAAgB,cAAA,CAAA,OAAA;AAAA,IAAf,cAAA,CAAA;AAAA,MACC,WAAA,EAAU,eAAA;AAAA,MACV,SAAA,EAAW,EAAA;AAAA,QACT,wJAAA;AAAA,QACA;AAAA;AACF,KAAA,EACI,KAAA;AAAA,GACN;AAEJ;AAEA,SAAS,aAAa,EAAA,EAUnB;AAVmB,EAAA,IAAA,EAAA,GAAA,EAAA,EACpB;AAAA,IAAA,SAAA;AAAA,IACA,QAAA;AAAA,IACA,IAAA,GAAO,OAAA;AAAA,IACP;AAAA,GAxDF,GAoDsB,EAAA,EAKjB,KAAA,GAAA,SAAA,CALiB,EAAA,EAKjB;AAAA,IAJH,WAAA;AAAA,IACA,UAAA;AAAA,IACA,MAAA;AAAA,IACA;AAAA,GAAA,CAAA;AAOA,EAAA,uBACE,IAAA,CAAgB,cAAA,CAAA,MAAA,EAAf,EAAsB,WAAA,EAAU,cAAA,EAC/B,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,YAAA,EAAA,EAAa,CAAA;AAAA,oBACd,IAAA;AAAA,MAAgB,cAAA,CAAA,OAAA;AAAA,MAAf,aAAA,CAAA,cAAA,CAAA;AAAA,QACC,WAAA,EAAU,eAAA;AAAA,QACV,SAAA,EAAW,EAAA;AAAA,UACT,4MAAA;AAAA,UACA,SAAS,OAAA,IACP,kIAAA;AAAA,UACF,SAAS,MAAA,IACP,+HAAA;AAAA,UACF,SAAS,KAAA,IACP,0GAAA;AAAA,UACF,SAAS,QAAA,IACP,mHAAA;AAAA,UACF;AAAA;AACF,OAAA,EACI,KAAA,CAAA,EAdL;AAAA,QAgBE,QAAA,EAAA;AAAA,UAAA,QAAA;AAAA,0BACD,IAAA;AAAA,YAAgB,cAAA,CAAA,KAAA;AAAA,YAAf;AAAA,cACC,SAAA,EAAW,EAAA;AAAA,gBACT,6MAAA;AAAA,gBACA;AAAA,eACF;AAAA,cAEA,QAAA,EAAA;AAAA,gCAAA,GAAA,CAAC,KAAA,EAAA,EAAM,WAAU,QAAA,EAAS,CAAA;AAAA,gCAC1B,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,SAAA,EAAU,QAAA,EAAA,cAAA,EAAE;AAAA;AAAA;AAAA;AAC9B;AAAA,OAAA;AAAA;AACF,GAAA,EACF,CAAA;AAEJ;AAEA,SAAS,YAAY,EAAA,EAAgD;AAAhD,EAAA,IAAA,EAAA,GAAA,EAAA,EAAE,EAAA,SAAA,EAjGvB,GAiGqB,EAAA,EAAgB,KAAA,GAAA,SAAA,CAAhB,IAAgB,CAAd,WAAA,CAAA,CAAA;AACrB,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA,cAAA,CAAA;AAAA,MACC,WAAA,EAAU,cAAA;AAAA,MACV,SAAA,EAAW,EAAA,CAAG,2BAAA,EAA6B,SAAS;AAAA,KAAA,EAChD,KAAA;AAAA,GACN;AAEJ;AAEA,SAAS,YAAY,EAAA,EAAgD;AAAhD,EAAA,IAAA,EAAA,GAAA,EAAA,EAAE,EAAA,SAAA,EA3GvB,GA2GqB,EAAA,EAAgB,KAAA,GAAA,SAAA,CAAhB,IAAgB,CAAd,WAAA,CAAA,CAAA;AACrB,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA,cAAA,CAAA;AAAA,MACC,WAAA,EAAU,cAAA;AAAA,MACV,SAAA,EAAW,EAAA,CAAG,iCAAA,EAAmC,SAAS;AAAA,KAAA,EACtD,KAAA;AAAA,GACN;AAEJ;AAEA,SAAS,WAAW,EAAA,EAG4B;AAH5B,EAAA,IAAA,EAAA,GAAA,EAAA,EAClB;AAAA,IAAA;AAAA,GAtHF,GAqHoB,EAAA,EAEf,KAAA,GAAA,SAAA,CAFe,EAAA,EAEf;AAAA,IADH;AAAA,GAAA,CAAA;AAGA,EAAA,uBACE,GAAA;AAAA,IAAgB,cAAA,CAAA,KAAA;AAAA,IAAf,cAAA,CAAA;AAAA,MACC,WAAA,EAAU,aAAA;AAAA,MACV,SAAA,EAAW,EAAA,CAAG,+BAAA,EAAiC,SAAS;AAAA,KAAA,EACpD,KAAA;AAAA,GACN;AAEJ;AAEA,SAAS,iBAAiB,EAAA,EAG4B;AAH5B,EAAA,IAAA,EAAA,GAAA,EAAA,EACxB;AAAA,IAAA;AAAA,GAnIF,GAkI0B,EAAA,EAErB,KAAA,GAAA,SAAA,CAFqB,EAAA,EAErB;AAAA,IADH;AAAA,GAAA,CAAA;AAGA,EAAA,uBACE,GAAA;AAAA,IAAgB,cAAA,CAAA,WAAA;AAAA,IAAf,cAAA,CAAA;AAAA,MACC,WAAA,EAAU,mBAAA;AAAA,MACV,SAAA,EAAW,EAAA,CAAG,+BAAA,EAAiC,SAAS;AAAA,KAAA,EACpD,KAAA;AAAA,GACN;AAEJ;AC1HA,SAAS,gBAAgB,EAAA,EAG4B;AAH5B,EAAA,IAAA,EAAA,GAAA,EAAA,EACvB;AAAA,IAAA,aAAA,GAAgB;AAAA,GApBlB,GAmByB,EAAA,EAEpB,KAAA,GAAA,SAAA,CAFoB,EAAA,EAEpB;AAAA,IADH;AAAA,GAAA,CAAA;AAGA,EAAA,uBACEA,GAAAA;AAAA,IAAkB,gBAAA,CAAA,QAAA;AAAA,IAAjB,cAAA,CAAA;AAAA,MACC,WAAA,EAAU,kBAAA;AAAA,MACV;AAAA,KAAA,EACI,KAAA;AAAA,GACN;AAEJ;AAEA,SAAS,QAAQ,KAAA,EAAqD;AACpE,EAAA,uBACEA,GAAAA,CAAC,eAAA,EAAA,EACC,QAAA,kBAAAA,GAAAA,CAAkB,uBAAjB,cAAA,CAAA,EAAsB,WAAA,EAAU,SAAA,EAAA,EAAc,KAAA,CAAO,CAAA,EACxD,CAAA;AAEJ;AAEA,SAAS,eACP,KAAA,EACA;AACA,EAAA,uBAAOA,GAAAA,CAAkB,gBAAA,CAAA,OAAA,EAAjB,cAAA,CAAA,EAAyB,WAAA,EAAU,qBAAsB,KAAA,CAAO,CAAA;AAC1E;AAEA,SAAS,eAAe,EAAA,EAK4B;AAL5B,EAAA,IAAA,EAAA,GAAA,EAAA,EACtB;AAAA,IAAA,SAAA;AAAA,IACA,UAAA,GAAa,CAAA;AAAA,IACb;AAAA,GAjDF,GA8CwB,EAAA,EAInB,KAAA,GAAA,SAAA,CAJmB,EAAA,EAInB;AAAA,IAHH,WAAA;AAAA,IACA,YAAA;AAAA,IACA;AAAA,GAAA,CAAA;AAGA,EAAA,uBACEA,GAAAA,CAAkB,gBAAA,CAAA,MAAA,EAAjB,EACC,QAAA,kBAAAC,IAAAA;AAAA,IAAkB,gBAAA,CAAA,OAAA;AAAA,IAAjB,aAAA,CAAA,cAAA,CAAA;AAAA,MACC,WAAA,EAAU,iBAAA;AAAA,MACV,UAAA;AAAA,MACA,SAAA,EAAW,EAAA;AAAA,QACT,gRAAA;AAAA,QACA;AAAA;AACF,KAAA,EACI,KAAA,CAAA,EAPL;AAAA,MASE,QAAA,EAAA;AAAA,QAAA,QAAA;AAAA,wBACDD,GAAAA,CAAkB,gBAAA,CAAA,KAAA,EAAjB,EAAuB,WAAU,8FAAA,EAA+F;AAAA;AAAA,KAAA;AAAA,GACnI,EACF,CAAA;AAEJ;AClDA,SAAS,OAAO,EAAA,EAGgC;AAHhC,EAAA,IAAA,EAAA,GAAA,EAAA,EACd;AAAA,IAAA;AAAA,GAnBF,GAkBgB,EAAA,EAEX,KAAA,GAAA,SAAA,CAFW,EAAA,EAEX;AAAA,IADH;AAAA,GAAA,CAAA;AAGA,EAAA,uBACEA,GAAAA;AAAA,IAAiB,eAAA,CAAA,IAAA;AAAA,IAAhB,cAAA,CAAA;AAAA,MACC,WAAA,EAAU,QAAA;AAAA,MACV,SAAA,EAAW,EAAA;AAAA,QACT,4DAAA;AAAA,QACA;AAAA;AACF,KAAA,EACI,KAAA;AAAA,GACN;AAEJ;AAEA,SAAS,YAAY,EAAA,EAG4B;AAH5B,EAAA,IAAA,EAAA,GAAA,EAAA,EACnB;AAAA,IAAA;AAAA,GAnCF,GAkCqB,EAAA,EAEhB,KAAA,GAAA,SAAA,CAFgB,EAAA,EAEhB;AAAA,IADH;AAAA,GAAA,CAAA;AAGA,EAAA,uBACEA,GAAAA;AAAA,IAAiB,eAAA,CAAA,KAAA;AAAA,IAAhB,cAAA,CAAA;AAAA,MACC,WAAA,EAAU,cAAA;AAAA,MACV,SAAA,EAAW,EAAA,CAAG,yBAAA,EAA2B,SAAS;AAAA,KAAA,EAC9C,KAAA;AAAA,GACN;AAEJ;AAEA,SAAS,eAAe,EAAA,EAG4B;AAH5B,EAAA,IAAA,EAAA,GAAA,EAAA,EACtB;AAAA,IAAA;AAAA,GAhDF,GA+CwB,EAAA,EAEnB,KAAA,GAAA,SAAA,CAFmB,EAAA,EAEnB;AAAA,IADH;AAAA,GAAA,CAAA;AAGA,EAAA,uBACEA,GAAAA;AAAA,IAAiB,eAAA,CAAA,QAAA;AAAA,IAAhB,cAAA,CAAA;AAAA,MACC,WAAA,EAAU,iBAAA;AAAA,MACV,SAAA,EAAW,EAAA;AAAA,QACT,sFAAA;AAAA,QACA;AAAA;AACF,KAAA,EACI,KAAA;AAAA,GACN;AAEJ;ACrCA,IAAM,cAAA,GAAiB,GAAA;AAAA,EACrB,uZAAA;AAAA,EACA;AAAA,IACE,QAAA,EAAU;AAAA,MACR,OAAA,EAAS;AAAA,QACP,OAAA,EACE,kEAAA;AAAA,QACF,WAAA,EACE,gHAAA;AAAA,QACF,OAAA,EACE,6EAAA;AAAA,QACF,SAAA,EACE,wEAAA;AAAA,QACF,KAAA,EAAO,8CAAA;AAAA,QACP,IAAA,EAAM;AAAA,OACR;AAAA,MACA,IAAA,EAAM;AAAA,QACJ,OAAA,EAAS,gCAAA;AAAA,QACT,EAAA,EAAI,+CAAA;AAAA,QACJ,EAAA,EAAI,sCAAA;AAAA,QACJ,IAAA,EAAM;AAAA;AACR,KACF;AAAA,IACA,eAAA,EAAiB;AAAA,MACf,OAAA,EAAS,SAAA;AAAA,MACT,IAAA,EAAM;AAAA;AACR;AAEJ;AAEA,SAAS,OAAO,EAAA,EAcT;AAdS,EAAA,IAAA,EAAA,GAAA,EAAA,EACZ;AAAA,IAAA,SAAA;AAAA,IACA,OAAA;AAAA,IACA,IAAA;AAAA,IACA,OAAA,GAAU,KAAA;AAAA,IACV,OAAA,GAAU,KAAA;AAAA,IACV,QAAA;AAAA,IACA;AAAA,GA7DJ,GAsDgB,EAAA,EAQT,KAAA,GAAA,SAAA,CARS,EAAA,EAQT;AAAA,IAPH,WAAA;AAAA,IACA,SAAA;AAAA,IACA,MAAA;AAAA,IACA,SAAA;AAAA,IACA,SAAA;AAAA,IACA,UAAA;AAAA,IACA;AAAA,GAAA,CAAA;AAQA,EAAA,MAAM,IAAA,GAAO,UAAU,IAAA,GAAO,QAAA;AAC9B,EAAA,uBACIC,IAAAA;AAAA,IAAC,IAAA;AAAA,IAAA,aAAA,CAAA,cAAA,CAAA;AAAA,MACG,WAAA,EAAU,QAAA;AAAA,MACV,UAAU,QAAA,IAAY,OAAA;AAAA,MACtB,SAAA,EAAW,GAAG,cAAA,CAAe,EAAE,SAAS,IAAA,EAAM,SAAA,EAAW,CAAC;AAAA,KAAA,EACtD,KAAA,CAAA,EAJP;AAAA,MAMI,QAAA,EAAA;AAAA,QAAA,OAAA,oBAAWD,GAAAA,CAAC,OAAA,EAAA,EAAQ,SAAA,EAAU,cAAA,EAAe,CAAA;AAAA,QAC7C;AAAA;AAAA,KAAA;AAAA,GACL;AAER;AC3DA,SAAS,aACP,KAAA,EACA;AACA,EAAA,uBAAOA,GAAAA,CAAuB,qBAAA,CAAA,IAAA,EAAtB,cAAA,CAAA,EAA2B,WAAA,EAAU,mBAAoB,KAAA,CAAO,CAAA;AAC1E;AAEA,SAAS,oBACP,KAAA,EACA;AACA,EAAA,uBACEA,GAAAA;AAAA,IAAuB,qBAAA,CAAA,OAAA;AAAA,IAAtB,cAAA,CAAA;AAAA,MACC,WAAA,EAAU;AAAA,KAAA,EACN,KAAA;AAAA,GACN;AAEJ;AAEA,SAAS,oBAAoB,EAAA,EAI4B;AAJ5B,EAAA,IAAA,EAAA,GAAA,EAAA,EAC3B;AAAA,IAAA,SAAA;AAAA,IACA,UAAA,GAAa;AAAA,GAzCf,GAuC6B,EAAA,EAGxB,KAAA,GAAA,SAAA,CAHwB,EAAA,EAGxB;AAAA,IAFH,WAAA;AAAA,IACA;AAAA,GAAA,CAAA;AAGA,EAAA,uBACEA,GAAAA,CAAuB,qBAAA,CAAA,MAAA,EAAtB,EACC,QAAA,kBAAAA,GAAAA;AAAA,IAAuB,qBAAA,CAAA,OAAA;AAAA,IAAtB,cAAA,CAAA;AAAA,MACC,WAAA,EAAU,uBAAA;AAAA,MACV,UAAA;AAAA,MACA,SAAA,EAAW,EAAA;AAAA,QACT,2RAAA;AAAA,QACA;AAAA;AACF,KAAA,EACI,KAAA;AAAA,GACN,EACF,CAAA;AAEJ;AAEA,SAAS,iBAAiB,EAAA,EAQvB;AARuB,EAAA,IAAA,EAAA,GAAA,EAAA,EACxB;AAAA,IAAA,SAAA;AAAA,IACA,KAAA;AAAA,IACA,OAAA,GAAU;AAAA,GA9DZ,GA2D0B,EAAA,EAIrB,KAAA,GAAA,SAAA,CAJqB,EAAA,EAIrB;AAAA,IAHH,WAAA;AAAA,IACA,OAAA;AAAA,IACA;AAAA,GAAA,CAAA;AAMA,EAAA,uBACEA,GAAAA;AAAA,IAAuB,qBAAA,CAAA,IAAA;AAAA,IAAtB,cAAA,CAAA;AAAA,MACC,WAAA,EAAU,oBAAA;AAAA,MACV,YAAA,EAAY,KAAA;AAAA,MACZ,cAAA,EAAc,OAAA;AAAA,MACd,SAAA,EAAW,EAAA;AAAA,QACT,0ZAAA;AAAA,QACA;AAAA;AACF,KAAA,EACI,KAAA;AAAA,GACN;AAEJ;AAEA,SAAS,kBAAkB,EAAA,EAMxB;AANwB,EAAA,IAAA,EAAA,GAAA,EAAA,EACzB;AAAA,IAAA,SAAA;AAAA,IACA;AAAA,GApFF,GAkF2B,EAAA,EAGtB,KAAA,GAAA,SAAA,CAHsB,EAAA,EAGtB;AAAA,IAFH,WAAA;AAAA,IACA;AAAA,GAAA,CAAA;AAKA,EAAA,uBACEA,GAAAA;AAAA,IAAuB,qBAAA,CAAA,KAAA;AAAA,IAAtB,cAAA,CAAA;AAAA,MACC,WAAA,EAAU,qBAAA;AAAA,MACV,YAAA,EAAY,KAAA;AAAA,MACZ,SAAA,EAAW,EAAA;AAAA,QACT,mDAAA;AAAA,QACA;AAAA;AACF,KAAA,EACI,KAAA;AAAA,GACN;AAEJ;AAEA,SAAS,sBAAsB,EAAA,EAG4B;AAH5B,EAAA,IAAA,EAAA,GAAA,EAAA,EAC7B;AAAA,IAAA;AAAA,GAvGF,GAsG+B,EAAA,EAE1B,KAAA,GAAA,SAAA,CAF0B,EAAA,EAE1B;AAAA,IADH;AAAA,GAAA,CAAA;AAGA,EAAA,uBACEA,GAAAA;AAAA,IAAuB,qBAAA,CAAA,SAAA;AAAA,IAAtB,cAAA,CAAA;AAAA,MACC,WAAA,EAAU,yBAAA;AAAA,MACV,SAAA,EAAW,EAAA,CAAG,2BAAA,EAA6B,SAAS;AAAA,KAAA,EAChD,KAAA;AAAA,GACN;AAEJ;ACjGA,SAASE,WAAU,EAAA,EAKgC;AALhC,EAAA,IAAA,EAAA,GAAA,EAAA,EACjB;AAAA,IAAA,SAAA;AAAA,IACA,WAAA,GAAc,YAAA;AAAA,IACd,UAAA,GAAa;AAAA,GAnBf,GAgBmB,EAAA,EAId,KAAA,GAAA,SAAA,CAJc,EAAA,EAId;AAAA,IAHH,WAAA;AAAA,IACA,aAAA;AAAA,IACA;AAAA,GAAA,CAAA;AAGA,EAAA,uBACEF,GAAAA;AAAA,IAAoB,kBAAA,CAAA,IAAA;AAAA,IAAnB,cAAA,CAAA;AAAA,MACC,WAAA,EAAU,WAAA;AAAA,MACV,UAAA;AAAA,MACA,WAAA;AAAA,MACA,SAAA,EAAW,EAAA;AAAA,QACT,gKAAA;AAAA,QACA;AAAA;AACF,KAAA,EACI,KAAA;AAAA,GACN;AAEJ;ACZA,IAAM,kBAAA,GAAqB,aAAA;AAAA,EACzB;AACF,CAAA;AAEO,SAAS,cAAA,GAAiB;AAC/B,EAAA,MAAM,GAAA,GAAM,WAAW,kBAAkB,CAAA;AACzC,EAAA,IAAI,CAAC,GAAA,EAAK;AACR,IAAA,MAAM,IAAI,MAAM,wHAAkD,CAAA;AAAA,EACpE;AACA,EAAA,OAAO,GAAA;AACT;AAEO,SAAS,mBAAA,CAAoB;AAAA,EAClC,KAAA;AAAA,EACA;AACF,CAAA,EAGG;AACD,EAAA,uBACEA,GAAAA,CAAC,kBAAA,CAAmB,QAAA,EAAnB,EAA4B,OAC1B,QAAA,EACH,CAAA;AAEJ;ACHA,SAAS,mBAAmB,KAAA,EAAoC;AAC9D,EAAA,IAAI,CAAC,KAAA,EAAO,OAAO,EAAC;AACpB,EAAA,MAAM,QAAuB,EAAC;AAC9B,EAAA,IAAI,KAAA,CAAM,UAAA,EAAY,KAAA,CAAM,eAAA,GAAkB,KAAA,CAAM,UAAA;AACpD,EAAA,IAAI,KAAA,CAAM,UAAA,EAAY,KAAA,CAAM,KAAA,GAAQ,KAAA,CAAM,UAAA;AAC1C,EAAA,IAAI,KAAA,CAAM,MAAA,EAAQ,KAAA,CAAM,WAAA,GAAc,KAAA,CAAM,MAAA;AAC5C,EAAA,OAAO,KAAA;AACT;AAuBA,SAAS,SAAS,IAAA,EAAc;AAC9B,EAAA,OAAO,IAAA,CACJ,IAAA,EAAK,CACL,KAAA,CAAM,KAAK,CAAA,CACX,KAAA,CAAM,CAAA,EAAG,CAAC,CAAA,CACV,GAAA,CAAI,CAAC,CAAA,KAAG;AA9Eb,IAAA,IAAA,EAAA,EAAA,EAAA;AA8EgB,IAAA,OAAA,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,CAAA,CAAE,CAAC,CAAA,KAAH,IAAA,GAAA,MAAA,GAAA,EAAA,CAAM,WAAA,EAAA,KAAN,IAAA,GAAA,EAAA,GAAuB,EAAA;AAAA,EAAA,CAAE,CAAA,CACpC,KAAK,EAAE,CAAA;AACZ;AAEO,SAAS,WAAA,CAAY;AAAA,EAC1B,KAAA;AAAA,EACA,IAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAA;AAAA,EACA,aAAA;AAAA,EACA,WAAA;AAAA,EACA,aAAA;AAAA,EACA,KAAA;AAAA,EACA;AACF,CAAA,EAAqB;AACnB,EAAA,MAAM,EAAE,QAAA,EAAU,aAAA,EAAe,eAAA,KAAoB,cAAA,EAAe;AACpE,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAIG,SAAS,KAAK,CAAA;AACtD,EAAA,MAAM,OAAQ,aAAA,IAAA,IAAA,GAAA,aAAA,GAAiB,GAAA;AAE/B,EAAA,uBACEF,IAAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,mBAAmB,KAAK,CAAA;AAAA,MAC/B,SAAA,EAAW,EAAA;AAAA,QACT,mFAAA;AAAA,QACA;AAAA,OACF;AAAA,MAEC,QAAA,EAAA;AAAA,QAAA,QAAA,mBACCD,GAAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,OAAA,EAAQ,OAAA;AAAA,YACR,IAAA,EAAK,MAAA;AAAA,YACL,YAAA,EAAW,2BAAA;AAAA,YACX,OAAA,EAAS,MAAM,aAAA,CAAc,IAAI,CAAA;AAAA,YAEjC,QAAA,kBAAAA,GAAAA,CAAC,IAAA,EAAA,EAAK,SAAA,EAAU,QAAA,EAAS;AAAA;AAAA,4BAG3BA,GAAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,OAAA,EAAQ,OAAA;AAAA,YACR,IAAA,EAAK,MAAA;AAAA,YACL,YAAA,EAAW,uCAAA;AAAA,YACX,OAAA,EAAS,eAAA;AAAA,YAET,QAAA,kBAAAA,GAAAA,CAAC,SAAA,EAAA,EAAU,SAAA,EAAU,QAAA,EAAS;AAAA;AAAA,SAChC;AAAA,QAGD,KAAA,IAAS,IAAA,oBACRC,IAAAA,CAAA,QAAA,EAAA,EACE,QAAA,EAAA;AAAA,0BAAAD,IAACE,UAAAA,EAAA,EAAU,WAAA,EAAY,UAAA,EAAW,WAAU,UAAA,EAAW,CAAA;AAAA,0BACvDF,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,2BAA2B,QAAA,EAAA,KAAA,EAAM;AAAA,SAAA,EAClD,CAAA;AAAA,wBAGFC,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,iCAAA,EACZ,QAAA,EAAA;AAAA,UAAA,OAAA;AAAA,UACA,wBACCA,IAAAA,CAAC,gBAAa,IAAA,EAAM,YAAA,EAAc,cAAc,eAAA,EAC9C,QAAA,EAAA;AAAA,4BAAAD,GAAAA,CAAC,mBAAA,EAAA,EAAoB,OAAA,EAAO,IAAA,EAC1B,QAAA,kBAAAC,IAAAA;AAAA,cAAC,MAAA;AAAA,cAAA;AAAA,gBACC,OAAA,EAAQ,OAAA;AAAA,gBACR,SAAA,EAAU,0BAAA;AAAA,gBACV,YAAA,EAAW,iCAAA;AAAA,gBAEX,QAAA,EAAA;AAAA,kCAAAA,KAAC,MAAA,EAAA,EACE,QAAA,EAAA;AAAA,oBAAA,IAAA,CAAK,SAAA,oBACJD,GAAAA,CAAC,WAAA,EAAA,EAAY,KAAK,IAAA,CAAK,SAAA,EAAW,GAAA,EAAK,IAAA,CAAK,IAAA,EAAM,CAAA;AAAA,oCAEpDA,IAAC,cAAA,EAAA,EAAe,SAAA,EAAU,iCACvB,QAAA,EAAA,QAAA,CAAS,IAAA,CAAK,IAAI,CAAA,EACrB;AAAA,mBAAA,EACF,CAAA;AAAA,kCACAC,IAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,iDAAA,EACd,QAAA,EAAA;AAAA,oCAAAD,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,mBAAA,EAAqB,eAAK,IAAA,EAAK,CAAA;AAAA,oBAC9C,IAAA,CAAK,wBACJA,GAAAA,CAAC,UAAK,SAAA,EAAU,qCAAA,EACb,eAAK,IAAA,EACR;AAAA,mBAAA,EAEJ,CAAA;AAAA,kCACAA,GAAAA;AAAA,oBAAC,WAAA;AAAA,oBAAA;AAAA,sBACC,SAAA,EAAW,EAAA;AAAA,wBACT,4DAAA;AAAA,wBACA,YAAA,IAAgB;AAAA;AAClB;AAAA;AACF;AAAA;AAAA,aACF,EACF,CAAA;AAAA,4BACAC,IAAAA,CAAC,mBAAA,EAAA,EAAoB,KAAA,EAAM,KAAA,EAAM,WAAU,UAAA,EACzC,QAAA,EAAA;AAAA,8BAAAD,IAAC,iBAAA,EAAA,EACC,QAAA,kBAAAC,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,eAAA,EACb,QAAA,EAAA;AAAA,gCAAAD,GAAAA,CAAC,MAAA,EAAA,EAAM,QAAA,EAAA,IAAA,CAAK,IAAA,EAAK,CAAA;AAAA,gBAChB,IAAA,CAAK,yBACJA,GAAAA,CAAC,UAAK,SAAA,EAAU,2CAAA,EACb,eAAK,KAAA,EACR;AAAA,eAAA,EAEJ,CAAA,EACF,CAAA;AAAA,8BACAA,IAAC,qBAAA,EAAA,EAAsB,CAAA;AAAA,cACtB,aAAA,IAAA,IAAA,GAAA,aAAA,GACE,WAAA,mBACCA,GAAAA,CAAC,gBAAA,EAAA,EAAiB,OAAA,EAAO,IAAA,EACvB,QAAA,kBAAAC,IAAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAM,WAAA,EACV,QAAA,EAAA;AAAA,gCAAAD,GAAAA,CAAC,IAAA,EAAA,EAAK,SAAA,EAAU,QAAA,EAAS,CAAA;AAAA,gBAAE;AAAA,eAAA,EAE7B,CAAA,EACF,CAAA,mBAEAC,IAAAA,CAAC,gBAAA,EAAA,EACC,QAAA,EAAA;AAAA,gCAAAD,GAAAA,CAAC,IAAA,EAAA,EAAK,SAAA,EAAU,QAAA,EAAS,CAAA;AAAA,gBAAE;AAAA,eAAA,EAE7B,CAAA;AAAA,cAEH,QAAA,oBACCC,IAAAA,CAAA,QAAA,EAAA,EACE,QAAA,EAAA;AAAA,gCAAAD,IAAC,qBAAA,EAAA,EAAsB,CAAA;AAAA,gCACvBC,IAAAA,CAAC,gBAAA,EAAA,EAAiB,OAAA,EAAQ,aAAA,EAAc,UAAU,QAAA,EAChD,QAAA,EAAA;AAAA,kCAAAD,GAAAA,CAAC,MAAA,EAAA,EAAO,SAAA,EAAU,QAAA,EAAS,CAAA;AAAA,kBAAE;AAAA,iBAAA,EAE/B;AAAA,eAAA,EACF;AAAA,aAAA,EAEJ;AAAA,WAAA,EACF;AAAA,SAAA,EAEJ;AAAA;AAAA;AAAA,GACF;AAEJ;AC5KO,SAAS,oBACd,KAAA,EACe;AACf,EAAA,IAAI,CAAC,KAAA,EAAO,OAAO,EAAC;AACpB,EAAA,MAAM,QAAgC,EAAC;AACvC,EAAA,IAAI,KAAA,CAAM,UAAA,EAAY,KAAA,CAAM,WAAW,IAAI,KAAA,CAAM,UAAA;AACjD,EAAA,IAAI,KAAA,CAAM,UAAA,EAAY,KAAA,CAAM,sBAAsB,IAAI,KAAA,CAAM,UAAA;AAC5D,EAAA,IAAI,KAAA,CAAM,MAAA,EAAQ,KAAA,CAAM,kBAAkB,IAAI,KAAA,CAAM,MAAA;AACpD,EAAA,IAAI,KAAA,CAAM,gBAAA;AACR,IAAA,KAAA,CAAM,6BAA6B,IAAI,KAAA,CAAM,gBAAA;AAC/C,EAAA,IAAI,KAAA,CAAM,MAAA,EAAQ,KAAA,CAAM,kBAAkB,IAAI,KAAA,CAAM,MAAA;AACpD,EAAA,IAAI,KAAA,CAAM,OAAA,EAAS,KAAA,CAAM,mBAAmB,IAAI,KAAA,CAAM,OAAA;AACtD,EAAA,IAAI,KAAA,CAAM,iBAAA;AACR,IAAA,KAAA,CAAM,8BAA8B,IAAI,KAAA,CAAM,iBAAA;AAChD,EAAA,IAAI,KAAA,CAAM,IAAA,EAAM,KAAA,CAAM,gBAAgB,IAAI,KAAA,CAAM,IAAA;AAChD,EAAA,OAAO,KAAA;AACT;AAoCA,SAAS,gBAAgB,GAAA,EAAyC;AAChE,EAAA,IAAI,GAAA,CAAI,MAAA,KAAW,CAAA,EAAG,OAAO,EAAC;AAC9B,EAAA,MAAM,kBAAkB,GAAA,CAAI,KAAA;AAAA,IAC1B,CAAC,KAAA,KACC,KAAA,CAAM,OAAA,CAAS,KAAA,CAAmB,KAAK,CAAA,IACtC,KAAA,CAAkB,IAAA,KAAS,MAAA,IAC3B,KAAA,CAAkB,IAAA,KAAS;AAAA,GAChC;AACA,EAAA,IAAI,iBAAiB,OAAO,GAAA;AAC5B,EAAA,OAAO,CAAC,EAAE,KAAA,EAAO,GAAA,EAAkB,CAAA;AACrC;AAGA,SAAS,YAAA,CAAa,MAAe,QAAA,EAA4B;AApGjE,EAAA,IAAA,EAAA,EAAA,EAAA;AAqGE,EAAA,IAAI,CAAC,UAAU,OAAO,KAAA;AACtB,EAAA,IAAI,KAAK,IAAA,EAAM;AACb,IAAA,IAAI,IAAA,CAAK,KAAA,EAAO,OAAO,QAAA,KAAa,IAAA,CAAK,IAAA;AACzC,IAAA,IAAI,QAAA,KAAa,IAAA,CAAK,IAAA,EAAM,OAAO,IAAA;AACnC,IAAA,IAAI,IAAA,CAAK,SAAS,GAAA,IAAO,QAAA,CAAS,WAAW,IAAA,CAAK,IAAA,GAAO,GAAG,CAAA,EAAG,OAAO,IAAA;AAAA,EACxE;AACA,EAAA,OAAA,CAAO,EAAA,GAAA,CAAA,EAAA,GAAA,IAAA,CAAK,KAAA,KAAL,IAAA,GAAA,MAAA,GAAA,EAAA,CAAY,IAAA,CAAK,CAAC,UAAU,YAAA,CAAa,KAAA,EAAO,QAAQ,CAAA,CAAA,KAAxD,IAAA,GAAA,EAAA,GAA8D,KAAA;AACvE;AAEA,IAAM,aAAA,GACJ,yPAAA;AACF,IAAM,eAAA,GACJ,gEAAA;AAEF,SAAS,KAAA,CAAM,EAAE,KAAA,EAAM,EAA+B;AACpD,EAAA,uBACEA,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,0IACb,QAAA,EAAA,KAAA,EACH,CAAA;AAEJ;AAGA,SAAS,WAAA,CAAY;AAAA,EACnB,IAAA;AAAA,EACA,QAAA;AAAA,EACA,aAAA;AAAA,EACA,SAAA;AAAA,EACA,UAAA;AAAA,EACA;AACF,CAAA,EAOG;AACD,EAAA,MAAM,MAAA,GAAS,YAAA,CAAa,IAAA,EAAM,QAAQ,CAAA;AAC1C,EAAA,MAAM,OAAO,IAAA,CAAK,IAAA;AAClB,EAAA,MAAM,OAAQ,aAAA,IAAA,IAAA,GAAA,aAAA,GAAiB,GAAA;AAE/B,EAAA,MAAM,OAAA,mBACJC,IAAAA,CAAAG,QAAAA,EAAA,EACG,QAAA,EAAA;AAAA,IAAA,IAAA,mBAAOJ,GAAAA,CAAC,IAAA,EAAA,EAAK,SAAA,EAAU,mBAAkB,CAAA,GAAK,IAAA;AAAA,IAC9C,CAAC,6BAAaA,GAAAA,CAAC,UAAK,SAAA,EAAU,UAAA,EAAY,eAAK,KAAA,EAAM,CAAA;AAAA,IACrD,CAAC,SAAA,IAAa,IAAA,CAAK,KAAA,IAAS,IAAA,oBAAQA,GAAAA,CAAC,KAAA,EAAA,EAAM,KAAA,EAAO,IAAA,CAAK,KAAA,EAAO;AAAA,GAAA,EACjE,CAAA;AAGF,EAAA,MAAM,SAAA,GAAY,EAAA;AAAA,IAChB,aAAA;AAAA,IACA,MAAA,IAAU,CAAC,SAAA,IAAa,kBAAA;AAAA,IACxB,SAAA,IAAa,qBAAA;AAAA,IACb,MAAA,IAAU,eAAA;AAAA,IACV,KAAK,QAAA,IAAY;AAAA,GACnB;AAEA,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,IAAA,mBAClBA,GAAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACC,MAAM,IAAA,CAAK,IAAA;AAAA,MACX,SAAA;AAAA,MACA,cAAA,EAAc,SAAS,MAAA,GAAS,MAAA;AAAA,MAChC,OAAA,EAAS,UAAA;AAAA,MAER,QAAA,EAAA;AAAA;AAAA,GACH,mBAEAA,GAAAA,CAAC,MAAA,EAAA,EAAK,WAAuB,QAAA,EAAA,OAAA,EAAQ,CAAA;AAIvC,EAAA,IAAI,SAAA,IAAa,KAAK,IAAA,EAAM;AAC1B,IAAA,uBACEC,KAAC,OAAA,EAAA,EACC,QAAA,EAAA;AAAA,sBAAAD,GAAAA,CAAC,cAAA,EAAA,EAAe,OAAA,EAAO,IAAA,EAAE,QAAA,EAAA,MAAA,EAAO,CAAA;AAAA,sBAChCA,GAAAA,CAAC,cAAA,EAAA,EAAe,IAAA,EAAK,OAAA,EAAS,eAAK,KAAA,EAAM;AAAA,KAAA,EAC3C,CAAA;AAAA,EAEJ;AACA,EAAA,OAAO,MAAA;AACT;AAGA,SAAS,kBAAA,CAAmB;AAAA,EAC1B,IAAA;AAAA,EACA,QAAA;AAAA,EACA,aAAA;AAAA,EACA;AACF,CAAA,EAKG;AACD,EAAA,MAAM,MAAA,GAAS,YAAA,CAAa,IAAA,EAAM,QAAQ,CAAA;AAC1C,EAAA,MAAM,OAAO,IAAA,CAAK,IAAA;AAIlB,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAIG,SAAyB,IAAI,CAAA;AAC7D,EAAA,MAAM,OAAO,QAAA,IAAA,IAAA,GAAA,QAAA,GAAY,MAAA;AAEzB,EAAA,uBACEF,KAAC,IAAA,EAAA,EACC,QAAA,EAAA;AAAA,oBAAAA,IAAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,QAAA;AAAA,QACL,OAAA,EAAS,MAAM,WAAA,CAAY,CAAC,IAAI,CAAA;AAAA,QAChC,eAAA,EAAe,IAAA;AAAA,QACf,SAAA,EAAW,EAAA,CAAG,aAAA,EAAe,QAAA,EAAU,UAAU,yBAAyB,CAAA;AAAA,QAEzE,QAAA,EAAA;AAAA,UAAA,IAAA,mBAAOD,GAAAA,CAAC,IAAA,EAAA,EAAK,SAAA,EAAU,mBAAkB,CAAA,GAAK,IAAA;AAAA,0BAC/CA,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,UAAA,EAAY,eAAK,KAAA,EAAM,CAAA;AAAA,0BACvCA,GAAAA;AAAA,YAAC,YAAA;AAAA,YAAA;AAAA,cACC,SAAA,EAAW,EAAA;AAAA,gBACT,8CAAA;AAAA,gBACA,IAAA,IAAQ;AAAA;AACV;AAAA;AACF;AAAA;AAAA,KACF;AAAA,IACC,IAAA,oBACCA,GAAAA,CAAC,IAAA,EAAA,EAAG,WAAU,gBAAA,EACX,QAAA,EAAA,IAAA,CAAK,KAAA,CAAO,GAAA,CAAI,CAAC,KAAA,qBAChBA,GAAAA,CAAC,QACC,QAAA,kBAAAA,GAAAA;AAAA,MAAC,WAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAM,KAAA;AAAA,QACN,QAAA;AAAA,QACA,aAAA;AAAA,QACA,UAAA;AAAA,QACA,MAAA,EAAM;AAAA;AAAA,KACR,EAAA,EAPO,KAAA,CAAM,KAQf,CACD,CAAA,EACH;AAAA,GAAA,EAEJ,CAAA;AAEJ;AAEO,SAAS,YAAA,CAAa;AAAA,EAC3B,GAAA;AAAA,EACA,QAAA;AAAA,EACA,aAAA;AAAA,EACA,IAAA;AAAA,EACA,MAAA;AAAA,EACA,SAAA,GAAY,KAAA;AAAA,EACZ,UAAA;AAAA,EACA,KAAA;AAAA,EACA,SAAA;AAAA,EACA;AACF,CAAA,EAAsB;AACpB,EAAA,MAAM,MAAA,GAAS,gBAAgB,GAAG,CAAA;AAClC,EAAA,MAAM,eAAe,OAAO,IAAA,KAAS,UAAA,GAAa,IAAA,CAAK,SAAS,CAAA,GAAI,IAAA;AAEpE,EAAA,uBACEC,IAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,cAAA,CAAA,cAAA,CAAA,EAAA,EAAK,mBAAA,CAAoB,KAAK,CAAA,CAAA,EAAM,KAAA,CAAA;AAAA,MAC3C,SAAA,EAAW,EAAA;AAAA,QACT,yDAAA;AAAA,QACA;AAAA,OACF;AAAA,MAEC,QAAA,EAAA;AAAA,QAAA,YAAA,IAAgB,wBACfD,GAAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAW,EAAA;AAAA,cACT,4DAAA;AAAA,cACA,SAAA,IAAa;AAAA,aACf;AAAA,YAEC,QAAA,EAAA;AAAA;AAAA,SACH;AAAA,wBAGFA,IAAC,KAAA,EAAA,EAAI,SAAA,EAAU,oCACZ,QAAA,EAAA,MAAA,CAAO,GAAA,CAAI,CAAC,KAAA,EAAO,EAAA,KAAI;AAnRhC,UAAA,IAAA,EAAA;AAoRU,UAAA,uBAAAC,KAAC,KAAA,EAAA,EAA4B,SAAA,EAAW,GAAG,EAAA,GAAK,CAAA,IAAK,MAAM,CAAA,EACxD,QAAA,EAAA;AAAA,YAAA,KAAA,CAAM,KAAA,IAAS,CAAC,SAAA,oBACfD,IAAC,GAAA,EAAA,EAAE,SAAA,EAAU,uFAAA,EACV,QAAA,EAAA,KAAA,CAAM,KAAA,EACT,CAAA;AAAA,4BAEFA,GAAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,WAAA,EACX,gBAAM,KAAA,CAAM,GAAA;AAAA,cAAI,CAAC,IAAA,KAChB,IAAA,CAAK,KAAA,IAAS,IAAA,CAAK,MAAM,MAAA,GAAS,CAAA,IAAK,CAAC,SAAA,mBACtCA,GAAAA;AAAA,gBAAC,kBAAA;AAAA,gBAAA;AAAA,kBAEC,IAAA;AAAA,kBACA,QAAA;AAAA,kBACA,aAAA;AAAA,kBACA;AAAA,iBAAA;AAAA,gBAJK,IAAA,CAAK;AAAA,eAKZ,mBAEAA,GAAAA,CAAC,IAAA,EAAA,EACC,QAAA,kBAAAA,GAAAA;AAAA,gBAAC,WAAA;AAAA,gBAAA;AAAA,kBACC,IAAA;AAAA,kBACA,QAAA;AAAA,kBACA,aAAA;AAAA,kBACA,SAAA;AAAA,kBACA;AAAA;AAAA,eACF,EAAA,EAPO,KAAK,KAQd;AAAA,aAEJ,EACF;AAAA,WAAA,EAAA,EAAA,CA5BQ,EAAA,GAAA,KAAA,CAAM,KAAA,KAAN,IAAA,GAAA,EAAA,GAAe,EA6BzB,CAAA;AAAA,QAAA,CACD,CAAA,EACH,CAAA;AAAA,QAEC,UAAU,IAAA,oBACTA,IAAC,KAAA,EAAA,EAAI,SAAA,EAAU,+CACZ,QAAA,EAAA,MAAA,EACH;AAAA;AAAA;AAAA,GAEJ;AAEJ;AChOO,SAAS,cAAA,CAAe;AAAA,EAC7B,QAAA;AAAA,EACA,kBAAA;AAAA,EACA,GAAA;AAAA,EACA,QAAA;AAAA,EACA,aAAA;AAAA,EACA,IAAA;AAAA,EACA,aAAA;AAAA,EACA,YAAA;AAAA,EACA,KAAA;AAAA,EACA,IAAA;AAAA,EACA,aAAA;AAAA,EACA,QAAA;AAAA,EACA,aAAA;AAAA,EACA,WAAA;AAAA,EACA,WAAA;AAAA,EACA,MAAA;AAAA,EACA,gBAAA,GAAmB,KAAA;AAAA,EACnB,gBAAA;AAAA,EACA;AACF,CAAA,EAAwB;AACtB,EAAA,MAAM,WAAW,WAAA,EAAY;AAC7B,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAIG,SAAS,gBAAgB,CAAA;AAC3D,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAIA,SAAS,KAAK,CAAA;AAElD,EAAA,MAAM,QAAA,GAAW,OAAA;AAAA,IACf,OAAO;AAAA,MACL,SAAA;AAAA,MACA,YAAA;AAAA,MACA,iBAAiB,MAAM,YAAA,CAAa,CAAC,CAAA,KAAM,CAAC,CAAC,CAAA;AAAA,MAC7C,UAAA;AAAA,MACA,aAAA;AAAA,MACA;AAAA,KACF,CAAA;AAAA,IACA,CAAC,SAAA,EAAW,UAAA,EAAY,QAAQ;AAAA,GAClC;AAEA,EAAA,MAAM,cAAA,GACJ,QAAA,IAAY,IAAA,GACR,OAAO,aAAa,QAAA,GAClB,EAAE,QAAA,EAAU,CAAA,EAAG,QAAQ,CAAA,EAAA,CAAA,EAAK,GAC5B,EAAE,QAAA,KACJ,EAAC;AAGP,EAAA,IAAI,CAAC,GAAA,EAAK;AACR,IAAA,uBACEH,GAAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,KAAA,EAAO,cAAA;AAAA,QACP,SAAA,EAAW,EAAA;AAAA,UACT,YAAY,IAAA,IAAQ,SAAA;AAAA,UACpB,qBAAA;AAAA,UACA;AAAA,SACF;AAAA,QAEC;AAAA;AAAA,KACH;AAAA,EAEJ;AAGA,EAAA,uBACEA,GAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,cAAA;AAAA,MACP,WAAW,EAAA,CAAG,QAAA,IAAY,IAAA,IAAQ,SAAA,EAAW,UAAU,kBAAkB,CAAA;AAAA,MAEzE,QAAA,kBAAAA,GAAAA,CAAC,eAAA,EAAA,EACC,QAAA,kBAAAA,GAAAA,CAAC,mBAAA,EAAA,EAAoB,KAAA,EAAO,QAAA,EAC1B,QAAA,kBAAAC,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,wCAAA,EAEZ,QAAA,EAAA;AAAA,QAAA,CAAC,4BACAD,GAAAA;AAAA,UAAC,OAAA;AAAA,UAAA;AAAA,YACC,gBAAA,EAAgB,SAAA;AAAA,YAChB,KAAA,EAAO,oBAAoB,YAAY,CAAA;AAAA,YACvC,SAAA,EAAW,EAAA;AAAA,cACT,+FAAA;AAAA,cACA,YAAY,MAAA,GAAS;AAAA,aACvB;AAAA,YAEA,QAAA,kBAAAA,GAAAA;AAAA,cAAC,YAAA;AAAA,cAAA;AAAA,gBACC,GAAA;AAAA,gBACA,QAAA;AAAA,gBACA,aAAA;AAAA,gBACA,IAAA;AAAA,gBACA,MAAA,EAAQ,YAAY,MAAA,GAAY,aAAA;AAAA,gBAChC,SAAA;AAAA,gBACA,KAAA,EAAO;AAAA;AAAA;AACT;AAAA,SACF;AAAA,wBAIFA,GAAAA,CAAC,KAAA,EAAA,EAAM,IAAA,EAAM,YAAY,UAAA,EAAY,YAAA,EAAc,aAAA,EACjD,QAAA,kBAAAC,IAAAA,CAAC,YAAA,EAAA,EAAa,IAAA,EAAK,MAAA,EAAO,WAAU,UAAA,EAClC,QAAA,EAAA;AAAA,0BAAAD,GAAAA,CAAC,UAAA,EAAA,EAAW,SAAA,EAAU,SAAA,EAAU,QAAA,EAAA,iCAAA,EAAM,CAAA;AAAA,0BACtCA,GAAAA;AAAA,YAAC,YAAA;AAAA,YAAA;AAAA,cACC,GAAA;AAAA,cACA,QAAA;AAAA,cACA,aAAA;AAAA,cACA,IAAA;AAAA,cACA,MAAA,EAAQ,aAAA;AAAA,cACR,KAAA,EAAO,YAAA;AAAA,cACP,UAAA,EAAY,MAAM,aAAA,CAAc,KAAK;AAAA;AAAA;AACvC,SAAA,EACF,CAAA,EACF,CAAA;AAAA,wBAGAC,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,8BAAA,EACZ,QAAA,EAAA;AAAA,UAAA,MAAA,IAAA,IAAA,GAAA,MAAA,mBACCD,GAAAA;AAAA,YAAC,WAAA;AAAA,YAAA;AAAA,cACC,KAAA;AAAA,cACA,IAAA;AAAA,cACA,OAAA,EAAS,aAAA;AAAA,cACT,QAAA;AAAA,cACA,aAAA;AAAA,cACA,WAAA;AAAA,cACA,aAAA;AAAA,cACA,KAAA,EAAO;AAAA;AAAA,WACT;AAAA,0BAEFA,GAAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACC,SAAA,EAAW,EAAA;AAAA,gBACT,8CAAA;AAAA,gBACA;AAAA,eACF;AAAA,cAEC;AAAA;AAAA;AACH,SAAA,EACF;AAAA,OAAA,EACF,GACF,CAAA,EACF;AAAA;AAAA,GACF;AAEJ;ACxIO,SAAS,WAAA,CAAY;AAAA,EAC1B,IAAA;AAAA,EACA,GAAA;AAAA,EACA,QAAA;AAAA,EACA,aAAA;AAAA,EACA,IAAA;AAAA,EACA,aAAA;AAAA,EACA,YAAA;AAAA,EACA,KAAA;AAAA,EACA,IAAA;AAAA,EACA,aAAA;AAAA,EACA,QAAA;AAAA,EACA,aAAA;AAAA,EACA,WAAA;AAAA,EACA,WAAA;AAAA,EACA,MAAA;AAAA,EACA,gBAAA,GAAmB,KAAA;AAAA,EACnB,gBAAA;AAAA,EACA;AACF,CAAA,EAAqB;AACnB,EAAA,MAAM,mBAAmB,WAAA,EAAY;AACrC,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAIG,SAAS,gBAAgB,CAAA;AAC3D,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAIA,SAAS,KAAK,CAAA;AAGlD,EAAA,MAAM,WACJ,IAAA,KAAS,QAAA,GAAW,IAAA,GAAO,IAAA,KAAS,YAAY,KAAA,GAAQ,gBAAA;AAE1D,EAAA,MAAM,QAAA,GAAWE,OAAAA;AAAA,IACf,OAAO;AAAA,MACL,SAAA;AAAA,MACA,YAAA;AAAA,MACA,iBAAiB,MAAM,YAAA,CAAa,CAAC,CAAA,KAAM,CAAC,CAAC,CAAA;AAAA,MAC7C,UAAA;AAAA,MACA,aAAA;AAAA,MACA;AAAA,KACF,CAAA;AAAA,IACA,CAAC,SAAA,EAAW,UAAA,EAAY,QAAQ;AAAA,GAClC;AAEA,EAAA,uBACEL,GAAAA,CAAC,eAAA,EAAA,EACC,QAAA,kBAAAA,GAAAA,CAAC,mBAAA,EAAA,EAAoB,KAAA,EAAO,QAAA,EAC1B,QAAA,kBAAAC,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,wCAAA,EAEZ,QAAA,EAAA;AAAA,IAAA,CAAC,4BACAD,GAAAA;AAAA,MAAC,OAAA;AAAA,MAAA;AAAA,QACC,gBAAA,EAAgB,SAAA;AAAA,QAChB,KAAA,EAAO,oBAAoB,YAAY,CAAA;AAAA,QACvC,SAAA,EAAW,EAAA;AAAA,UACT,+FAAA;AAAA,UACA,YAAY,MAAA,GAAS;AAAA,SACvB;AAAA,QAEA,QAAA,kBAAAA,GAAAA;AAAA,UAAC,YAAA;AAAA,UAAA;AAAA,YACC,GAAA;AAAA,YACA,QAAA;AAAA,YACA,aAAA;AAAA,YACA,IAAA;AAAA,YACA,MAAA,EAAQ,YAAY,MAAA,GAAY,aAAA;AAAA,YAChC,SAAA;AAAA,YACA,KAAA,EAAO;AAAA;AAAA;AACT;AAAA,KACF;AAAA,oBAIFA,GAAAA,CAAC,KAAA,EAAA,EAAM,IAAA,EAAM,YAAY,UAAA,EAAY,YAAA,EAAc,aAAA,EACjD,QAAA,kBAAAC,IAAAA,CAAC,YAAA,EAAA,EAAa,IAAA,EAAK,MAAA,EAAO,WAAU,UAAA,EAClC,QAAA,EAAA;AAAA,sBAAAD,GAAAA,CAAC,UAAA,EAAA,EAAW,SAAA,EAAU,SAAA,EAAU,QAAA,EAAA,iCAAA,EAAM,CAAA;AAAA,sBACtCA,GAAAA;AAAA,QAAC,YAAA;AAAA,QAAA;AAAA,UACC,GAAA;AAAA,UACA,QAAA;AAAA,UACA,aAAA;AAAA,UACA,IAAA;AAAA,UACA,MAAA,EAAQ,aAAA;AAAA,UACR,KAAA,EAAO,YAAA;AAAA,UACP,UAAA,EAAY,MAAM,aAAA,CAAc,KAAK;AAAA;AAAA;AACvC,KAAA,EACF,CAAA,EACF,CAAA;AAAA,oBAGAC,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,8BAAA,EACZ,QAAA,EAAA;AAAA,MAAA,MAAA,IAAA,IAAA,GAAA,MAAA,mBACCD,GAAAA;AAAA,QAAC,WAAA;AAAA,QAAA;AAAA,UACC,KAAA;AAAA,UACA,IAAA;AAAA,UACA,OAAA,EAAS,aAAA;AAAA,UACT,QAAA;AAAA,UACA,aAAA;AAAA,UACA,WAAA;AAAA,UACA,aAAA;AAAA,UACA,KAAA,EAAO;AAAA;AAAA,OACT;AAAA,sBAEFA,GAAAA;AAAA,QAAC,MAAA;AAAA,QAAA;AAAA,UACC,SAAA,EAAW,EAAA;AAAA,YACT,8CAAA;AAAA,YACA;AAAA,WACF;AAAA,UAEC;AAAA;AAAA;AACH,KAAA,EACF;AAAA,GAAA,EACF,GACF,CAAA,EACF,CAAA;AAEJ;AC5JO,SAAS,eAAA,CAAgB;AAAA,EAC9B,QAAA;AAAA,EACA,QAAA,GAAW,GAAA;AAAA,EACX;AACF,CAAA,EAAyB;AACvB,EAAA,MAAM,KAAA,GACJ,OAAO,QAAA,KAAa,QAAA,GAChB,EAAE,QAAA,EAAU,CAAA,EAAG,QAAQ,CAAA,EAAA,CAAA,EAAK,GAC5B,EAAE,QAAA,EAAS;AAEjB,EAAA,uBACEA,GAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,EAAA,CAAG,sCAAA,EAAwC,SAAS,CAAA;AAAA,MAC/D,KAAA;AAAA,MAEC;AAAA;AAAA,GACH;AAEJ;ACzBO,SAAS,kBAAA,CAAmB;AAAA,EACjC,OAAA;AAAA,EACA,iBAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA;AACF,CAAA,EAA4B;AAC1B,EAAA,MAAM,KAAA,GAAQ;AAAA,IACZ,OAAA,IAAW,aAAa,OAAO,CAAA,CAAA,CAAA;AAAA,IAC/B,iBAAA,IAAqB,wBAAwB,iBAAiB,CAAA,CAAA,CAAA;AAAA,IAC9D,IAAA,IAAQ,UAAU,IAAI,CAAA,CAAA,CAAA;AAAA,IACtB,GAAG,MAAA,CAAO,OAAA,CAAQ,IAAA,IAAA,IAAA,GAAA,IAAA,GAAQ,EAAE,CAAA,CAAE,GAAA,CAAI,CAAC,CAAC,GAAG,CAAC,CAAA,KAAM,GAAG,CAAC,CAAA,CAAA,EAAI,CAAC,CAAA,CAAA,CAAG;AAAA,GAC5D,CACG,MAAA,CAAO,OAAO,CAAA,CACd,KAAK,EAAE,CAAA;AAEV,EAAA,uBACEC,IAAAA,CAAAG,QAAAA,EAAA,EACG,QAAA,EAAA;AAAA,IAAA,KAAA,oBAASJ,GAAAA,CAAC,OAAA,EAAA,EAAO,QAAA,EAAA,CAAA,MAAA,EAAS,KAAK,CAAA,CAAA,CAAA,EAAI,CAAA;AAAA,IACnC;AAAA,GAAA,EACH,CAAA;AAEJ;ACxBO,SAAS,eAAA,CAAgB;AAAA,EAC9B,KAAA;AAAA,EACA,WAAA;AAAA,EACA,OAAA;AAAA,EACA,UAAA;AAAA,EACA;AACF,CAAA,EAAyB;AACrB,EAAA,uBACIC,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAW,EAAA,CAAG,oEAAA,EAAsE,SAAS,CAAA,EAC9F,QAAA,EAAA;AAAA,oBAAAA,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,WAAA,EACV,QAAA,EAAA;AAAA,MAAA,UAAA;AAAA,sBACDD,GAAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,yCAAyC,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,MAC5D,+BACDA,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,iCAAiC,QAAA,EAAA,WAAA,EAAY;AAAA,KAAA,EAE9D,CAAA;AAAA,IACC,2BACGA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,oCAAoC,QAAA,EAAA,OAAA,EAAQ;AAAA,GAAA,EAEnE,CAAA;AAER;AAUO,SAAS,SAAA,CAAU;AAAA,EACxB,KAAA;AAAA,EACA,WAAA;AAAA,EACA,OAAA;AAAA,EACA,UAAA;AAAA,EACA,SAAA;AAAA,EACA,gBAAA;AAAA,EACA;AACF,CAAA,EAAmB;AACjB,EAAA,uBACEC,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAW,EAAA,CAAG,WAAA,EAAa,SAAS,CAAA,EACvC,QAAA,EAAA;AAAA,oBAAAD,GAAAA;AAAA,MAAC,eAAA;AAAA,MAAA;AAAA,QACC,KAAA;AAAA,QACA,WAAA;AAAA,QACA,OAAA;AAAA,QACA;AAAA;AAAA,KACF;AAAA,oBACAA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,kBAAmB,QAAA,EAAS;AAAA,GAAA,EAC9C,CAAA;AAEJ;;;ACvEO,SAAS,MAAM,KAAA,EAAwB;AAC5C,EAAA,IAAI,UAAU,IAAA,IAAQ,KAAA,KAAU,MAAA,IAAa,KAAA,KAAU,IAAI,OAAO,EAAA;AAClE,EAAA,MAAM,GAAA,GACJ,OAAO,KAAA,KAAU,QAAA,GACb,KAAA,GACA,MAAA,CAAO,MAAA,CAAO,KAAK,CAAA,CAAE,OAAA,CAAQ,IAAA,EAAM,EAAE,CAAC,CAAA;AAC5C,EAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,GAAG,CAAA,EAAG,OAAO,OAAO,KAAK,CAAA;AAC9C,EAAA,OAAO,IAAI,cAAA,CAAe,OAAA,EAAS,EAAE,qBAAA,EAAuB,IAAI,CAAA;AAClE;AAGO,SAAS,IAAI,KAAA,EAAwB;AAC1C,EAAA,IAAI,UAAU,IAAA,IAAQ,KAAA,KAAU,MAAA,IAAa,KAAA,KAAU,IAAI,OAAO,EAAA;AAClE,EAAA,MAAM,IAAI,MAAA,CAAO,KAAK,CAAA,CAAE,OAAA,CAAQ,OAAO,EAAE,CAAA;AAGzC,EAAA,IAAI,CAAA,CAAE,UAAA,CAAW,IAAI,CAAA,EAAG;AACtB,IAAA,IAAI,EAAE,MAAA,KAAW,CAAA,SAAU,CAAA,CAAE,OAAA,CAAQ,yBAAyB,UAAU,CAAA;AACxE,IAAA,IAAI,EAAE,MAAA,KAAW,EAAA,SAAW,CAAA,CAAE,OAAA,CAAQ,yBAAyB,UAAU,CAAA;AAAA,EAC3E;AAEA,EAAA,IAAI,EAAE,MAAA,KAAW,CAAA,SAAU,CAAA,CAAE,OAAA,CAAQ,kBAAkB,OAAO,CAAA;AAE9D,EAAA,IAAI,EAAE,MAAA,KAAW,EAAA,SAAW,CAAA,CAAE,OAAA,CAAQ,yBAAyB,UAAU,CAAA;AAEzE,EAAA,IAAI,EAAE,MAAA,KAAW,EAAA,SAAW,CAAA,CAAE,OAAA,CAAQ,yBAAyB,UAAU,CAAA;AAGzE,EAAA,OAAO,OAAO,KAAK,CAAA;AACrB;AAGO,SAAS,OAAO,KAAA,EAAwB;AAC7C,EAAA,IAAI,UAAU,IAAA,IAAQ,KAAA,KAAU,MAAA,IAAa,KAAA,KAAU,IAAI,OAAO,EAAA;AAClE,EAAA,MAAM,IAAI,MAAA,CAAO,KAAK,CAAA,CAAE,OAAA,CAAQ,OAAO,EAAE,CAAA;AACzC,EAAA,IAAI,EAAE,MAAA,KAAW,EAAA,SAAW,CAAA,CAAE,OAAA,CAAQ,yBAAyB,UAAU,CAAA;AACzE,EAAA,OAAO,OAAO,KAAK,CAAA;AACrB;AAGA,SAAS,OAAO,KAAA,EAA6B;AAC3C,EAAA,IAAI,KAAA,IAAS,IAAA,IAAQ,KAAA,KAAU,EAAA,EAAI,OAAO,IAAA;AAC1C,EAAA,MAAM,CAAA,GAAI,iBAAiB,IAAA,GAAO,KAAA,GAAQ,IAAI,IAAA,CAAK,MAAA,CAAO,KAAK,CAAC,CAAA;AAChE,EAAA,OAAO,OAAO,KAAA,CAAM,CAAA,CAAE,OAAA,EAAS,IAAI,IAAA,GAAO,CAAA;AAC5C;AAEA,SAAS,IAAI,CAAA,EAAmB;AAC9B,EAAA,OAAO,MAAA,CAAO,CAAC,CAAA,CAAE,QAAA,CAAS,GAAG,GAAG,CAAA;AAClC;AAGO,SAAS,WAAW,KAAA,EAAwB;AACjD,EAAA,MAAM,CAAA,GAAI,OAAO,KAAK,CAAA;AACtB,EAAA,IAAI,CAAC,GAAG,OAAO,EAAA;AACf,EAAA,OAAO,GAAG,CAAA,CAAE,WAAA,EAAa,CAAA,CAAA,EAAI,IAAI,CAAA,CAAE,QAAA,EAAS,GAAI,CAAC,CAAC,CAAA,CAAA,EAAI,GAAA,CAAI,CAAA,CAAE,OAAA,EAAS,CAAC,CAAA,CAAA;AACxE;AAGO,SAAS,eAAe,KAAA,EAAwB;AACrD,EAAA,MAAM,CAAA,GAAI,OAAO,KAAK,CAAA;AACtB,EAAA,IAAI,CAAC,GAAG,OAAO,EAAA;AACf,EAAA,OAAO,CAAA,EAAG,WAAW,CAAC,CAAC,IAAI,GAAA,CAAI,CAAA,CAAE,UAAU,CAAC,IAAI,GAAA,CAAI,CAAA,CAAE,YAAY,CAAC,IAAI,GAAA,CAAI,CAAA,CAAE,UAAA,EAAY,CAAC,CAAA,CAAA;AAC5F;AAMO,SAAS,YAAA,CAAa,MAAwB,KAAA,EAAwB;AAC3E,EAAA,QAAQ,IAAA;AAAM,IACZ,KAAK,OAAA;AACH,MAAA,OAAO,MAAM,KAAgB,CAAA;AAAA,IAC/B,KAAK,KAAA;AACH,MAAA,OAAO,IAAI,KAAgB,CAAA;AAAA,IAC7B,KAAK,QAAA;AACH,MAAA,OAAO,OAAO,KAAgB,CAAA;AAAA,IAChC,KAAK,MAAA;AACH,MAAA,OAAO,WAAW,KAAK,CAAA;AAAA,IACzB,KAAK,UAAA;AACH,MAAA,OAAO,eAAe,KAAK,CAAA;AAAA,IAC7B;AACE,MAAA,OAAO,KAAA,IAAS,IAAA,GAAO,EAAA,GAAK,MAAA,CAAO,KAAK,CAAA;AAAA;AAE9C;ACpFA,SAAS,MAAM,EAAA,EAAwD;AAAxD,EAAA,IAAA,EAAA,GAAA,EAAA,EAAE,aAAW,IAAA,EAd5B,GAce,IAAsB,KAAA,GAAA,SAAA,CAAtB,EAAA,EAAsB,CAApB,WAAA,EAAW,MAAA,CAAA,CAAA;AAC1B,EAAA,uBACEA,GAAAA;AAAA,IAAC,OAAA;AAAA,IAAA,cAAA,CAAA;AAAA,MACC,IAAA;AAAA,MACA,WAAA,EAAU,OAAA;AAAA,MACV,SAAA,EAAW,EAAA;AAAA,QACT,kJAAA;AAAA,QACA,0FAAA;AAAA,QACA,kFAAA;AAAA,QACA,+EAAA;AAAA,QACA,iDAAA;AAAA,QACA,kEAAA;AAAA,QACA;AAAA;AACF,KAAA,EACI,KAAA;AAAA,GACN;AAEJ;AChBA,SAASM,OAAM,EAAA,EAAkD;AAAlD,EAAA,IAAA,EAAA,GAAA,EAAA,EAAE,EAAA,SAAA,EAfjB,GAee,EAAA,EAAgB,KAAA,GAAA,SAAA,CAAhB,IAAgB,CAAd,WAAA,CAAA,CAAA;AACf,EAAA,uBACEN,GAAAA;AAAA,IAAC,OAAA;AAAA,IAAA,cAAA,CAAA;AAAA,MACC,WAAA,EAAU,OAAA;AAAA,MACV,SAAA,EAAW,EAAA;AAAA,QACT,sEAAA;AAAA,QACA,2DAAA;AAAA,QACA;AAAA;AACF,KAAA,EACI,KAAA;AAAA,GACN;AAEJ;ACNA,IAAM,UAAA,GAAyC;AAAA,EAC7C,EAAA,EAAI,SAAA;AAAA,EACJ,EAAA,EAAI,iBAAA;AAAA,EACJ,EAAA,EAAI,UAAA;AAAA,EACJ,EAAA,EAAI,UAAA;AAAA,EACJ,GAAA,EAAK;AACP,CAAA;AAEA,IAAM,UAAA,GAAyC;AAAA,EAC7C,EAAA,EAAI,QAAA;AAAA,EACJ,EAAA,EAAI,QAAA;AAAA,EACJ,EAAA,EAAI,QAAA;AAAA,EACJ,EAAA,EAAI,QAAA;AAAA,EACJ,GAAA,EAAK;AACP,CAAA;AAKA,IAAM,eAAA,GAA8C;AAAA,EAClD,EAAA,EAAI,oCAAA;AAAA,EACJ,EAAA,EAAI,oCAAA;AAAA,EACJ,EAAA,EAAI,oCAAA;AAAA,EACJ,EAAA,EAAI,oCAAA;AAAA,EACJ,GAAA,EAAK;AACP,CAAA;AAOA,SAAS,OAAO,EAAA,EAAmD;AAAnD,EAAA,IAAA,EAAA,GAAA,EAAA,EAAE,EAAA,SAAA,EAAW,OAAO,IAAA,EArDpC,GAqDgB,IAA6B,KAAA,GAAA,SAAA,CAA7B,EAAA,EAA6B,CAA3B,WAAA,EAAW,MAAA,CAAA,CAAA;AAC3B,EAAA,uBACEA,GAAAA;AAAA,IAAiB,eAAA,CAAA,IAAA;AAAA,IAAhB,aAAA,CAAA,cAAA,CAAA;AAAA,MACC,WAAA,EAAU,QAAA;AAAA,MACV,SAAA,EAAW,EAAA;AAAA,QACT,wQAAA;AAAA,QACA,WAAW,IAAI,CAAA;AAAA,QACf;AAAA;AACF,KAAA,EACI,KAAA,CAAA,EAPL;AAAA,MASC,QAAA,kBAAAA,GAAAA;AAAA,QAAiB,eAAA,CAAA,KAAA;AAAA,QAAhB;AAAA,UACC,WAAA,EAAU,cAAA;AAAA,UACV,SAAA,EAAW,EAAA;AAAA,YACT,iIAAA;AAAA,YACA,WAAW,IAAI,CAAA;AAAA,YACf,gBAAgB,IAAI;AAAA;AACtB;AAAA;AACF,KAAA;AAAA,GACF;AAEJ;AC9DA,SAAS,QAAQ,KAAA,EAAqD;AACpE,EAAA,uBAAOA,GAAAA,CAAkB,gBAAA,CAAA,IAAA,EAAjB,cAAA,CAAA,EAAsB,WAAA,EAAU,aAAc,KAAA,CAAO,CAAA;AAC/D;AAEA,SAAS,eACP,KAAA,EACA;AACA,EAAA,uBAAOA,GAAAA,CAAkB,gBAAA,CAAA,OAAA,EAAjB,cAAA,CAAA,EAAyB,WAAA,EAAU,qBAAsB,KAAA,CAAO,CAAA;AAC1E;AAEA,SAAS,cACP,KAAA,EACA;AACA,EAAA,uBAAOA,GAAAA,CAAkB,gBAAA,CAAA,MAAA,EAAjB,cAAA,CAAA,EAAwB,WAAA,EAAU,oBAAqB,KAAA,CAAO,CAAA;AACxE;AAEA,SAAS,eAAe,EAAA,EAK4B;AAL5B,EAAA,IAAA,EAAA,GAAA,EAAA,EACtB;AAAA,IAAA,SAAA;AAAA,IACA,KAAA,GAAQ,OAAA;AAAA,IACR,UAAA,GAAa;AAAA,GA/Bf,GA4BwB,EAAA,EAInB,KAAA,GAAA,SAAA,CAJmB,EAAA,EAInB;AAAA,IAHH,WAAA;AAAA,IACA,OAAA;AAAA,IACA;AAAA,GAAA,CAAA;AAGA,EAAA,uBACEA,GAAAA,CAAkB,gBAAA,CAAA,MAAA,EAAjB,EACC,QAAA,kBAAAA,GAAAA;AAAA,IAAkB,gBAAA,CAAA,OAAA;AAAA,IAAjB,cAAA,CAAA;AAAA,MACC,WAAA,EAAU,iBAAA;AAAA,MACV,KAAA;AAAA,MACA,UAAA;AAAA,MACA,SAAA,EAAW,EAAA;AAAA,QACT,2QAAA;AAAA,QACA;AAAA;AACF,KAAA,EACI,KAAA;AAAA,GACN,EACF,CAAA;AAEJ;AC2BA,IAAM,UAAA,GAAa,EAAA;AACnB,IAAM,eAAA,GAAkB,EAAA;AAExB,IAAM,WAAA,GACJ,wLAAA;AACF,IAAM,YAAA,GACJ,+EAAA;AAEK,IAAM,WAAA,GAAc,UAAA;AAAA,EACzB,SAASO,YAAAA,CACP;AAAA,IACE,OAAA;AAAA,IACA,KAAA;AAAA,IACA,QAAA;AAAA,IACA,WAAA,GAAc,gCAAA;AAAA,IACd,UAAA,GAAa,IAAA;AAAA,IACb,SAAA,GAAY,IAAA;AAAA,IACZ,QAAA;AAAA,IACA,SAAA,GAAY,8CAAA;AAAA,IACZ,iBAAA,GAAoB,iBAAA;AAAA,IACpB,EAAA;AAAA,IACA,SAAA;AAAA,IACA,gBAAA;AAAA,IACA;AAAA,KAEF,GAAA,EACA;AArGJ,IAAA,IAAA,EAAA,EAAA,EAAA;AAsGE,IAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAIJ,SAAS,KAAK,CAAA;AACtC,IAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAIA,SAAS,EAAE,CAAA;AAKrC,IAAA,MAAM,CAAC,aAAA,EAAe,gBAAgB,CAAA,GAAIA,SAAS,KAAK,CAAA;AACxD,IAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAIA,SAAS,CAAC,CAAA;AACtC,IAAA,MAAM,OAAA,GAAU,OAAuB,IAAI,CAAA;AAC3C,IAAA,MAAM,UAAA,GAAa,OAAuB,IAAI,CAAA;AAM9C,IAAA,MAAM,eAAA,GAAkB,WAAA,CAAY,CAAC,CAAA,KAAkB;AACrD,MAAA,CAAA,CAAE,cAAA,EAAe;AACjB,MAAC,CAAA,CAAE,aAAA,CAAiC,SAAA,IAAa,CAAA,CAAE,MAAA;AAAA,IACrD,CAAA,EAAG,EAAE,CAAA;AACL,IAAA,MAAM,UAAA,GAAa,WAAA;AAAA,MACjB,CAAC,IAAA,KAAgC;AAC/B,QAAA,IAAI,QAAQ,OAAA,EAAS;AACnB,UAAA,OAAA,CAAQ,OAAA,CAAQ,mBAAA,CAAoB,OAAA,EAAS,eAAe,CAAA;AAAA,QAC9D;AACA,QAAA,OAAA,CAAQ,OAAA,GAAU,IAAA;AAClB,QAAA,IAAI,IAAA,EAAM;AACR,UAAA,IAAA,CAAK,iBAAiB,OAAA,EAAS,eAAA,EAAiB,EAAE,OAAA,EAAS,OAAO,CAAA;AAAA,QACpE;AAAA,MACF,CAAA;AAAA,MACA,CAAC,eAAe;AAAA,KAClB;AACA,IAAA,MAAM,cAAA,GAAiB,OAAyB,IAAI,CAAA;AACpD,IAAA,MAAM,SAAA,GAAY,OAA0B,IAAI,CAAA;AAChD,IAAA,MAAM,MAAA,GAAS,CAAA,EAAG,EAAA,IAAA,IAAA,GAAA,EAAA,GAAM,cAAc,CAAA,QAAA,CAAA;AAEtC,IAAA,mBAAA,CAAoB,KAAK,OAAO;AAAA,MAC9B,OAAO,MAAM;AA1IjB,QAAA,IAAAK,GAAAA,EAAAC,GAAAA;AA2IM,QAAA,IAAI,UAAA,EAAY;AACd,UAAA,CAAAD,GAAAA,GAAA,cAAA,CAAe,OAAA,KAAf,IAAA,GAAA,MAAA,GAAAA,GAAAA,CAAwB,KAAA,EAAA;AAAA,QAC1B,CAAA,MAAO;AACL,UAAA,CAAAC,GAAAA,GAAA,SAAA,CAAU,OAAA,KAAV,IAAA,GAAA,MAAA,GAAAA,GAAAA,CAAmB,KAAA,EAAA;AACnB,UAAA,QAAA,EAAS;AAAA,QACX;AAAA,MACF;AAAA,KACF,CAAE,CAAA;AAEF,IAAA,MAAM,WAAW,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,UAAU,KAAK,CAAA;AACtD,IAAA,MAAM,SAAA,GAAY,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAA,KAAM,EAAE,KAAA,IAAS,CAAA,CAAE,WAAW,CAAA,GAC1D,eAAA,GACA,UAAA;AAGJ,IAAA,MAAM,QAAA,GAAWJ,QAAQ,MAAM;AAC7B,MAAA,IAAI,CAAC,cAAc,CAAC,IAAA,IAAQ,CAAC,KAAA,CAAM,IAAA,IAAQ,OAAO,OAAA;AAClD,MAAA,MAAM,CAAA,GAAI,KAAA,CAAM,IAAA,EAAK,CAAE,WAAA,EAAY;AACnC,MAAA,OAAO,OAAA,CAAQ,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,MAAM,WAAA,EAAY,CAAE,QAAA,CAAS,CAAC,CAAC,CAAA;AAAA,IAChE,GAAG,CAAC,OAAA,EAAS,KAAA,EAAO,UAAA,EAAY,IAAI,CAAC,CAAA;AAGrC,IAAA,MAAM,cAAc,cAAA,CAAe;AAAA,MACjC,OAAO,QAAA,CAAS,MAAA;AAAA,MAChB,gBAAA,EAAkB,MAAM,OAAA,CAAQ,OAAA;AAAA,MAChC,cAAc,MAAM,SAAA;AAAA,MACpB,QAAA,EAAU;AAAA,KACX,CAAA;AAOD,IAAA,MAAM,CAAC,aAAA,EAAe,cAAc,CAAA,GAAIF,SAAS,CAAC,CAAA;AAClD,IAAAO,UAAU,MAAM;AACd,MAAA,IAAI,CAAC,IAAA,EAAM;AACX,MAAA,MAAM,GAAA,GAAM,sBAAsB,MAAM,cAAA,CAAe,CAAC,CAAA,KAAM,CAAA,GAAI,CAAC,CAAC,CAAA;AACpE,MAAA,OAAO,MAAM,qBAAqB,GAAG,CAAA;AAAA,IACvC,CAAA,EAAG,CAAC,IAAI,CAAC,CAAA;AAOT,IAAAA,UAAU,MAAM;AACd,MAAA,IAAI,CAAC,IAAA,IAAQ,KAAA,CAAM,IAAA,EAAK,EAAG;AAC3B,MAAA,MAAM,MAAM,OAAA,CAAQ,SAAA,CAAU,CAAC,CAAA,KAAM,CAAA,CAAE,UAAU,KAAK,CAAA;AACtD,MAAA,IAAI,OAAO,CAAA,EAAG;AACZ,QAAA,SAAA,CAAU,GAAG,CAAA;AACb,QAAA,WAAA,CAAY,aAAA,CAAc,GAAA,EAAK,EAAE,KAAA,EAAO,UAAU,CAAA;AAAA,MACpD;AAAA,IACF,GAAG,CAAC,IAAA,EAAM,OAAA,EAAS,KAAA,EAAO,aAAa,CAAC,CAAA;AAExC,IAAA,MAAM,WAAW,MAAM;AACrB,MAAA,IAAI,QAAA,EAAU;AACd,MAAA,QAAA,CAAS,EAAE,CAAA;AACX,MAAA,gBAAA,CAAiB,KAAK,CAAA;AACtB,MAAA,MAAM,MAAM,OAAA,CAAQ,SAAA,CAAU,CAAC,CAAA,KAAM,CAAA,CAAE,UAAU,KAAK,CAAA;AACtD,MAAA,SAAA,CAAU,GAAA,IAAO,CAAA,GAAI,GAAA,GAAM,CAAC,CAAA;AAC5B,MAAA,OAAA,CAAQ,IAAI,CAAA;AAAA,IACd,CAAA;AAEA,IAAA,MAAM,MAAA,GAAS,CAAC,GAAA,KAA2B;AACzC,MAAA,IAAI,IAAI,QAAA,EAAU;AAClB,MAAA,QAAA,IAAA,IAAA,GAAA,MAAA,GAAA,QAAA,CAAW,GAAA,CAAI,KAAA,CAAA;AACf,MAAA,QAAA,CAAS,EAAE,CAAA;AACX,MAAA,OAAA,CAAQ,KAAK,CAAA;AAAA,IACf,CAAA;AAEA,IAAA,MAAM,QAAQ,MAAM;AAClB,MAAA,QAAA,IAAA,IAAA,GAAA,MAAA,GAAA,QAAA,CAAW,EAAA,CAAA;AACX,MAAA,QAAA,CAAS,EAAE,CAAA;AAAA,IACb,CAAA;AAEA,IAAA,MAAM,UAAA,GAAa,CAAC,KAAA,KAAkB;AACpC,MAAA,IAAI,QAAA,CAAS,WAAW,CAAA,EAAG;AAC3B,MAAA,MAAM,IAAA,GAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,GAAA,CAAI,MAAA,GAAS,KAAA,EAAO,CAAC,CAAA,EAAG,QAAA,CAAS,MAAA,GAAS,CAAC,CAAA;AACtE,MAAA,SAAA,CAAU,IAAI,CAAA;AACd,MAAA,WAAA,CAAY,cAAc,IAAI,CAAA;AAAA,IAChC,CAAA;AAEA,IAAA,MAAM,aAAA,GAAgB,CAAC,CAAA,KAA2B;AAChD,MAAA,IAAI,CAAA,CAAE,QAAQ,WAAA,EAAa;AACzB,QAAA,CAAA,CAAE,cAAA,EAAe;AACjB,QAAA,IAAI,CAAC,MAAM,QAAA,EAAS;AAAA,wBACJ,CAAC,CAAA;AAAA,MACnB,CAAA,MAAA,IAAW,CAAA,CAAE,GAAA,KAAQ,SAAA,EAAW;AAC9B,QAAA,CAAA,CAAE,cAAA,EAAe;AACjB,QAAA,UAAA,CAAW,EAAE,CAAA;AAAA,MACf,CAAA,MAAA,IAAW,CAAA,CAAE,GAAA,KAAQ,OAAA,EAAS;AAC5B,QAAA,IAAI,IAAA,EAAM;AACR,UAAA,CAAA,CAAE,cAAA,EAAe;AACjB,UAAA,MAAM,GAAA,GAAM,SAAS,MAAM,CAAA;AAC3B,UAAA,IAAI,GAAA,SAAY,GAAG,CAAA;AAAA,QACrB;AAAA,MACF,CAAA,MAAA,IAAW,CAAA,CAAE,GAAA,KAAQ,QAAA,EAAU;AAC7B,QAAA,OAAA,CAAQ,KAAK,CAAA;AAAA,MACf;AAAA,IACF,CAAA;AAGA,IAAA,MAAM,IAAA,GACJ,QAAA,CAAS,MAAA,KAAW,CAAA,mBAClBV,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,qDAAA,EACZ,QAAA,EAAA,SAAA,EACH,CAAA,mBAEAA,GAAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,GAAA,EAAK,UAAA;AAAA,QACL,EAAA,EAAI,MAAA;AAAA,QACJ,IAAA,EAAK,SAAA;AAAA,QACL,SAAA,EAAU,8BAAA;AAAA,QAEV,0BAAAA,GAAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAO,EAAE,QAAQ,WAAA,CAAY,YAAA,EAAa,EAAG,QAAA,EAAU,YAAW,EACpE,QAAA,EAAA,WAAA,CAAY,iBAAgB,CAAE,GAAA,CAAI,CAAC,GAAA,KAAQ;AAC1C,UAAA,MAAM,GAAA,GAAM,QAAA,CAAS,GAAA,CAAI,KAAK,CAAA;AAC9B,UAAA,MAAM,UAAA,GAAa,IAAI,KAAA,KAAU,KAAA;AACjC,UAAA,MAAM,QAAA,GAAW,IAAI,KAAA,KAAU,MAAA;AAC/B,UAAA,uBACEC,IAAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cAEC,IAAA,EAAK,QAAA;AAAA,cACL,UAAU,GAAA,CAAI,QAAA;AAAA,cAEd,WAAA,EAAa,CAAC,CAAA,KAAM,CAAA,CAAE,cAAA,EAAe;AAAA,cACrC,OAAA,EAAS,MAAM,MAAA,CAAO,GAAG,CAAA;AAAA,cACzB,YAAA,EAAc,MAAM,SAAA,CAAU,GAAA,CAAI,KAAK,CAAA;AAAA,cACvC,SAAA,EAAW,EAAA;AAAA,gBACT,qFAAA;AAAA,gBACA,kDAAA;AAAA,gBACA,QAAA,IAAY;AAAA,eACd;AAAA,cACA,OAAO,EAAE,GAAA,EAAK,IAAI,KAAA,EAAO,MAAA,EAAQ,IAAI,IAAA,EAAK;AAAA,cAE1C,QAAA,EAAA;AAAA,gCAAAD,GAAAA;AAAA,kBAAC,KAAA;AAAA,kBAAA;AAAA,oBACC,SAAA,EAAW,EAAA;AAAA,sBACT,iBAAA;AAAA,sBACA,aAAa,aAAA,GAAgB;AAAA;AAC/B;AAAA,iBACF;AAAA,gBACC,GAAA,CAAI,KAAA;AAAA,gCAEHA,GAAAA;AAAA,kBAAC,KAAA;AAAA,kBAAA;AAAA,oBACC,KAAK,GAAA,CAAI,KAAA;AAAA,oBACT,GAAA,EAAI,EAAA;AAAA,oBACJ,SAAA,EAAU;AAAA;AAAA,iBACZ;AAAA,gCAEFC,IAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,0BAAA,EACd,QAAA,EAAA;AAAA,kCAAAD,GAAAA,CAAC,UAAK,SAAA,EAAW,EAAA,CAAG,kBAAkB,UAAA,IAAc,aAAa,CAAA,EAC9D,QAAA,EAAA,GAAA,CAAI,KAAA,EACP,CAAA;AAAA,kBACC,GAAA,CAAI,+BACHA,GAAAA,CAAC,UAAK,SAAA,EAAU,8CAAA,EACb,cAAI,WAAA,EACP;AAAA,iBAAA,EAEJ;AAAA;AAAA,aAAA;AAAA,YArCK,GAAA,CAAI;AAAA,WAsCX;AAAA,QAEJ,CAAC,CAAA,EACH;AAAA;AAAA,KACF;AAGJ,IAAA,MAAM,iCACJA,GAAAA;AAAA,MAAC,cAAA;AAAA,MAAA;AAAA,QACC,KAAA,EAAM,OAAA;AAAA,QACN,SAAA,EAAW,EAAA,CAAG,KAAA,EAAO,gBAAgB,CAAA;AAAA,QACrC,KAAA,EAAO,EAAE,KAAA,EAAO,oCAAA,EAAqC;AAAA,QACrD,SAAA,EAAW,aAAA;AAAA,QAEX,iBAAiB,UAAA,GAAa,CAAC,CAAA,KAAM,CAAA,CAAE,gBAAe,GAAI,MAAA;AAAA,QAC1D,iBAAA,EAAmB,CAAC,CAAA,KAAM;AA1ThC,UAAA,IAAAQ,GAAAA;AA2TQ,UAAA,IAAA,CAAIA,GAAAA,GAAA,WAAW,OAAA,KAAX,IAAA,GAAA,MAAA,GAAAA,IAAoB,QAAA,CAAS,CAAA,CAAE,MAAA,CAAA,EAAiB,CAAA,CAAE,cAAA,EAAe;AAAA,QACvE,CAAA;AAAA,QAEC,QAAA,EAAA;AAAA;AAAA,KACH;AAIF,IAAA,IAAI,UAAA,EAAY;AACd,MAAA,uBACEP,IAAAA,CAAC,OAAA,EAAA,EAAQ,IAAA,EAAY,cAAc,OAAA,EACjC,QAAA,EAAA;AAAA,wBAAAD,GAAAA,CAAC,aAAA,EAAA,EAAc,OAAA,EAAO,IAAA,EACpB,QAAA,kBAAAC,IAAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,GAAA,EAAK,UAAA;AAAA,YACL,SAAA,EAAW,EAAA;AAAA,cACT,WAAA;AAAA,cACA,4EAAA;AAAA,cACA,QAAA,IAAY,YAAA;AAAA,cACZ;AAAA,aACF;AAAA,YAEC,QAAA,EAAA;AAAA,cAAA,CAAA,QAAA,IAAA,IAAA,GAAA,MAAA,GAAA,QAAA,CAAU,UAAS,CAAC,IAAA;AAAA,8BAEnBD,GAAAA;AAAA,gBAAC,KAAA;AAAA,gBAAA;AAAA,kBACC,KAAK,QAAA,CAAS,KAAA;AAAA,kBACd,GAAA,EAAI,EAAA;AAAA,kBACJ,SAAA,EAAU;AAAA;AAAA,eACZ;AAAA,8BAEFA,GAAAA;AAAA,gBAAC,OAAA;AAAA,gBAAA;AAAA,kBACC,GAAA,EAAK,cAAA;AAAA,kBACL,EAAA;AAAA,kBACA,QAAA;AAAA,kBACA,IAAA,EAAK,UAAA;AAAA,kBACL,eAAA,EAAe,IAAA;AAAA,kBACf,eAAA,EAAe,MAAA;AAAA,kBACf,mBAAA,EAAkB,MAAA;AAAA,kBAKlB,KAAA,EACE,IAAA,GACI,aAAA,GACE,KAAA,GAAA,CACA,EAAA,GAAA,QAAA,IAAA,IAAA,GAAA,MAAA,GAAA,QAAA,CAAU,UAAV,IAAA,GAAA,EAAA,GAAmB,EAAA,GAAA,CACrB,EAAA,GAAA,QAAA,IAAA,IAAA,GAAA,MAAA,GAAA,QAAA,CAAU,KAAA,KAAV,IAAA,GAAA,EAAA,GAAmB,EAAA;AAAA,kBAEzB,WAAA,EAAa,OAAO,iBAAA,GAAoB,WAAA;AAAA,kBACxC,QAAA,EAAU,CAAC,CAAA,KAAM;AACf,oBAAA,QAAA,CAAS,CAAA,CAAE,OAAO,KAAK,CAAA;AACvB,oBAAA,gBAAA,CAAiB,IAAI,CAAA;AACrB,oBAAA,SAAA,CAAU,CAAC,CAAA;AACX,oBAAA,IAAI,CAAC,IAAA,EAAM,OAAA,CAAQ,IAAI,CAAA;AAAA,kBACzB,CAAA;AAAA,kBACA,OAAA,EAAS,CAAC,CAAA,KAAM;AACd,oBAAA,QAAA,EAAS;AACT,oBAAA,CAAA,CAAE,OAAO,MAAA,EAAO;AAAA,kBAClB,CAAA;AAAA,kBACA,MAAA;AAAA,kBACA,SAAA,EAAW,aAAA;AAAA,kBACX,SAAA,EAAU;AAAA;AAAA,eACZ;AAAA,cACC,SAAA,IAAa,QAAA,IAAY,CAAC,QAAA,oBACzBA,GAAAA;AAAA,gBAAC,QAAA;AAAA,gBAAA;AAAA,kBACC,IAAA,EAAK,QAAA;AAAA,kBACL,QAAA,EAAU,EAAA;AAAA,kBACV,YAAA,EAAW,2BAAA;AAAA,kBACX,WAAA,EAAa,CAAC,CAAA,KAAM,CAAA,CAAE,cAAA,EAAe;AAAA,kBACrC,OAAA,EAAS,KAAA;AAAA,kBACT,SAAA,EAAU,kGAAA;AAAA,kBAEV,QAAA,kBAAAA,GAAAA,CAAC,CAAA,EAAA,EAAE,SAAA,EAAU,UAAA,EAAW;AAAA;AAAA,eAC1B;AAAA,8BAEFA,GAAAA;AAAA,gBAACW,WAAAA;AAAA,gBAAA;AAAA,kBACC,SAAA,EAAU,uCAAA;AAAA,kBACV,WAAA,EAAa,CAAC,CAAA,KAAM,CAAA,CAAE,cAAA,EAAe;AAAA,kBACrC,SAAS,MAAO,IAAA,GAAO,OAAA,CAAQ,KAAK,IAAI,QAAA;AAAS;AAAA;AACnD;AAAA;AAAA,SACF,EACF,CAAA;AAAA,QACC;AAAA,OAAA,EACH,CAAA;AAAA,IAEJ;AAGA,IAAA,uBACEV,IAAAA;AAAA,MAAC,OAAA;AAAA,MAAA;AAAA,QACC,IAAA;AAAA,QACA,YAAA,EAAc,CAAC,CAAA,KAAM;AACnB,UAAA,OAAA,CAAQ,CAAC,CAAA;AACT,UAAA,IAAI,CAAA,EAAG;AACL,YAAA,MAAM,MAAM,OAAA,CAAQ,SAAA,CAAU,CAAC,GAAA,KAAQ,GAAA,CAAI,UAAU,KAAK,CAAA;AAC1D,YAAA,SAAA,CAAU,GAAA,IAAO,CAAA,GAAI,GAAA,GAAM,CAAC,CAAA;AAAA,UAC9B;AAAA,QACF,CAAA;AAAA,QAEA,QAAA,EAAA;AAAA,0BAAAD,GAAAA,CAAC,cAAA,EAAA,EAAe,OAAA,EAAO,IAAA,EACrB,QAAA,kBAAAC,IAAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cACC,GAAA,EAAK,SAAA;AAAA,cACL,IAAA,EAAK,QAAA;AAAA,cACL,EAAA;AAAA,cACA,QAAA;AAAA,cACA,eAAA,EAAc,SAAA;AAAA,cACd,eAAA,EAAe,IAAA;AAAA,cACf,MAAA;AAAA,cACA,SAAA,EAAW,EAAA,CAAG,WAAA,EAAa,YAAA,EAAc,mBAAmB,SAAS,CAAA;AAAA,cAEpE,QAAA,EAAA;AAAA,gBAAA,QAAA,mBACCA,IAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,iCAAA,EACb,QAAA,EAAA;AAAA,kBAAA,QAAA,CAAS,KAAA;AAAA,kCAERD,GAAAA;AAAA,oBAAC,KAAA;AAAA,oBAAA;AAAA,sBACC,KAAK,QAAA,CAAS,KAAA;AAAA,sBACd,GAAA,EAAI,EAAA;AAAA,sBACJ,SAAA,EAAU;AAAA;AAAA,mBACZ;AAAA,kCAEFA,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,UAAA,EAAY,mBAAS,KAAA,EAAM;AAAA,iBAAA,EAC7C,oBAEAA,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,kCAAkC,QAAA,EAAA,WAAA,EAAY,CAAA;AAAA,gCAEhEC,IAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,kCAAA,EACb,QAAA,EAAA;AAAA,kBAAA,SAAA,IAAa,QAAA,IAAY,CAAC,QAAA,oBACzBD,GAAAA;AAAA,oBAAC,MAAA;AAAA,oBAAA;AAAA,sBACC,IAAA,EAAK,QAAA;AAAA,sBACL,QAAA,EAAU,EAAA;AAAA,sBACV,YAAA,EAAW,2BAAA;AAAA,sBACX,SAAA,EAAU,yFAAA;AAAA,sBACV,OAAA,EAAS,CAAC,CAAA,KAAM;AACd,wBAAA,CAAA,CAAE,eAAA,EAAgB;AAClB,wBAAA,KAAA,EAAM;AAAA,sBACR,CAAA;AAAA,sBAEA,QAAA,kBAAAA,GAAAA,CAAC,CAAA,EAAA,EAAE,SAAA,EAAU,UAAA,EAAW;AAAA;AAAA,mBAC1B;AAAA,kCAEFA,GAAAA,CAACW,WAAAA,EAAA,EAAY,WAAU,uCAAA,EAAwC;AAAA,iBAAA,EACjE;AAAA;AAAA;AAAA,WACF,EACF,CAAA;AAAA,UACC;AAAA;AAAA;AAAA,KACH;AAAA,EAEF;AACF;AC1YA,SAAS,cAAc,IAAA,EAA6B;AAClD,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAA,KAAW;AACtC,IAAA,MAAM,MAAA,GAAS,IAAI,UAAA,EAAW;AAC9B,IAAA,MAAA,CAAO,MAAA,GAAS,MAAM,OAAA,CAAQ,MAAA,CAAO,MAAgB,CAAA;AACrD,IAAA,MAAA,CAAO,OAAA,GAAU,MAAA;AACjB,IAAA,MAAA,CAAO,cAAc,IAAI,CAAA;AAAA,EAC3B,CAAC,CAAA;AACH;AAGA,SAAS,aAAA,CAAc,MAAY,MAAA,EAAyB;AAC1D,EAAA,MAAM,QAAA,GAAW,MAAA,CACd,KAAA,CAAM,GAAG,CAAA,CACT,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,EAAM,CAAA,CACnB,OAAO,OAAO,CAAA;AACjB,EAAA,IAAI,QAAA,CAAS,MAAA,KAAW,CAAA,EAAG,OAAO,IAAA;AAClC,EAAA,OAAO,QAAA,CAAS,IAAA,CAAK,CAAC,CAAA,KAAM;AAC1B,IAAA,IAAI,CAAA,CAAE,QAAA,CAAS,IAAI,CAAA,EAAG,OAAO,IAAA,CAAK,IAAA,CAAK,UAAA,CAAW,CAAA,CAAE,KAAA,CAAM,CAAA,EAAG,EAAE,CAAC,CAAA;AAChE,IAAA,IAAI,CAAA,CAAE,UAAA,CAAW,GAAG,CAAA,EAAG,OAAO,IAAA,CAAK,IAAA,CAAK,WAAA,EAAY,CAAE,QAAA,CAAS,CAAA,CAAE,WAAA,EAAa,CAAA;AAC9E,IAAA,OAAO,KAAK,IAAA,KAAS,CAAA;AAAA,EACvB,CAAC,CAAA;AACH;AAEO,IAAM,gBAAA,GAAmBC,UAAAA,CAG9B,SAASC,iBAAAA,CACT;AAAA,EACE,QAAQ,EAAC;AAAA,EACT,QAAA;AAAA,EACA,QAAA,GAAW,CAAA;AAAA,EACX,MAAA,GAAS,SAAA;AAAA,EACT,QAAA;AAAA,EACA,QAAA;AAAA,EACA,YAAA;AAAA,EACA,IAAA,GAAO,EAAA;AAAA,EACP,OAAA,GAAU,IAAA;AAAA,EACV;AACF,CAAA,EACA,GAAA,EACA;AACA,EAAA,MAAM,QAAA,GAAWC,OAAyB,IAAI,CAAA;AAC9C,EAAA,MAAM,YAAA,GAAeA,OAA0B,IAAI,CAAA;AACnD,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAIX,SAAS,KAAK,CAAA;AAC9C,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAIA,SAAS,CAAC,CAAA;AAC5C,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAIA,SAAwB,IAAI,CAAA;AAE9D,EAAAY,mBAAAA,CAAoB,KAAK,OAAO;AAAA,IAC9B,OAAO,MAAG;AArHd,MAAA,IAAA,EAAA;AAqHiB,MAAA,OAAA,CAAA,EAAA,GAAA,YAAA,CAAa,YAAb,IAAA,GAAA,MAAA,GAAA,EAAA,CAAsB,KAAA,EAAA;AAAA,IAAA;AAAA,GACrC,CAAE,CAAA;AAEF,EAAA,MAAM,MAAA,GAAS,CAAC,QAAA,IAAY,KAAA,CAAM,SAAS,SAAA,GAAY,QAAA;AAEvD,EAAA,MAAM,QAAA,GAAW,OAAO,QAAA,KAA8B;AACpD,IAAA,IAAI,CAAC,YAAY,QAAA,EAAU;AAC3B,IAAA,MAAM,SAAA,GAAY,WAAW,KAAA,CAAM,MAAA;AACnC,IAAA,MAAM,QAAQ,KAAA,CAAM,IAAA,CAAK,QAAQ,CAAA,CAC9B,MAAA,CAAO,CAAC,CAAA,KAAM,aAAA,CAAc,GAAG,MAAM,CAAC,EACtC,KAAA,CAAM,CAAA,EAAG,KAAK,GAAA,CAAI,CAAA,EAAG,SAAS,CAAC,CAAA;AAClC,IAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AAExB,IAAA,YAAA,IAAA,IAAA,GAAA,MAAA,GAAA,YAAA,CAAe,KAAA,CAAA;AAEf,IAAA,YAAA,CAAa,CAAC,CAAA,KAAM,CAAA,GAAI,KAAA,CAAM,MAAM,CAAA;AACpC,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,GAAO,MAAM,OAAA,CAAQ,GAAA;AAAA,QACzB,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,KAAO,QAAA,GAAW,SAAS,CAAC,CAAA,GAAI,aAAA,CAAc,CAAC,CAAE;AAAA,OAC9D;AACA,MAAA,QAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,QAAA,CAAW,CAAC,GAAG,KAAA,EAAO,GAAG,IAAI,CAAA,CAAA;AAAA,IAC/B,CAAA,SAAE;AACA,MAAA,YAAA,CAAa,CAAC,MAAM,IAAA,CAAK,GAAA,CAAI,GAAG,CAAA,GAAI,KAAA,CAAM,MAAM,CAAC,CAAA;AAAA,IACnD;AAAA,EACF,CAAA;AAEA,EAAA,MAAM,QAAA,GAAW,CAAC,KAAA,KAChB,QAAA,IAAA,IAAA,GAAA,MAAA,GAAA,QAAA,CAAW,KAAA,CAAM,OAAO,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,KAAM,KAAK,CAAA,CAAA;AAE/C,EAAA,MAAM,SAAA,GAAY,EAAE,KAAA,EAAO,IAAA,EAAM,QAAQ,IAAA,EAAK;AAE9C,EAAA,uBACEd,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAW,EAAA,CAAG,sBAAA,EAAwB,SAAS,CAAA,EAEjD,QAAA,EAAA;AAAA,IAAA,KAAA,CAAM,GAAA,CAAI,CAAC,GAAA,EAAK,CAAA,qBACfA,IAAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QAEC,KAAA,EAAO,SAAA;AAAA,QACP,SAAA,EAAU,2DAAA;AAAA,QAGV,QAAA,EAAA;AAAA,0BAAAD,GAAAA;AAAA,YAAC,KAAA;AAAA,YAAA;AAAA,cACC,GAAA,EAAK,GAAA;AAAA,cACL,GAAA,EAAI,EAAA;AAAA,cACJ,OAAA,EAAS,MAAM,OAAA,IAAW,YAAA,CAAa,CAAC,CAAA;AAAA,cACxC,SAAA,EAAW,EAAA,CAAG,wBAAA,EAA0B,OAAA,IAAW,gBAAgB;AAAA;AAAA,WACrE;AAAA,UACC,OAAA,oBACCA,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,iHAAA,EACd,QAAA,kBAAAA,GAAAA,CAAC,MAAA,EAAA,EAAO,SAAA,EAAU,QAAA,EAAS,CAAA,EAC7B,CAAA;AAAA,UAED,CAAC,4BACAA,GAAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cACC,IAAA,EAAK,QAAA;AAAA,cACL,YAAA,EAAW,cAAA;AAAA,cACX,OAAA,EAAS,MAAM,QAAA,CAAS,CAAC,CAAA;AAAA,cACzB,SAAA,EAAU,uIAAA;AAAA,cAEV,QAAA,kBAAAA,GAAAA,CAACgB,CAAAA,EAAA,EAAE,WAAU,UAAA,EAAW;AAAA;AAAA;AAC1B;AAAA,OAAA;AAAA,MAxBG;AAAA,KA2BR,CAAA;AAAA,IAGA,KAAA,CAAM,IAAA,CAAK,EAAE,MAAA,EAAQ,SAAA,EAAW,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,EAAG,CAAA,qBACzChB,GAAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QAEC,KAAA,EAAO,SAAA;AAAA,QACP,SAAA,EAAU,mFAAA;AAAA,QAEV,QAAA,kBAAAA,GAAAA,CAACiB,OAAAA,EAAA,EAAQ,WAAU,qBAAA,EAAsB;AAAA,OAAA;AAAA,MAJpC,KAAK,CAAC,CAAA;AAAA,KAMd,CAAA;AAAA,IAGA,0BACChB,IAAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,GAAA,EAAK,YAAA;AAAA,QACL,IAAA,EAAK,QAAA;AAAA,QACL,SAAS,MAAG;AAtMtB,UAAA,IAAA,EAAA;AAsMyB,UAAA,OAAA,CAAA,EAAA,GAAA,QAAA,CAAS,YAAT,IAAA,GAAA,MAAA,GAAA,EAAA,CAAkB,KAAA,EAAA;AAAA,QAAA,CAAA;AAAA,QACjC,UAAA,EAAY,CAAC,CAAA,KAAM;AACjB,UAAA,CAAA,CAAE,cAAA,EAAe;AACjB,UAAA,WAAA,CAAY,IAAI,CAAA;AAAA,QAClB,CAAA;AAAA,QACA,WAAA,EAAa,MAAM,WAAA,CAAY,KAAK,CAAA;AAAA,QACpC,MAAA,EAAQ,CAAC,CAAA,KAAM;AACb,UAAA,CAAA,CAAE,cAAA,EAAe;AACjB,UAAA,WAAA,CAAY,KAAK,CAAA;AACjB,UAAA,KAAK,QAAA,CAAS,CAAA,CAAE,YAAA,CAAa,KAAK,CAAA;AAAA,QACpC,CAAA;AAAA,QACA,WAAA,EAAW,QAAA;AAAA,QACX,KAAA,EAAO,SAAA;AAAA,QACP,SAAA,EAAW,EAAA;AAAA,UACT,wIAAA;AAAA,UACA,yCAAA;AAAA,UACA;AAAA,SACF;AAAA,QAEA,QAAA,EAAA;AAAA,0BAAAD,GAAAA,CAAC,SAAA,EAAA,EAAU,SAAA,EAAU,QAAA,EAAS,CAAA;AAAA,0BAC9BA,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,WAAU,QAAA,EAAA,oBAAA,EAAG;AAAA;AAAA;AAAA,KAC/B;AAAA,oBAGFA,GAAAA;AAAA,MAAC,OAAA;AAAA,MAAA;AAAA,QACC,GAAA,EAAK,QAAA;AAAA,QACL,IAAA,EAAK,MAAA;AAAA,QACL,MAAA;AAAA,QACA,UAAU,QAAA,GAAW,CAAA;AAAA,QACrB,SAAA,EAAU,QAAA;AAAA,QACV,QAAA,EAAU,CAAC,CAAA,KAAM;AACf,UAAA,KAAK,QAAA,CAAS,CAAA,CAAE,MAAA,CAAO,KAAK,CAAA;AAC5B,UAAA,CAAA,CAAE,OAAO,KAAA,GAAQ,EAAA;AAAA,QACnB;AAAA;AAAA,KACF;AAAA,oBAGAA,GAAAA;AAAA,MAAiBkB,cAAA,CAAA,IAAA;AAAA,MAAhB;AAAA,QACC,MAAM,SAAA,KAAc,IAAA;AAAA,QACpB,cAAc,CAAC,CAAA,KAAM,CAAC,CAAA,IAAK,aAAa,IAAI,CAAA;AAAA,QAE5C,QAAA,kBAAAjB,IAAAA,CAAiBiB,cAAA,CAAA,MAAA,EAAhB,EACC,QAAA,EAAA;AAAA,0BAAAlB,GAAAA,CAAiBkB,cAAA,CAAA,OAAA,EAAhB,EAAwB,SAAA,EAAU,wJAAA,EAAyJ,CAAA;AAAA,0BAC5LjB,IAAAA;AAAA,YAAiBiB,cAAA,CAAA,OAAA;AAAA,YAAhB;AAAA,cACC,OAAA,EAAS,MAAM,YAAA,CAAa,IAAI,CAAA;AAAA,cAChC,SAAA,EAAU,sEAAA;AAAA,cAEV,QAAA,EAAA;AAAA,gCAAAlB,GAAAA,CAAiBkB,cAAA,CAAA,KAAA,EAAhB,EAAsB,SAAA,EAAU,WAAU,QAAA,EAAA,8CAAA,EAE3C,CAAA;AAAA,gBACC,SAAA,KAAc,IAAA;AAAA,gCAEblB,GAAAA;AAAA,kBAAC,KAAA;AAAA,kBAAA;AAAA,oBACC,GAAA,EAAK,MAAM,SAAS,CAAA;AAAA,oBACpB,GAAA,EAAI,EAAA;AAAA,oBACJ,OAAA,EAAS,CAAC,CAAA,KAAM,CAAA,CAAE,eAAA,EAAgB;AAAA,oBAClC,SAAA,EAAU;AAAA;AAAA,iBACZ;AAAA,gCAEFC,IAAAA,CAAiBiB,cAAA,CAAA,KAAA,EAAhB,EAAsB,WAAU,+JAAA,EAC/B,QAAA,EAAA;AAAA,kCAAAlB,GAAAA,CAACgB,CAAAA,EAAA,EAAE,SAAA,EAAU,QAAA,EAAS,CAAA;AAAA,kCACtBhB,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,WAAU,QAAA,EAAA,cAAA,EAAE;AAAA,iBAAA,EAC9B;AAAA;AAAA;AAAA;AACF,SAAA,EACF;AAAA;AAAA;AACF,GAAA,EACF,CAAA;AAEJ,CAAC;AC9KD,IAAM,eAAA,GAAsC,CAAC,OAAA,EAAS,KAAA,EAAO,QAAQ,CAAA;AAGrE,IAAM,UAAA,GAAwD;AAAA,EAC5D,GAAA,EAAK,EAAA;AAAA;AAAA,EACL,MAAA,EAAQ;AAAA;AACV,CAAA;AAEA,IAAM,QAAA,GAAW,4BAAA;AAMjB,SAAS,aAAA,CACP,IAAA,EACA,KAAA,EACA,QAAA,EACoB;AACpB,EAAA,MAAM,CAAA,GAAI,MAAA,CAAO,KAAA,IAAA,IAAA,GAAA,KAAA,GAAS,EAAE,EAAE,IAAA,EAAK;AACnC,EAAA,IAAI,CAAC,CAAA,EAAG,OAAO,QAAA,GAAW,2DAAA,GAAiB,MAAA;AAE3C,EAAA,QAAQ,IAAA;AAAM,IACZ,KAAK,OAAA;AACH,MAAA,OAAO,QAAA,CAAS,IAAA,CAAK,CAAC,CAAA,GAAI,MAAA,GAAY,0FAAA;AAAA,IACxC,KAAK,KAAA,EAAO;AACV,MAAA,MAAM,GAAA,GAAM,CAAA,CAAE,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAA,CAAE,MAAA;AACjC,MAAA,OAAO,GAAA,KAAQ,EAAA,IAAM,GAAA,KAAQ,EAAA,GACzB,MAAA,GACA,gGAAA;AAAA,IACN;AAAA,IACA,KAAK,QAAA;AACH,MAAA,OAAO,EAAE,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAA,CAAE,MAAA,KAAW,KACnC,MAAA,GACA,8GAAA;AAAA,IACN;AACE,MAAA,OAAO,MAAA;AAAA;AAEb;AAaO,SAAS,aAAA,CACd,MACA,KAAA,EACoB;AACpB,EAAA,MAAM,GAAA,GAAM,MAAA,CAAO,KAAA,IAAA,IAAA,GAAA,KAAA,GAAS,EAAE,CAAA;AAC9B,EAAA,MAAM,CAAA,GAAI,IAAI,IAAA,EAAK;AACnB,EAAA,IAAI,CAAC,CAAA,EAAG,OAAO,IAAA,CAAK,WAAW,2DAAA,GAAiB,MAAA;AAChD,EAAA,IAAI,IAAA,CAAK,QAAA,EAAU,OAAO,IAAA,CAAK,SAAS,GAAG,CAAA;AAC3C,EAAA,IAAI,KAAK,IAAA,EAAM,OAAO,aAAA,CAAc,IAAA,CAAK,MAAM,GAAG,CAAA;AAClD,EAAA,OAAO,MAAA;AACT;AA+EO,SAAS,cAAA,CAAe;AAAA,EAC7B,KAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAA;AAAA,EACA,WAAA;AAAA,EACA,KAAA;AAAA,EACA,WAAA,GAAc,UAAA;AAAA,EACd,cAAA;AAAA,EACA,SAAA;AAAA,EACA,IAAA;AAAA,EACA,KAAA;AAAA,EACA,QAAA;AAAA,EACA,WAAA;AAAA,EACA,QAAA;AAAA,EACA,aAAA;AAAA,EACA,UAAA;AAAA,EACA,IAAA;AAAA,EACA,OAAA;AAAA,EACA,WAAA;AAAA,EACA,WAAA;AAAA,EACA,WAAA;AAAA,EACA,gBAAA,GAAmB,IAAA;AAAA,EACnB,UAAA;AAAA,EACA;AACF,CAAA,EAAwB;AACtB,EAAA,MAAM,aAAa,WAAA,KAAgB,YAAA;AAGnC,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAIG,SAAS,KAAK,CAAA;AAK5C,EAAA,IAAI,YAAA;AACJ,EAAA,IAAI,CAAC,YAAY,IAAA,EAAM;AACrB,IAAA,MAAM,GAAA,GAAM,MAAA,CAAO,KAAA,IAAA,IAAA,GAAA,KAAA,GAAS,EAAE,CAAA;AAC9B,IAAA,MAAM,CAAA,GAAI,IAAI,IAAA,EAAK;AACnB,IAAA,IAAI,CAAC,CAAA,EAAG;AACN,MAAA,YAAA,GAAe,QAAA,IAAY,gBAAgB,2DAAA,GAAiB,MAAA;AAAA,IAC9D,CAAA,MAAA,IAAW,WAAW,aAAA,EAAe;AACnC,MAAA,YAAA,GAAe,WAAW,QAAA,CAAS,GAAG,CAAA,GAAI,aAAA,CAAc,MAAM,KAAK,CAAA;AAAA,IACrE;AAAA,EACF;AACA,EAAA,MAAM,aAAa,KAAA,IAAA,IAAA,GAAA,KAAA,GAAS,YAAA;AAC5B,EAAA,MAAM,UAAU,UAAA,IAAc,IAAA;AAO9B,EAAA,MAAM,QAAA,GAAWW,OAAyB,IAAI,CAAA;AAC9C,EAAA,MAAM,WAAA,GAAcA,OAA4B,IAAI,CAAA;AACpD,EAAA,MAAM,SAAA,GAAYA,OAA0B,IAAI,CAAA;AAChD,EAAA,MAAM,SAAA,GAAYA,OAA+B,IAAI,CAAA;AACrD,EAAA,MAAM,SAAA,GAAYA,OAA0B,IAAI,CAAA;AAChD,EAAA,MAAM,UAAA,GAAaA,OAAO,KAAK,CAAA;AAC/B,EAAA,MAAM,cAAA,GAAiBA,OAAO,UAAU,CAAA;AACxC,EAAAJ,UAAU,MAAM;AAlSlB,IAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA;AAmSI,IAAA,MAAM,YAAA,GACJ,UAAA,KAAe,MAAA,IAAa,UAAA,KAAe,cAAA,CAAe,OAAA;AAC5D,IAAA,MAAM,YAAA,GAAe,OAAA,IAAW,CAAC,UAAA,CAAW,OAAA;AAC5C,IAAA,IAAI,gBAAA,IAAoB,OAAA,KAAY,YAAA,IAAgB,YAAA,CAAA,EAAe;AACjE,MAAA,IAAI,IAAA,KAAS,QAAA,EAAU,CAAA,EAAA,GAAA,SAAA,CAAU,OAAA,KAAV,IAAA,GAAA,MAAA,GAAA,EAAA,CAAmB,KAAA,EAAA;AAAA,WAAA,IACjC,IAAA,KAAS,UAAA,EAAY,CAAA,EAAA,GAAA,WAAA,CAAY,OAAA,KAAZ,IAAA,GAAA,MAAA,GAAA,EAAA,CAAqB,KAAA,EAAA;AAAA,WAAA,IAC1C,IAAA,KAAS,QAAA,EAAU,CAAA,EAAA,GAAA,SAAA,CAAU,OAAA,KAAV,IAAA,GAAA,MAAA,GAAA,EAAA,CAAmB,KAAA,EAAA;AAAA,WAAA,IACtC,IAAA,KAAS,QAAA,EAAU,CAAA,EAAA,GAAA,SAAA,CAAU,OAAA,KAAV,IAAA,GAAA,MAAA,GAAA,EAAA,CAAmB,KAAA,EAAA;AAAA,WAC1C,CAAA,EAAA,GAAA,QAAA,CAAS,YAAT,IAAA,GAAA,MAAA,GAAA,EAAA,CAAkB,KAAA,EAAA;AAAA,IACzB;AACA,IAAA,UAAA,CAAW,OAAA,GAAU,OAAA;AACrB,IAAA,cAAA,CAAe,OAAA,GAAU,UAAA;AAAA,EAC3B,GAAG,CAAC,OAAA,EAAS,UAAA,EAAY,gBAAA,EAAkB,IAAI,CAAC,CAAA;AAGhD,EAAA,IAAI,WAAA,GAAyB,IAAA;AAC7B,EAAA,IAAI,CAAC,YAAY,IAAA,EAAM;AACrB,IAAA,IAAI,SAAS,QAAA,EAAU;AACrB,MAAA,WAAA,mBACEV,GAAAA;AAAA,QAAC,WAAA;AAAA,QAAA,cAAA,CAAA;AAAA,UACC,GAAA,EAAK,SAAA;AAAA,UACL,EAAA,EAAI,OAAA;AAAA,UACJ,OAAA,EAAS,4BAAW,EAAC;AAAA,UACrB,KAAA,EAAO,KAAA,IAAS,IAAA,GAAO,MAAA,CAAO,KAAK,CAAA,GAAI,EAAA;AAAA,UACvC,QAAA,EAAU,CAAC,CAAA,KAAM,QAAA,IAAA,IAAA,GAAA,MAAA,GAAA,QAAA,CAAW,CAAA,CAAA;AAAA,UAC5B,WAAA;AAAA,UACA,MAAA,EAAQ,MAAM,UAAA,CAAW,IAAI;AAAA,SAAA,EACzB,WAAA;AAAA,OACN;AAAA,IAEJ,CAAA,MAAA,IAAW,SAAS,UAAA,EAAY;AAC9B,MAAA,WAAA,mBACEA,GAAAA;AAAA,QAAC,UAAA;AAAA,QAAA;AAAA,UACC,GAAA,EAAK,WAAA;AAAA,UACL,EAAA,EAAI,OAAA;AAAA,UACJ,MAAM,IAAA,IAAA,IAAA,GAAA,IAAA,GAAQ,CAAA;AAAA,UACd,WAAA;AAAA,UACA,cAAA,EAAc,UAAU,IAAA,GAAO,MAAA;AAAA,UAC/B,MAAA,EAAQ,MAAM,UAAA,CAAW,IAAI,CAAA;AAAA,UAC7B,OAAO,KAAA,IAAA,IAAA,GAAA,KAAA,GAAS,EAAA;AAAA,UAChB,QAAA,EAAU,CAAC,CAAA,KAAM,QAAA,IAAA,IAAA,GAAA,MAAA,GAAA,QAAA,CAAW,EAAE,MAAA,CAAO,KAAA,CAAA;AAAA,UACrC,SAAA,EAAU;AAAA;AAAA,OACZ;AAAA,IAEJ,CAAA,MAAA,IAAW,SAAS,QAAA,EAAU;AAC5B,MAAA,MAAM,YAAY,OAAA,IAAA,IAAA,GAAA,MAAA,GAAA,OAAA,CAAU,CAAA,CAAA;AAC5B,MAAA,MAAM,WAAW,OAAA,IAAA,IAAA,GAAA,MAAA,GAAA,OAAA,CAAU,CAAA,CAAA;AAC3B,MAAA,MAAM,OAAA,GAAU,YAAY,IAAA,IAAQ,MAAA,CAAO,KAAK,CAAA,KAAM,MAAA,CAAO,SAAS,KAAK,CAAA;AAC3E,MAAA,MAAM,WAAA,GAAc,OAAA,GAAU,QAAA,IAAA,IAAA,GAAA,MAAA,GAAA,QAAA,CAAU,KAAA,GAAQ,SAAA,IAAA,IAAA,GAAA,MAAA,GAAA,SAAA,CAAW,KAAA;AAC3D,MAAA,WAAA,mBACEC,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gCAAA,EACb,QAAA,EAAA;AAAA,wBAAAD,GAAAA;AAAA,UAAC,MAAA;AAAA,UAAA,cAAA,CAAA;AAAA,YACC,GAAA,EAAK,SAAA;AAAA,YACL,EAAA,EAAI,OAAA;AAAA,YACJ,OAAA;AAAA,YACA,eAAA,EAAiB,CAAC,IAAA,KAAkB;AAClC,cAAA,UAAA,CAAW,IAAI,CAAA;AACf,cAAA,QAAA,IAAA,IAAA,GAAA,MAAA,GAAA,QAAA,CAAW,MAAA,CAAO,IAAA,GAAO,QAAA,IAAA,IAAA,GAAA,MAAA,GAAA,QAAA,CAAU,KAAA,GAAQ,uCAAW,KAAK,CAAA,CAAA;AAAA,YAC7D;AAAA,WAAA,EACI,WAAA;AAAA,SACN;AAAA,QACC,eAAe,IAAA,oBACdA,IAAC,MAAA,EAAA,EAAK,SAAA,EAAU,iCAAiC,QAAA,EAAA,WAAA,EAAY;AAAA,OAAA,EAEjE,CAAA;AAAA,IAEJ,CAAA,MAAA,IAAW,SAAS,QAAA,EAAU;AAC5B,MAAA,WAAA,mBACEA,GAAAA;AAAA,QAAC,gBAAA;AAAA,QAAA,cAAA,CAAA;AAAA,UACC,GAAA,EAAK,SAAA;AAAA,UACL,OAAO,KAAA,GAAQ,CAAC,OAAO,KAAK,CAAC,IAAI,EAAC;AAAA,UAClC,QAAA,EAAU,CAAC,IAAA,KAAM;AA1W3B,YAAA,IAAA,EAAA;AA0W8B,YAAA,OAAA,QAAA,IAAA,IAAA,GAAA,MAAA,GAAA,QAAA,CAAA,CAAW,EAAA,GAAA,IAAA,CAAK,CAAC,CAAA,KAAN,IAAA,GAAA,EAAA,GAAW,EAAA,CAAA;AAAA,UAAA,CAAA;AAAA,UAC1C,QAAA,EAAU;AAAA,SAAA,EACN,WAAA;AAAA,OACN;AAAA,IAEJ,CAAA,MAAA,IAAW,eAAA,CAAgB,QAAA,CAAS,IAAwB,CAAA,EAAG;AAC7D,MAAA,WAAA,mBACEA,GAAAA;AAAA,QAAC,KAAA;AAAA,QAAA,cAAA,CAAA;AAAA,UACC,GAAA,EAAK,QAAA;AAAA,UACL,EAAA,EAAI,OAAA;AAAA,UACJ,SAAA,EAAU,SAAA;AAAA,UACV,WAAA;AAAA,UACA,cAAA,EAAc,UAAU,IAAA,GAAO,MAAA;AAAA,UAC/B,MAAA,EAAQ,MAAM,UAAA,CAAW,IAAI,CAAA;AAAA,UAC7B,KAAA,EACE,UAAU,EAAA,IAAM,KAAA,IAAS,OACrB,EAAA,GACA,YAAA,CAAa,MAA0B,KAAK,CAAA;AAAA,UAElD,QAAA,EAAU,CAAC,CAAA,KAAM;AACf,YAAA,MAAM,GAAA,GAAM,WAAW,IAAwB,CAAA;AAC/C,YAAA,IAAI,SAAS,CAAA,CAAE,MAAA,CAAO,KAAA,CAAM,OAAA,CAAQ,UAAU,EAAE,CAAA;AAChD,YAAA,IAAI,GAAA,EAAK,MAAA,GAAS,MAAA,CAAO,KAAA,CAAM,GAAG,GAAG,CAAA;AACrC,YAAA,QAAA,IAAA,IAAA,GAAA,MAAA,GAAA,QAAA,CAAW,MAAA,CAAA;AAAA,UACb;AAAA,SAAA,EACI,UAAA;AAAA,OACN;AAAA,IAEJ,CAAA,MAAO;AACL,MAAA,WAAA,mBACEA,GAAAA;AAAA,QAAC,KAAA;AAAA,QAAA,cAAA,CAAA;AAAA,UACC,GAAA,EAAK,QAAA;AAAA,UACL,EAAA,EAAI,OAAA;AAAA,UACJ,IAAA;AAAA,UACA,WAAA;AAAA,UACA,cAAA,EAAc,UAAU,IAAA,GAAO,MAAA;AAAA,UAC/B,MAAA,EAAQ,MAAM,UAAA,CAAW,IAAI,CAAA;AAAA,UAC7B,OAAO,KAAA,IAAA,IAAA,GAAA,KAAA,GAAS,EAAA;AAAA,UAChB,QAAA,EAAU,CAAC,CAAA,KAAM,QAAA,IAAA,IAAA,GAAA,MAAA,GAAA,QAAA,CAAW,EAAE,MAAA,CAAO,KAAA;AAAA,SAAA,EACjC,UAAA;AAAA,OACN;AAAA,IAEJ;AAAA,EACF;AAEA,EAAA,MAAM,UAAU,QAAA,IAAA,IAAA,GAAA,QAAA,GAAY,WAAA;AAE5B,EAAA,MAAM,OAAA,GAAU,wBACdC,IAAAA;AAAA,IAACK,MAAAA;AAAA,IAAA;AAAA,MACC,OAAA;AAAA,MACA,SAAA,EAAW,EAAA;AAAA,QACT,UAAA,IAAc,uBAAA;AAAA,QACd,CAAC,UAAA,IAAc,QAAA;AAAA,QACf;AAAA,OACF;AAAA,MAEC,QAAA,EAAA;AAAA,QAAA,KAAA;AAAA,QACA,4BAAYN,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,2BAA0B,QAAA,EAAA,GAAA,EAAC;AAAA;AAAA;AAAA,GAC1D,GACE,IAAA;AAEJ,EAAA,MAAM,YACJ,UAAA,IAAc,IAAA,mBACZA,GAAAA,CAAC,GAAA,EAAA,EAAE,WAAU,iCAAA,EAAmC,QAAA,EAAA,UAAA,EAAW,CAAA,GACzD,WAAA,IAAe,uBACjBA,GAAAA,CAAC,OAAE,SAAA,EAAU,sCAAA,EAAwC,uBAAY,CAAA,GAC/D,IAAA;AAEN,EAAA,IAAI,UAAA,EAAY;AACd,IAAA,uBACEC,IAAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAW,EAAA,CAAG,4CAAA,EAA8C,SAAS,CAAA;AAAA,QAEpE,QAAA,EAAA;AAAA,UAAA,OAAA;AAAA,0BACDA,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gBAAA,EACZ,QAAA,EAAA;AAAA,YAAA,OAAA;AAAA,YACA;AAAA,WAAA,EACH;AAAA;AAAA;AAAA,KACF;AAAA,EAEJ;AAEA,EAAA,uBACEA,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAW,EAAA,CAAG,eAAA,EAAiB,SAAS,CAAA,EAC1C,QAAA,EAAA;AAAA,IAAA,OAAA;AAAA,IACA,OAAA;AAAA,IACA;AAAA,GAAA,EACH,CAAA;AAEJ;AC7ZO,SAAS,aACd,OAAA,EACA;AAOA,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAIE,SAAiB,OAAO,CAAA;AACpD,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAIA,SAAS,KAAK,CAAA;AAEhD,EAAA,MAAM,KAAA,GAAQW,MAAAA,CAA4C,EAAE,CAAA;AAE5D,EAAA,MAAM,UAAA,GAAaA,MAAAA,CAAoB,EAAE,CAAA;AAEzC,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAIX,SAAyB,IAAI,CAAA;AAEnE,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAIA,SAAS,CAAC,CAAA;AAG9C,EAAA,MAAM,KAAA,GAAQ,CAAC,IAAA,EAAe,IAAA,GAAkB,EAAC,KAAM;AACrD,IAAA,KAAA,CAAM,OAAA,CAAQ,IAAI,CAAA,GAAI,IAAA;AACtB,IAAA,IAAI,CAAC,WAAW,OAAA,CAAQ,QAAA,CAAS,IAAI,CAAA,EAAG,UAAA,CAAW,OAAA,CAAQ,IAAA,CAAK,IAAI,CAAA;AACpE,IAAA,OAAO;AAAA,MACL,KAAA,EAAO,OAAO,IAAI,CAAA;AAAA,MAClB,QAAA,EAAU,CAAC,CAAA,KACT,SAAA,CAAU,CAAC,CAAA,KAAO,aAAA,CAAA,cAAA,CAAA,EAAA,EAAK,CAAA,CAAA,EAAL,EAAQ,CAAC,IAAI,GAAG,GAAE,CAAY,CAAA;AAAA,MAClD,MAAM,IAAA,CAAK,IAAA;AAAA,MACX,UAAU,IAAA,CAAK,QAAA;AAAA,MACf,UAAU,IAAA,CAAK,QAAA;AAAA,MACf,aAAA,EAAe,SAAA;AAAA,MACf,kBAAkB,WAAA,KAAgB,IAAA;AAAA,MAClC;AAAA,KACF;AAAA,EACF,CAAA;AAGA,EAAA,MAAM,OAAA,GAAU,CAAC,IAAA,KAAe;AA5ElC,IAAA,IAAA,EAAA;AA6EI,IAAA,OAAA,aAAA,CAAA,CAAc,EAAA,GAAA,KAAA,CAAM,QAAQ,IAAI,CAAA,KAAlB,YAAuB,EAAC,EAAG,MAAA,CAAO,IAAI,CAAC,CAAA;AAAA,EAAA,CAAA;AAGvD,EAAA,MAAM,WAAW,MAAM;AACrB,IAAA,YAAA,CAAa,IAAI,CAAA;AACjB,IAAA,MAAM,YAAA,GAAe,UAAA,CAAW,OAAA,CAAQ,IAAA,CAAK,CAAC,SAAS,CAAC,CAAC,OAAA,CAAQ,IAAI,CAAC,CAAA;AACtE,IAAA,cAAA,CAAe,sCAAgB,IAAI,CAAA;AACnC,IAAA,aAAA,CAAc,CAAC,CAAA,KAAM,CAAA,GAAI,CAAC,CAAA;AAC1B,IAAA,OAAO,YAAA,KAAiB,MAAA;AAAA,EAC1B,CAAA;AAOA,EAAA,MAAM,KAAA,GAAQ,CAAC,MAAA,KAAsD;AACnE,IAAA,IAAI,CAAC,MAAA,EAAQ;AACX,MAAA,SAAA,CAAU,OAAO,CAAA;AAAA,IACnB,CAAA,MAAO;AACL,MAAA,MAAM,OAAO,cAAA,CAAA,EAAA,EAAK,OAAA,CAAA;AAClB,MAAC,OAAO,IAAA,CAAK,OAAO,CAAA,CAAkB,OAAA,CAAQ,CAAC,GAAA,KAAQ;AACrD,QAAA,MAAM,CAAA,GAAI,OAAO,GAAG,CAAA;AACpB,QAAA,IAAI,CAAA,KAAM,MAAA,IAAa,CAAA,KAAM,IAAA,EAAM;AAIjC,UAAA,IAAA,CAAK,GAAG,CAAA,GACN,OAAO,CAAA,KAAM,QAAA,GAAW,KAAK,SAAA,CAAU,CAAC,CAAA,GAAI,MAAA,CAAO,CAAC,CAAA;AAAA,QAExD;AAAA,MACF,CAAC,CAAA;AACD,MAAA,SAAA,CAAU,IAAI,CAAA;AAAA,IAChB;AACA,IAAA,YAAA,CAAa,KAAK,CAAA;AAClB,IAAA,cAAA,CAAe,IAAI,CAAA;AAAA,EACrB,CAAA;AAEA,EAAA,OAAO,EAAE,QAAQ,SAAA,EAAW,SAAA,EAAW,cAAc,KAAA,EAAO,OAAA,EAAS,UAAU,KAAA,EAAM;AACvF;ACpFA,IAAM,UAAA,GAA6C;AAAA,EACjD,EAAA,EAAS,aAAA;AAAA,EACT,OAAA,EAAS,cAAA;AAAA,EACT,EAAA,EAAS;AACX,CAAA;AAEA,IAAM,SAAA,GAA4C;AAAA,EAChD,EAAA,EAAS,EAAA;AAAA,EACT,OAAA,EAAS,EAAA;AAAA,EACT,EAAA,EAAS;AACX,CAAA;AAGA,IAAM,OAAA,GAA0C;AAAA,EAC9C,EAAA,EAAS,OAAA;AAAA,EACT,OAAA,EAAS,KAAA;AAAA,EACT,EAAA,EAAS;AACX,CAAA;AAGA,IAAM,SAAA,GAAgF;AAAA,EACpF,IAAS,EAAE,IAAA,EAAM,QAAQ,GAAA,EAAK,MAAA,EAAS,KAAK,OAAA,EAAQ;AAAA,EACpD,SAAS,EAAE,IAAA,EAAM,QAAQ,GAAA,EAAK,MAAA,EAAS,KAAK,OAAA,EAAQ;AAAA,EACpD,IAAS,EAAE,IAAA,EAAM,QAAQ,GAAA,EAAK,OAAA,EAAS,KAAK,OAAA;AAC9C,CAAA;AAqCO,SAAS,WAAW,EAAA,EAkBP;AAlBO,EAAA,IAAA,EAAA,GAAA,EAAA,EACzB;AAAA,IAAA,MAAA,GAAS,SAAA;AAAA,IACT,IAAA,GAAO,SAAA;AAAA,IACP,KAAA;AAAA,IACA,cAAA;AAAA,IACA,QAAA;AAAA,IACA,SAAA;AAAA,IACA,IAAA;AAAA,IACA,KAAA;AAAA,IACA,SAAA;AAAA,IACA,EAAA,EAAI,MAAA;AAAA,IACJ,IAAA;AAAA,IACA,KAAA;AAAA,IACA,QAAA,EAAU,SAAA;AAAA,IACV,aAAA,EAAe,cAAA;AAAA,IACf,gBAAA,EAAkB,iBAAA;AAAA,IAClB,UAAA,EAAY;AAAA,GA7Gd,GA6F2B,EAAA,EAiBtB,UAAA,GAAA,SAAA,CAjBsB,EAAA,EAiBtB;AAAA,IAhBH,QAAA;AAAA,IACA,MAAA;AAAA,IACA,OAAA;AAAA,IACA,gBAAA;AAAA,IACA,UAAA;AAAA,IACA,WAAA;AAAA,IACA,MAAA;AAAA,IACA,OAAA;AAAA,IACA,WAAA;AAAA,IACA,IAAA;AAAA,IACA,MAAA;AAAA,IACA,OAAA;AAAA,IACA,UAAA;AAAA,IACA,eAAA;AAAA,IACA,kBAAA;AAAA,IACA;AAAA,GAAA,CAAA;AAGA,EAAA,MAAM,SAAS,KAAA,EAAM;AACrB,EAAA,MAAM,KAAK,MAAA,IAAA,IAAA,GAAA,MAAA,GAAU,MAAA;AACrB,EAAA,MAAM,aAAa,IAAA,KAAS,UAAA;AAC5B,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAIA,SAAS,KAAK,CAAA;AAC1C,EAAA,MAAM,QAAA,GAAW,UAAU,IAAI,CAAA;AAE/B,EAAA,MAAM,WAAW,SAAA,IAAa,UAAA;AAC9B,EAAA,MAAM,WAAA,GAAc,SAAA,IAAa,KAAA,KAAU,EAAA,IAAM,KAAA,IAAS,IAAA;AAC1D,EAAA,MAAM,QAAA,GAAA,CAAY,SAAA,GAAY,CAAA,GAAI,CAAA,KAAM,aAAa,CAAA,GAAI,CAAA,CAAA;AACzD,EAAA,MAAM,YAAA,GAAe,UAAU,IAAI,CAAA,CAAE,aAAa,CAAA,GAAI,KAAA,GAAQ,QAAA,GAAW,KAAA,GAAQ,MAAM,CAAA;AAEvF,EAAA,MAAM,OAAA,mBACJF,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,UAAA,EACb,QAAA,EAAA;AAAA,oBAAAD,GAAAA;AAAA,MAAC,OAAA;AAAA,MAAA,cAAA,CAAA;AAAA,QACC,EAAA;AAAA,QACA,IAAA,EAAM,UAAA,GAAc,MAAA,GAAS,MAAA,GAAS,UAAA,GAAc,IAAA;AAAA,QACpD,KAAA;AAAA,QACA,cAAA,EAAc,QAAQ,IAAA,GAAO,MAAA;AAAA,QAC7B,QAAA,EAAU,CAAC,CAAA,KAAM,QAAA,IAAA,IAAA,GAAA,MAAA,GAAA,QAAA,CAAW,EAAE,MAAA,CAAO,KAAA,CAAA;AAAA,QACrC,SAAA,EAAW,EAAA;AAAA,UACT,iIAAA;AAAA,UACA,0FAAA;AAAA,UACA,+EAAA;AAAA,UACA,iDAAA;AAAA,UACA,kEAAA;AAAA,UACA,WAAW,IAAI,CAAA;AAAA,UACf;AAAA;AACF,OAAA,EACI,UAAA;AAAA,KACN;AAAA,IAGC,QAAA,oBACCC,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,mDAAA,EAEZ,QAAA,EAAA;AAAA,MAAA,SAAA,oBACCD,GAAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UACC,IAAA,EAAK,QAAA;AAAA,UACL,QAAA,EAAU,EAAA;AAAA,UACV,OAAA,EAAS,MAAM,QAAA,IAAA,IAAA,GAAA,MAAA,GAAA,QAAA,CAAW,EAAA,CAAA;AAAA,UAC1B,SAAA,EAAW,EAAA;AAAA,YACT,yGAAA;AAAA,YACA,QAAQ,IAAI,CAAA;AAAA,YACZ,cAAc,aAAA,GAAgB;AAAA,WAChC;AAAA,UACA,YAAA,EAAW,iCAAA;AAAA,UAEX,QAAA,kBAAAA,GAAAA,CAACgB,CAAAA,EAAA,EAAE,MAAM,QAAA,EAAU;AAAA;AAAA,OACrB;AAAA,MAID,8BACChB,GAAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UACC,IAAA,EAAK,QAAA;AAAA,UACL,QAAA,EAAU,EAAA;AAAA,UACV,SAAS,MAAM,SAAA,CAAU,CAAC,CAAA,KAAM,CAAC,CAAC,CAAA;AAAA,UAClC,SAAA,EAAW,EAAA,CAAG,wGAAA,EAA0G,OAAA,CAAQ,IAAI,CAAC,CAAA;AAAA,UACrI,YAAA,EAAY,SAAS,6CAAA,GAAa,uCAAA;AAAA,UAEjC,QAAA,EAAA,MAAA,mBAASA,GAAAA,CAAC,MAAA,EAAA,EAAO,IAAA,EAAM,QAAA,EAAU,CAAA,mBAAKA,GAAAA,CAAC,GAAA,EAAA,EAAI,IAAA,EAAM,QAAA,EAAU;AAAA;AAAA;AAC9D,KAAA,EAEJ;AAAA,GAAA,EAEJ,CAAA;AAGF,EAAA,MAAM,MAAA,GAAS,IAAA,mBACbA,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAW,EAAA,CAAG,cAAA,EAAgB,KAAA,GAAQ,kBAAA,GAAqB,uBAAuB,CAAA,EAClF,gBACH,CAAA,GACE,IAAA;AAEJ,EAAA,IAAI,CAAC,KAAA,EAAO;AACV,IAAA,uBACEC,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EACF,QAAA,EAAA;AAAA,MAAA,OAAA;AAAA,MACA;AAAA,KAAA,EACH,CAAA;AAAA,EAEJ;AAEA,EAAA,IAAI,WAAW,QAAA,EAAU;AACvB,IAAA,uBACEA,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAW,EAAA,CAAG,yBAAA,EAA2B,SAAS,CAAA,EACrD,QAAA,EAAA;AAAA,sBAAAD,GAAAA;AAAA,QAACM,MAAAA;AAAA,QAAA;AAAA,UACC,OAAA,EAAS,EAAA;AAAA,UACT,SAAA,EAAW,EAAA,CAAG,wCAAA,EAA0C,cAAA,IAAA,IAAA,GAAA,cAAA,GAAkB,MAAM,CAAA;AAAA,UAE/E,QAAA,EAAA;AAAA;AAAA,OACH;AAAA,sBACAL,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gBAAA,EACZ,QAAA,EAAA;AAAA,QAAA,OAAA;AAAA,QACA;AAAA,OAAA,EACH;AAAA,KAAA,EACF,CAAA;AAAA,EAEJ;AAGA,EAAA,uBACEA,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAW,EAAA,CAAG,qBAAA,EAAuB,SAAS,CAAA,EACjD,QAAA,EAAA;AAAA,oBAAAD,IAACM,MAAAA,EAAA,EAAM,SAAS,EAAA,EAAI,SAAA,EAAU,iCAC3B,QAAA,EAAA,KAAA,EACH,CAAA;AAAA,IACC,OAAA;AAAA,IACA;AAAA,GAAA,EACH,CAAA;AAEJ;AC5KO,SAAS,cAAc,EAAA,EAgBP;AAhBO,EAAA,IAAA,EAAA,GAAA,EAAA,EAC5B;AAAA,IAAA,MAAA,GAAS,SAAA;AAAA,IACT,KAAA;AAAA,IACA,cAAA;AAAA,IACA,QAAA;AAAA,IACA,IAAA;AAAA,IACA,KAAA;AAAA,IACA,SAAA;AAAA,IACA,EAAA,EAAI,MAAA;AAAA,IACJ,IAAA,GAAO,CAAA;AAAA,IACP,KAAA;AAAA,IACA,QAAA,EAAU,SAAA;AAAA,IACV,aAAA,EAAe,cAAA;AAAA,IACf,gBAAA,EAAkB,iBAAA;AAAA,IAClB,UAAA,EAAY;AAAA,GAhEd,GAkD8B,EAAA,EAezB,aAAA,GAAA,SAAA,CAfyB,EAAA,EAezB;AAAA,IAdH,QAAA;AAAA,IACA,OAAA;AAAA,IACA,gBAAA;AAAA,IACA,UAAA;AAAA,IACA,MAAA;AAAA,IACA,OAAA;AAAA,IACA,WAAA;AAAA,IACA,IAAA;AAAA,IACA,MAAA;AAAA,IACA,OAAA;AAAA,IACA,UAAA;AAAA,IACA,eAAA;AAAA,IACA,kBAAA;AAAA,IACA;AAAA,GAAA,CAAA;AAGA,EAAA,MAAM,SAASa,KAAAA,EAAM;AACrB,EAAA,MAAM,KAAK,MAAA,IAAA,IAAA,GAAA,MAAA,GAAU,MAAA;AAErB,EAAA,MAAM,6BACJnB,GAAAA;AAAA,IAAC,UAAA;AAAA,IAAA,cAAA,CAAA;AAAA,MACC,EAAA;AAAA,MACA,IAAA;AAAA,MACA,KAAA;AAAA,MACA,cAAA,EAAc,QAAQ,IAAA,GAAO,MAAA;AAAA,MAC7B,QAAA,EAAU,CAAC,CAAA,KAAM,QAAA,IAAA,IAAA,GAAA,MAAA,GAAA,QAAA,CAAW,EAAE,MAAA,CAAO,KAAA,CAAA;AAAA,MACrC,SAAA,EAAW,EAAA;AAAA,QACT,uJAAA;AAAA,QACA,0FAAA;AAAA,QACA,+EAAA;AAAA,QACA,iDAAA;AAAA,QACA;AAAA;AACF,KAAA,EACI,aAAA;AAAA,GACN;AAGF,EAAA,MAAM,MAAA,GAAS,IAAA,mBACbA,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAW,EAAA,CAAG,cAAA,EAAgB,KAAA,GAAQ,kBAAA,GAAqB,uBAAuB,CAAA,EAClF,gBACH,CAAA,GACE,IAAA;AAEJ,EAAA,IAAI,CAAC,KAAA,EAAO;AACV,IAAA,uBACEC,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EACF,QAAA,EAAA;AAAA,MAAA,UAAA;AAAA,MACA;AAAA,KAAA,EACH,CAAA;AAAA,EAEJ;AAEA,EAAA,IAAI,WAAW,QAAA,EAAU;AACvB,IAAA,uBACEA,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAW,EAAA,CAAG,wBAAA,EAA0B,SAAS,CAAA,EACpD,QAAA,EAAA;AAAA,sBAAAD,GAAAA;AAAA,QAACM,MAAAA;AAAA,QAAA;AAAA,UACC,OAAA,EAAS,EAAA;AAAA,UACT,SAAA,EAAW,EAAA,CAAG,6CAAA,EAA+C,cAAA,IAAA,IAAA,GAAA,cAAA,GAAkB,MAAM,CAAA;AAAA,UAEpF,QAAA,EAAA;AAAA;AAAA,OACH;AAAA,sBACAL,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gBAAA,EACZ,QAAA,EAAA;AAAA,QAAA,UAAA;AAAA,QACA;AAAA,OAAA,EACH;AAAA,KAAA,EACF,CAAA;AAAA,EAEJ;AAGA,EAAA,uBACEA,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAW,EAAA,CAAG,qBAAA,EAAuB,SAAS,CAAA,EACjD,QAAA,EAAA;AAAA,oBAAAD,IAACM,MAAAA,EAAA,EAAM,SAAS,EAAA,EAAI,SAAA,EAAU,iCAC3B,QAAA,EAAA,KAAA,EACH,CAAA;AAAA,IACC,UAAA;AAAA,IACA;AAAA,GAAA,EACH,CAAA;AAEJ;ACrFA,SAAS,WAAW,CAAA,EAAuC;AA7C3D,EAAA,IAAA,EAAA,EAAA,EAAA;AA8CI,EAAA,IAAI;AACA,IAAA,CAAC,EAAA,GAAA,CAAA,EAAA,GAAA,CAAA,CAAE,eAAmC,UAAA,KAArC,IAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,IAAA,CAAA,EAAA,CAAA;AAAA,EACL,SAAQc,EAAAA,EAAA;AAAA,EAER;AACJ;AAEO,IAAM,cAAA,GAAiBR,UAAAA;AAAA,EAC1B,SAASS,eAAAA,CACL;AAAA,IACI,KAAA,GAAQ,EAAA;AAAA,IACR,QAAA;AAAA,IACA,WAAA,GAAc,mDAAA;AAAA,IACd,GAAA;AAAA,IACA,GAAA;AAAA,IACA,QAAA;AAAA,IACA,SAAA;AAAA,IACA,YAAA,EAAc,SAAA;AAAA,IACd;AAAA,KAEJ,GAAA,EACF;AACE,IAAA,uBACIrB,GAAAA;AAAA,MAAC,OAAA;AAAA,MAAA;AAAA,QACG,GAAA;AAAA,QACA,EAAA;AAAA,QACA,IAAA,EAAK,MAAA;AAAA,QACL,YAAA,EAAY,SAAA;AAAA,QACZ,KAAA;AAAA,QACA,GAAA;AAAA,QACA,GAAA;AAAA,QACA,QAAA;AAAA,QACA,QAAA,EAAU,CAAC,CAAA,KAAM,QAAA,IAAA,IAAA,GAAA,MAAA,GAAA,QAAA,CAAW,EAAE,MAAA,CAAO,KAAA,CAAA;AAAA,QACrC,OAAA,EAAS,UAAA;AAAA,QAET,gBAAc,KAAA,IAAS,WAAA;AAAA,QAEvB,YAAA,EAAY,QAAQ,OAAA,GAAU,MAAA;AAAA,QAC9B,SAAA,EAAW,EAAA;AAAA,UACP,kBAAA;AAAA;AAAA,UAEA,wGAAA;AAAA,UACA,+EAAA;AAAA,UACA,kDAAA;AAAA,UACA;AAAA;AACJ;AAAA,KACJ;AAAA,EAER;AACJ;ACtEA,IAAM,KAAA,uBAAY,IAAA,EAAK;AAEvB,IAAM,SAAA,GAAY;AAAA,EACd,SAAA;AAAA,EAAM,SAAA;AAAA,EAAM,SAAA;AAAA,EAAM,SAAA;AAAA,EAAM,SAAA;AAAA,EAAM,SAAA;AAAA,EAC9B,SAAA;AAAA,EAAM,SAAA;AAAA,EAAM,SAAA;AAAA,EAAM,UAAA;AAAA,EAAO,UAAA;AAAA,EAAO;AACpC,CAAA;AAEA,IAAM,SAAA,GACF,8KAAA;AAGJ,IAAM,SAAA,GACF,uPAAA;AAKJ,IAAM,eAAesB,aAAAA,CAAc;AAAA,EAC/B,SAAA,EAAW,KAAA,CAAM,WAAA,EAAY,GAAI,GAAA;AAAA,EACjC,OAAA,EAAS,KAAA,CAAM,WAAA,EAAY,GAAI;AACnC,CAAC,CAAA;AAOD,SAAS,eAAA,CAAgB,EAAE,aAAA,EAAc,EAAsB;AAC3D,EAAA,MAAM,EAAE,SAAA,EAAW,OAAA,EAAQ,GAAIC,WAAW,YAAY,CAAA;AACtD,EAAA,MAAM,EAAE,SAAA,EAAW,aAAA,EAAe,SAAA,KAAc,YAAA,EAAa;AAE7D,EAAA,MAAM,OAAO,aAAA,CAAc,IAAA;AAC3B,EAAA,MAAM,IAAA,GAAO,KAAK,WAAA,EAAY;AAC9B,EAAA,MAAM,KAAA,GAAQ,KAAK,QAAA,EAAS;AAE5B,EAAA,MAAM,QAAQ,KAAA,CAAM,IAAA;AAAA,IAChB,EAAE,MAAA,EAAQ,OAAA,GAAU,SAAA,GAAY,CAAA,EAAE;AAAA,IAClC,CAAC,CAAA,EAAG,CAAA,KAAM,SAAA,GAAY;AAAA,GAC1B;AAEA,EAAA,uBACItB,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gDAAA,EAEX,QAAA,EAAA;AAAA,oBAAAD,GAAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACG,IAAA,EAAK,QAAA;AAAA,QACL,YAAA,EAAW,qBAAA;AAAA,QACX,UAAU,CAAC,aAAA;AAAA,QACX,OAAA,EAAS,MAAM,aAAA,IAAiB,SAAA,CAAU,aAAa,CAAA;AAAA,QACvD,SAAA,EAAW,SAAA;AAAA,QAEX,QAAA,kBAAAA,GAAAA,CAAC,WAAA,EAAA,EAAY,SAAA,EAAU,QAAA,EAAS;AAAA;AAAA,KACpC;AAAA,oBAGAC,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,2BAAA,EACX,QAAA,EAAA;AAAA,sBAAAD,GAAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UACG,KAAA,EAAO,IAAA;AAAA,UACP,QAAA,EAAU,CAAC,CAAA,KACP,SAAA,CAAU,IAAI,IAAA,CAAK,MAAA,CAAO,CAAA,CAAE,MAAA,CAAO,KAAK,CAAA,EAAG,KAAK,CAAC,CAAA;AAAA,UAErD,SAAA,EAAW,SAAA;AAAA,UAEV,QAAA,EAAA,KAAA,CAAM,IAAI,CAAC,CAAA,qBACRC,IAAAA,CAAC,QAAA,EAAA,EAAe,OAAO,CAAA,EAAI,QAAA,EAAA;AAAA,YAAA,CAAA;AAAA,YAAE;AAAA,WAAA,EAAA,EAAhB,CAAiB,CACjC;AAAA;AAAA,OACL;AAAA,sBACAD,GAAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UACG,KAAA,EAAO,KAAA;AAAA,UACP,QAAA,EAAU,CAAC,CAAA,KACP,SAAA,CAAU,IAAI,IAAA,CAAK,IAAA,EAAM,MAAA,CAAO,CAAA,CAAE,MAAA,CAAO,KAAK,CAAC,CAAC,CAAA;AAAA,UAEpD,SAAA,EAAW,SAAA;AAAA,UAEV,QAAA,EAAA,SAAA,CAAU,GAAA,CAAI,CAAC,KAAA,EAAO,CAAA,qBACnBA,GAAAA,CAAC,QAAA,EAAA,EAAe,KAAA,EAAO,CAAA,EAAI,QAAA,EAAA,KAAA,EAAA,EAAd,CAAoB,CACpC;AAAA;AAAA;AACL,KAAA,EACJ,CAAA;AAAA,oBAGAA,GAAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACG,IAAA,EAAK,QAAA;AAAA,QACL,YAAA,EAAW,qBAAA;AAAA,QACX,UAAU,CAAC,SAAA;AAAA,QACX,OAAA,EAAS,MAAM,SAAA,IAAa,SAAA,CAAU,SAAS,CAAA;AAAA,QAC/C,SAAA,EAAW,SAAA;AAAA,QAEX,QAAA,kBAAAA,GAAAA,CAACwB,YAAAA,EAAA,EAAa,WAAU,QAAA,EAAS;AAAA;AAAA;AACrC,GAAA,EACJ,CAAA;AAER;AAEO,SAAS,SAAS,EAAA,EAOP;AAPO,EAAA,IAAA,EAAA,GAAA,EAAA,EACrB;AAAA,IAAA,SAAA;AAAA,IACA,UAAA;AAAA,IACA,eAAA,GAAkB,IAAA;AAAA,IAClB,UAAA;AAAA,IACA;AAAA,GA3HJ,GAsHyB,EAAA,EAMlB,KAAA,GAAA,SAAA,CANkB,EAAA,EAMlB;AAAA,IALH,WAAA;AAAA,IACA,YAAA;AAAA,IACA,iBAAA;AAAA,IACA,YAAA;AAAA,IACA;AAAA,GAAA,CAAA;AAGA,EAAA,MAAM,SAAA,GAAA,CAAa,UAAA,IAAA,IAAA,GAAA,UAAA,GAAc,IAAI,IAAA,CAAK,KAAA,CAAM,aAAY,GAAI,GAAA,EAAK,CAAC,CAAA,EAAG,WAAA,EAAY;AACrF,EAAA,MAAM,OAAA,GAAA,CAAW,QAAA,IAAA,IAAA,GAAA,QAAA,GAAY,IAAI,IAAA,CAAK,KAAA,CAAM,aAAY,GAAI,EAAA,EAAI,EAAE,CAAA,EAAG,WAAA,EAAY;AAEjF,EAAA,uBACIxB,GAAAA,CAAC,YAAA,CAAa,QAAA,EAAb,EAAsB,OAAO,EAAE,SAAA,EAAW,OAAA,EAAQ,EAC/C,QAAA,kBAAAA,GAAAA;AAAA,IAAC,SAAA;AAAA,IAAA,cAAA,CAAA,aAAA,CAAA,cAAA,CAAA,cAAA,CAAA;AAAA,MACG,MAAA,EAAQ,EAAA;AAAA,MACR;AAAA,KAAA,EACK,UAAA,GAAa,EAAE,UAAA,EAAW,GAAI,EAAC,CAAA,EAC/B,QAAA,GAAW,EAAE,QAAA,EAAS,GAAI,EAAC,CAAA,EAJnC;AAAA,MAKG,SAAA,EAAW,EAAA,CAAG,KAAA,EAAO,SAAS,CAAA;AAAA,MAC9B,UAAA,EAAY,cAAA,CAAA;AAAA,QACR,MAAA,EAAQ,qBAAA;AAAA,QACR,KAAA,EAAO,qBAAA;AAAA;AAAA,QAEP,aAAA,EAAe,uBAAA;AAAA,QACf,aAAA,EAAe,QAAA;AAAA;AAAA,QAEf,GAAA,EAAK,QAAA;AAAA;AAAA,QAEL,UAAA,EAAY,wBAAA;AAAA,QACZ,QAAA,EAAU,MAAA;AAAA,QACV,OAAA,EACI,kEAAA;AAAA,QACJ,IAAA,EAAM,WAAA;AAAA;AAAA,QAEN,GAAA,EAAK,iCAAA;AAAA,QACL,UAAA,EAAY,EAAA;AAAA,UACR,kFAAA;AAAA,UACA,8CAAA;AAAA,UACA,yEAAA;AAAA,UACA;AAAA,SACJ;AAAA;AAAA,QAEA,QAAA,EACI,mFAAA;AAAA,QACJ,KAAA,EAAO,kCAAA;AAAA,QACP,OAAA,EAAS,kCAAA;AAAA,QACT,QAAA,EAAU,gCAAA;AAAA,QACV,WAAA,EAAa,cAAA;AAAA,QACb,SAAA,EAAW,cAAA;AAAA,QACX,YAAA,EACI,+CAAA;AAAA,QACJ,MAAA,EAAQ;AAAA,OAAA,EACL,UAAA,CAAA;AAAA,MAEP,UAAA,EAAY;AAAA;AAAA,QAER,YAAA,EAAc;AAAA;AAClB,KAAA,CAAA,EACI,KAAA;AAAA,GACR,EACJ,CAAA;AAER;ACtIA,SAAS,UAAUyB,IAAAA,EAA2C;AAC1D,EAAA,IAAI,CAACA,MAAK,OAAO,MAAA;AACjB,EAAA,MAAM,CAAC,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA,GAAIA,KAAI,KAAA,CAAM,GAAG,CAAA,CAAE,GAAA,CAAI,MAAM,CAAA;AAC3C,EAAA,IAAI,CAAC,CAAA,IAAK,CAAC,CAAA,IAAK,CAAC,GAAG,OAAO,MAAA;AAC3B,EAAA,OAAO,IAAI,IAAA,CAAK,CAAA,EAAG,CAAA,GAAI,GAAG,CAAC,CAAA;AAC/B;AAGA,SAASC,YAAW,IAAA,EAAoB;AACpC,EAAA,MAAM,CAAA,GAAI,KAAK,WAAA,EAAY;AAC3B,EAAA,MAAM,CAAA,GAAI,OAAO,IAAA,CAAK,QAAA,KAAa,CAAC,CAAA,CAAE,QAAA,CAAS,CAAA,EAAG,GAAG,CAAA;AACrD,EAAA,MAAM,CAAA,GAAI,OAAO,IAAA,CAAK,OAAA,EAAS,CAAA,CAAE,QAAA,CAAS,GAAG,GAAG,CAAA;AAChD,EAAA,OAAO,CAAA,EAAG,CAAC,CAAA,CAAA,EAAI,CAAC,IAAI,CAAC,CAAA,CAAA;AACzB;AAEO,SAAS,eAAA,CAAgB;AAAA,EAC5B,KAAA,GAAQ,EAAA;AAAA,EACR,QAAA;AAAA,EACA,WAAA,GAAc,mDAAA;AAAA,EACd,GAAA;AAAA,EACA,GAAA;AAAA,EACA,SAAA,GAAY,KAAA;AAAA,EACZ,QAAA;AAAA,EACA,SAAA;AAAA,EACA,cAAA,GAAiB,QAAA;AAAA,EACjB,EAAA;AAAA,EACA,YAAA,EAAc;AAClB,CAAA,EAAyB;AAzEzB,EAAA,IAAA,EAAA;AA0EI,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAIvB,SAAS,KAAK,CAAA;AAEtC,EAAA,MAAM,QAAA,GAAW,UAAU,KAAK,CAAA;AAChC,EAAA,MAAM,OAAA,GAAU,UAAU,GAAG,CAAA;AAC7B,EAAA,MAAM,OAAA,GAAU,UAAU,GAAG,CAAA;AAI7B,EAAA,MAAM,YAAA,GAAA,CAAe,EAAA,GAAA,QAAA,IAAA,IAAA,GAAA,QAAA,GAAY,OAAA,KAAZ,IAAA,GAAA,EAAA,GAAuB,OAAA;AAE5C,EAAA,MAAM,YAAA,GAAe,CAAC,IAAA,KAA2B;AAC7C,IAAA,QAAA,IAAA,IAAA,GAAA,MAAA,GAAA,QAAA,CAAW,IAAA,GAAOuB,WAAAA,CAAW,IAAI,CAAA,GAAI,EAAA,CAAA;AACrC,IAAA,IAAI,IAAA,UAAc,KAAK,CAAA;AAAA,EAC3B,CAAA;AAEA,EAAA,MAAM,WAAA,GAAc,CAAC,CAAA,KAAwB;AACzC,IAAA,CAAA,CAAE,eAAA,EAAgB;AAClB,IAAA,QAAA,IAAA,IAAA,GAAA,MAAA,GAAA,QAAA,CAAW,EAAA,CAAA;AAAA,EACf,CAAA;AAEA,EAAA,uBACIzB,IAAAA,CAAC,OAAA,EAAA,EAAQ,MAAY,YAAA,EAAc,QAAA,GAAW,SAAY,OAAA,EACtD,QAAA,EAAA;AAAA,oBAAAD,GAAAA,CAAC,cAAA,EAAA,EAAe,OAAA,EAAO,IAAA,EACnB,QAAA,kBAAAC,IAAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACG,EAAA;AAAA,QACA,IAAA,EAAK,QAAA;AAAA,QACL,cAAY,SAAA,IAAA,IAAA,GAAA,SAAA,GAAa,WAAA;AAAA,QACzB,eAAA,EAAe,IAAA;AAAA,QACf,QAAA;AAAA,QACA,SAAA,EAAW,EAAA;AAAA,UACP,kGAAA;AAAA,UACA,0GAAA;AAAA,UACA,kDAAA;AAAA,UACA,WAAA;AAAA,UACA,cAAA;AAAA,UACA;AAAA,SACJ;AAAA,QAEA,QAAA,EAAA;AAAA,0BAAAD,GAAAA,CAAC,YAAA,EAAA,EAAa,SAAA,EAAU,uCAAA,EAAwC,CAAA;AAAA,0BAChEA,GAAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACG,SAAA,EAAW,EAAA;AAAA,gBACP,iBAAA;AAAA,gBACA,CAAC,KAAA,IAAS;AAAA,eACd;AAAA,cAEC,QAAA,EAAA,KAAA,IAAS;AAAA;AAAA,WACd;AAAA,UAEC,SAAA,IAAa,KAAA,IAAS,CAAC,QAAA,oBACpBA,GAAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACG,IAAA,EAAK,QAAA;AAAA,cACL,YAAA,EAAW,iCAAA;AAAA,cACX,OAAA,EAAS,WAAA;AAAA,cACT,SAAA,EAAU,iEAAA;AAAA,cAEV,QAAA,kBAAAA,GAAAA,CAACgB,CAAAA,EAAA,EAAE,WAAU,UAAA,EAAW;AAAA;AAAA;AAC5B;AAAA;AAAA,KAER,EACJ,CAAA;AAAA,oBAEAhB,GAAAA,CAAC,cAAA,EAAA,EAAe,WAAU,YAAA,EAAa,KAAA,EAAM,SACzC,QAAA,kBAAAA,GAAAA;AAAA,MAAC,QAAA;AAAA,MAAA,cAAA,CAAA,cAAA,CAAA,cAAA,CAAA;AAAA,QACG,IAAA,EAAK,QAAA;AAAA,QACL,QAAA;AAAA,QACA,QAAA,EAAU,YAAA;AAAA,QACV;AAAA,OAAA,EAEK,OAAA,GAAU,EAAE,UAAA,EAAY,OAAA,KAAY,EAAC,CAAA,EACrC,OAAA,GAAU,EAAE,UAAU,OAAA,EAAQ,GAAI,EAAC,CAAA,EAEnC,WAAW,OAAA,GACV;AAAA,QACI,QAAA,EAAU;AAAA,UACN,GAAI,UAAU,CAAC,EAAE,QAAQ,OAAA,EAAS,IAAI,EAAC;AAAA,UACvC,GAAI,UAAU,CAAC,EAAE,OAAO,OAAA,EAAS,IAAI;AAAC;AAC1C,UAEJ,EAAC;AAAA,KACX,EACJ;AAAA,GAAA,EACJ,CAAA;AAER;ACtGO,SAAS,WAAA,CAAY;AAAA,EAC1B,QAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAAA,EACA,KAAA,GAAQ,2BAAA;AAAA,EACR,WAAA,GAAc,IAAA;AAAA,EACd,WAAA,GAAc,IAAA;AAAA,EACd,WAAA,GAAc,cAAA;AAAA,EACd,UAAA,GAAa,oBAAA;AAAA,EACb,OAAA,GAAU,KAAA;AAAA,EACV,OAAA;AAAA,EACA;AACF,CAAA,EAAqB;AACnB,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAIG,SAAS,WAAW,CAAA;AAC5C,EAAA,MAAM,QAAA,GAAW,cAAc,IAAA,GAAO,IAAA;AAEtC,EAAA,uBACEF,IAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,EAAA;AAAA,QACT,0DAAA;AAAA,QACA;AAAA,OACF;AAAA,MAGC,QAAA,EAAA;AAAA,QAAA,WAAA,mBACCA,IAAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,QAAA;AAAA,YACL,SAAS,MAAM,OAAA,CAAQ,CAAC,CAAA,KAAM,CAAC,CAAC,CAAA;AAAA,YAChC,eAAA,EAAe,QAAA;AAAA,YACf,SAAA,EAAU,oIAAA;AAAA,YAET,QAAA,EAAA;AAAA,cAAA,KAAA;AAAA,8BACDD,GAAAA;AAAA,gBAACW,WAAAA;AAAA,gBAAA;AAAA,kBACC,SAAA,EAAW,EAAA;AAAA,oBACT,4DAAA;AAAA,oBACA,CAAC,QAAA,IAAY;AAAA;AACf;AAAA;AACF;AAAA;AAAA,YAGF,KAAA,oBACEX,IAAC,KAAA,EAAA,EAAI,SAAA,EAAU,iCAAiC,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,QAIzD,4BACCC,IAAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,QAAA,EAAU,CAAC,CAAA,KAAM;AACf,cAAA,CAAA,CAAE,cAAA,EAAe;AACjB,cAAA,QAAA,IAAA,IAAA,GAAA,MAAA,GAAA,QAAA,EAAA;AAAA,YACF,CAAA;AAAA,YAGA,QAAA,EAAA;AAAA,8BAAAD,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,8BAAA,EAAgC,QAAA,EAAS,CAAA;AAAA,8BAGxDC,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,+CAAA,EACZ,QAAA,EAAA;AAAA,gBAAA,OAAA;AAAA,gBACA,2BACCA,IAAAA;AAAA,kBAAC,MAAA;AAAA,kBAAA;AAAA,oBACC,IAAA,EAAK,QAAA;AAAA,oBACL,OAAA,EAAQ,SAAA;AAAA,oBACR,OAAA,EAAS,OAAA;AAAA,oBACT,QAAA,EAAU,OAAA;AAAA,oBAEV,QAAA,EAAA;AAAA,sCAAAD,GAAAA,CAAC,SAAA,EAAA,EAAU,SAAA,EAAU,QAAA,EAAS,CAAA;AAAA,sBAC7B;AAAA;AAAA;AAAA,iBACH;AAAA,gCAEFC,IAAAA,CAAC,MAAA,EAAA,EAAO,IAAA,EAAK,QAAA,EAAS,UAAU,OAAA,EAC9B,QAAA,EAAA;AAAA,kCAAAD,GAAAA,CAAC,MAAA,EAAA,EAAO,SAAA,EAAU,QAAA,EAAS,CAAA;AAAA,kBAC1B;AAAA,iBAAA,EACH;AAAA,eAAA,EACF;AAAA;AAAA;AAAA;AACF;AAAA;AAAA,GAEJ;AAEJ;AAcO,SAAS,gBAAA,CAAiB;AAAA,EAC/B,KAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAA;AAAA,EACA,cAAA;AAAA,EACA;AACF,CAAA,EAA0B;AACxB,EAAA,uBACEC,IAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,EAAA;AAAA,QACT,4DAAA;AAAA,QACA;AAAA,OACF;AAAA,MAEC,QAAA,EAAA;AAAA,QAAA,KAAA,oBACCD,GAAAA;AAAA,UAACM,MAAAA;AAAA,UAAA;AAAA,YACC,OAAA;AAAA,YACA,SAAA,EAAW,EAAA;AAAA,cACT,wCAAA;AAAA,cACA;AAAA,aACF;AAAA,YAEC,QAAA,EAAA;AAAA;AAAA,SACH;AAAA,wBAEFN,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,kBAAkB,QAAA,EAAS;AAAA;AAAA;AAAA,GAC5C;AAEJ;AC5HA,IAAM,WAAA,GACJ,8KAAA;AAEK,SAAS,aAAA,CAAc;AAAA,EAC5B,KAAA,GAAQ,oBAAA;AAAA,EACR,WAAA;AAAA,EACA,IAAA;AAAA,EACA,YAAA;AAAA,EACA,OAAA;AAAA,EACA,eAAA;AAAA,EACA,WAAA,GAAc,iCAAA;AAAA,EACd,YAAA,GAAe,cAAA;AAAA,EACf,OAAA,GAAU,SAAA;AAAA,EACV;AACF,CAAA,EAAuB;AACrB,EAAA,uBACEA,GAAAA,CAAC,gBAAA,EAAA,EAAiB,KAAA,EAAc,OAAA,EAAkB,WAChD,QAAA,kBAAAC,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,YAAA,EACZ,QAAA,EAAA;AAAA,IAAA,WAAA,IAAe,WAAA,CAAY,MAAA,GAAS,CAAA,oBACnCA,IAAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,YAAA,EAAW,2BAAA;AAAA,QACX,OAAO,IAAA,IAAA,IAAA,GAAA,IAAA,GAAQ,EAAA;AAAA,QACf,QAAA,EAAU,CAAC,CAAA,KAAM,YAAA,IAAA,IAAA,GAAA,MAAA,GAAA,YAAA,CAAe,EAAE,MAAA,CAAO,KAAA,CAAA;AAAA,QACzC,SAAA,EAAW,EAAA,CAAG,WAAA,EAAa,MAAM,CAAA;AAAA,QAEhC,QAAA,EAAA;AAAA,UAAA,YAAA,KAAiB,wBAAQD,GAAAA,CAAC,QAAA,EAAA,EAAO,KAAA,EAAM,IAAI,QAAA,EAAA,YAAA,EAAa,CAAA;AAAA,UACxD,WAAA,CAAY,GAAA,CAAI,CAAC,CAAA,qBAChBA,GAAAA,CAAC,QAAA,EAAA,EAAqB,KAAA,EAAO,CAAA,CAAE,KAAA,EAC5B,QAAA,EAAA,CAAA,CAAE,KAAA,EAAA,EADQ,CAAA,CAAE,KAEf,CACD;AAAA;AAAA;AAAA,KACH;AAAA,oBAEFA,GAAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,EAAA,EAAI,OAAA;AAAA,QACJ,WAAA;AAAA,QACA,KAAA,EAAO,OAAA;AAAA,QACP,UAAU,CAAC,CAAA,KAAM,eAAA,CAAgB,CAAA,CAAE,OAAO,KAAK;AAAA;AAAA;AACjD,GAAA,EACF,CAAA,EACF,CAAA;AAEJ;AC1BA,IAAM2B,YAAAA,GACF,8KAAA;AAGJ,SAAS,IAAI,IAAA,EAAoB;AAC7B,EAAA,MAAM,CAAA,GAAI,KAAK,WAAA,EAAY;AAC3B,EAAA,MAAM,CAAA,GAAI,OAAO,IAAA,CAAK,QAAA,KAAa,CAAC,CAAA,CAAE,QAAA,CAAS,CAAA,EAAG,GAAG,CAAA;AACrD,EAAA,MAAM,CAAA,GAAI,OAAO,IAAA,CAAK,OAAA,EAAS,CAAA,CAAE,QAAA,CAAS,GAAG,GAAG,CAAA;AAChD,EAAA,OAAO,CAAA,EAAG,CAAC,CAAA,CAAA,EAAI,CAAC,IAAI,CAAC,CAAA,CAAA;AACzB;AAGA,SAAS,QAAQ,CAAA,EAAiB;AAC9B,EAAA,MAAM,CAAA,uBAAQ,IAAA,EAAK;AACnB,EAAA,CAAA,CAAE,OAAA,CAAQ,CAAA,CAAE,OAAA,EAAQ,GAAI,CAAC,CAAA;AACzB,EAAA,OAAO,CAAA;AACX;AAGA,SAAS,UAAU,CAAA,EAAiB;AAChC,EAAA,MAAM,CAAA,uBAAQ,IAAA,EAAK;AACnB,EAAA,CAAA,CAAE,QAAA,CAAS,CAAA,CAAE,QAAA,EAAS,GAAI,CAAC,CAAA;AAC3B,EAAA,OAAO,CAAA;AACX;AAEA,IAAM,eAAA,GAAqC;AAAA,EACvC,EAAE,KAAA,EAAO,cAAA,EAAM,QAAA,EAAU,MAAM,CAAC,GAAA,iBAAI,IAAI,IAAA,EAAM,GAAG,GAAA,iBAAI,IAAI,IAAA,EAAM,CAAC,CAAA,EAAE;AAAA,EAClE,EAAE,KAAA,EAAO,sBAAA,EAAS,QAAA,EAAU,MAAM,CAAC,GAAA,CAAI,OAAA,CAAQ,CAAC,CAAC,GAAG,GAAA,iBAAI,IAAI,IAAA,EAAM,CAAC,CAAA,EAAE;AAAA,EACrE,EAAE,KAAA,EAAO,uBAAA,EAAU,QAAA,EAAU,MAAM,CAAC,GAAA,CAAI,OAAA,CAAQ,EAAE,CAAC,GAAG,GAAA,iBAAI,IAAI,IAAA,EAAM,CAAC,CAAA,EAAE;AAAA,EACvE,EAAE,KAAA,EAAO,4BAAA,EAAU,QAAA,EAAU,MAAM,CAAC,GAAA,CAAI,SAAA,CAAU,CAAC,CAAC,GAAG,GAAA,iBAAI,IAAI,IAAA,EAAM,CAAC,CAAA;AAC1E,CAAA;AAEO,SAAS,eAAA,CAAgB;AAAA,EAC5B,KAAA,GAAQ,cAAA;AAAA,EACR,WAAA;AAAA,EACA,IAAA;AAAA,EACA,YAAA;AAAA,EACA,YAAA,GAAe,cAAA;AAAA,EACf,SAAA;AAAA,EACA,OAAA;AAAA,EACA,iBAAA;AAAA,EACA,eAAA;AAAA,EACA,OAAA;AAAA,EACA,gBAAA,GAAmB,mDAAA;AAAA,EACnB,cAAA,GAAiB,mDAAA;AAAA,EACjB;AACJ,CAAA,EAAyB;AACrB,EAAA,MAAM,UAAA,GACF,YAAY,IAAA,GAAO,eAAA,GAAkB,MAAM,OAAA,CAAQ,OAAO,CAAA,GAAI,OAAA,GAAU,EAAC;AAE7E,EAAA,uBACI3B,IAAC,gBAAA,EAAA,EAAiB,KAAA,EAAc,WAC5B,QAAA,kBAAAC,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,mCAAA,EACV,QAAA,EAAA;AAAA,IAAA,WAAA,IAAe,WAAA,CAAY,MAAA,GAAS,CAAA,oBACjCA,IAAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACG,YAAA,EAAW,2BAAA;AAAA,QACX,OAAO,IAAA,IAAA,IAAA,GAAA,IAAA,GAAQ,EAAA;AAAA,QACf,QAAA,EAAU,CAAC,CAAA,KAAM,YAAA,IAAA,IAAA,GAAA,MAAA,GAAA,YAAA,CAAe,EAAE,MAAA,CAAO,KAAA,CAAA;AAAA,QACzC,SAAA,EAAW,EAAA,CAAG0B,YAAAA,EAAa,MAAM,CAAA;AAAA,QAEhC,QAAA,EAAA;AAAA,UAAA,YAAA,KAAiB,wBACd3B,GAAAA,CAAC,QAAA,EAAA,EAAO,KAAA,EAAM,IAAI,QAAA,EAAA,YAAA,EAAa,CAAA;AAAA,UAElC,WAAA,CAAY,GAAA,CAAI,CAAC,CAAA,qBACdA,GAAAA,CAAC,QAAA,EAAA,EAAqB,KAAA,EAAO,CAAA,CAAE,KAAA,EAC1B,QAAA,EAAA,CAAA,CAAE,KAAA,EAAA,EADM,CAAA,CAAE,KAEf,CACH;AAAA;AAAA;AAAA,KACL;AAAA,oBAGJA,GAAAA;AAAA,MAAC,cAAA;AAAA,MAAA;AAAA,QACG,YAAA,EAAW,oBAAA;AAAA,QACX,OAAO,SAAA,IAAA,IAAA,GAAA,SAAA,GAAa,EAAA;AAAA,QACpB,KAAK,OAAA,IAAW,MAAA;AAAA,QAChB,QAAA,EAAU,iBAAA;AAAA,QACV,WAAA,EAAa,gBAAA;AAAA,QACb,SAAA,EAAU;AAAA;AAAA,KACd;AAAA,oBACAA,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,yBAAwB,QAAA,EAAA,KAAA,EAAG,CAAA;AAAA,oBAC3CA,GAAAA;AAAA,MAAC,cAAA;AAAA,MAAA;AAAA,QACG,YAAA,EAAW,oBAAA;AAAA,QACX,OAAO,OAAA,IAAA,IAAA,GAAA,OAAA,GAAW,EAAA;AAAA,QAClB,KAAK,SAAA,IAAa,MAAA;AAAA,QAClB,QAAA,EAAU,eAAA;AAAA,QACV,WAAA,EAAa,cAAA;AAAA,QACb,SAAA,EAAU;AAAA;AAAA,KACd;AAAA,IAEC,UAAA,CAAW,MAAA,GAAS,CAAA,oBACjBA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,wBAAA,EACV,QAAA,EAAA,UAAA,CAAW,GAAA,CAAI,CAAC,MAAA,qBACbA,GAAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QAEG,IAAA,EAAK,QAAA;AAAA,QACL,OAAA,EAAQ,SAAA;AAAA,QACR,IAAA,EAAK,IAAA;AAAA,QACL,SAAS,MAAM;AACX,UAAA,MAAM,CAAC,KAAA,EAAO,GAAG,CAAA,GAAI,OAAO,QAAA,EAAS;AACrC,UAAA,iBAAA,CAAkB,KAAK,CAAA;AACvB,UAAA,eAAA,CAAgB,GAAG,CAAA;AAAA,QACvB,CAAA;AAAA,QAEC,QAAA,EAAA,MAAA,CAAO;AAAA,OAAA;AAAA,MAVH,MAAA,CAAO;AAAA,KAYnB,CAAA,EACL;AAAA,GAAA,EAER,CAAA,EACJ,CAAA;AAER;ACjKA,SAAS,SAAS,EAAA,EAGgC;AAHhC,EAAA,IAAA,EAAA,GAAA,EAAA,EAChB;AAAA,IAAA;AAAA,GAlBF,GAiBkB,EAAA,EAEb,KAAA,GAAA,SAAA,CAFa,EAAA,EAEb;AAAA,IADH;AAAA,GAAA,CAAA;AAGA,EAAA,uBACEA,GAAAA;AAAA,IAAmB,iBAAA,CAAA,IAAA;AAAA,IAAlB,aAAA,CAAA,cAAA,CAAA;AAAA,MACC,WAAA,EAAU,UAAA;AAAA,MACV,SAAA,EAAW,EAAA;AAAA,QACT,iGAAA;AAAA,QACA,+EAAA;AAAA,QACA,iDAAA;AAAA,QACA,kHAAA;AAAA,QACA,oIAAA;AAAA,QACA;AAAA;AACF,KAAA,EACI,KAAA,CAAA,EAVL;AAAA,MAYC,QAAA,kBAAAA,GAAAA;AAAA,QAAmB,iBAAA,CAAA,SAAA;AAAA,QAAlB;AAAA,UACC,WAAA,EAAU,oBAAA;AAAA,UACV,SAAA,EAAU,+CAAA;AAAA,UAET,QAAA,EAAA,KAAA,CAAM,OAAA,KAAY,eAAA,mBACjBA,IAAC,KAAA,EAAA,EAAM,SAAA,EAAU,UAAA,EAAW,CAAA,mBAE5BA,GAAAA,CAAC4B,KAAAA,EAAA,EAAM,WAAU,UAAA,EAAW;AAAA;AAAA;AAEhC,KAAA;AAAA,GACF;AAEJ;ACOO,SAAS,mBAAA,CAAoB;AAAA,EAClC,KAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAQ,EAAC;AAAA,EACT,QAAA;AAAA,EACA,OAAA,GAAU,KAAA;AAAA,EACV,aAAA,GAAgB,CAAA;AAAA,EAChB,OAAA;AAAA,EACA;AACF,CAAA,EAA6B;AAC3B,EAAA,MAAM,SAAST,KAAAA,EAAM;AACrB,EAAA,MAAM,SAAS,OAAA,IAAA,IAAA,GAAA,OAAA,GAAW,MAAA;AAE1B,EAAA,MAAM,SAAS,CAAC,CAAA,EAAW,OAAA,KACzB,QAAA,CAAS,UAAU,CAAC,GAAG,KAAA,EAAO,CAAC,IAAI,KAAA,CAAM,MAAA,CAAO,CAAC,IAAA,KAAS,IAAA,KAAS,CAAC,CAAC,CAAA;AAEvE,EAAA,IAAI,OAAA,EAAS;AACX,IAAA,uBACEnB,IAAC,gBAAA,EAAA,EAAiB,KAAA,EAAc,SAAS,MAAA,EAAQ,SAAA,EAC/C,QAAA,kBAAAA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,wBACZ,QAAA,EAAA,KAAA,CAAM,IAAA,CAAK,EAAE,MAAA,EAAQ,aAAA,EAAe,EAAE,GAAA,CAAI,CAAC,CAAA,EAAG,CAAA,qBAC7CA,GAAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QAEC,SAAA,EAAU;AAAA,OAAA;AAAA,MADL;AAAA,KAGR,GACH,CAAA,EACF,CAAA;AAAA,EAEJ;AAEA,EAAA,uBACEA,GAAAA,CAAC,gBAAA,EAAA,EAAiB,KAAA,EAAc,SAAS,MAAA,EAAQ,SAAA,EAC/C,QAAA,kBAAAA,GAAAA,CAAC,SAAI,SAAA,EAAU,gCAAA,EACZ,QAAA,EAAA,OAAA,CAAQ,GAAA,CAAI,CAAC,GAAA,KAAQ;AACpB,IAAA,MAAM,EAAA,GAAK,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,IAAI,KAAK,CAAA,CAAA;AACjC,IAAA,uBACEC,IAAAA;AAAA,MAACK,MAAAA;AAAA,MAAA;AAAA,QAEC,OAAA,EAAS,EAAA;AAAA,QACT,SAAA,EAAW,EAAA;AAAA,UACT,uCAAA;AAAA,UACA,IAAI,QAAA,IAAY;AAAA,SAClB;AAAA,QAEA,QAAA,EAAA;AAAA,0BAAAN,GAAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cACC,EAAA;AAAA,cACA,OAAA,EAAS,KAAA,CAAM,QAAA,CAAS,GAAA,CAAI,KAAK,CAAA;AAAA,cACjC,UAAU,GAAA,CAAI,QAAA;AAAA,cACd,iBAAiB,CAAC,OAAA,KAAY,OAAO,GAAA,CAAI,KAAA,EAAO,YAAY,IAAI;AAAA;AAAA,WAClE;AAAA,UACC,GAAA,CAAI;AAAA;AAAA,OAAA;AAAA,MAbA,GAAA,CAAI;AAAA,KAcX;AAAA,EAEJ,CAAC,GACH,CAAA,EACF,CAAA;AAEJ;ACpBO,SAAS,iBAAA,CAAkB,EAAE,KAAA,EAAO,SAAA,EAAU,EAA2B;AAC9E,EAAA,MAAM,SAASmB,KAAAA,EAAM;AAErB,EAAA,uBACEnB,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,EAAA,CAAG,qBAAA,EAAuB,SAAS,CAAA,EAChD,QAAA,EAAA,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,EAAM,KAAA,KAAU;AAhGlC,IAAA,IAAA,EAAA;AAiGQ,IAAA,MAAM,WAAU,EAAA,GAAA,IAAA,CAAK,OAAA,KAAL,YAAgB,CAAA,EAAG,MAAM,IAAI,KAAK,CAAA,CAAA;AAElD,IAAA,IAAI,IAAA,CAAK,SAAS,UAAA,EAAY;AAC5B,MAAA,uBACEA,GAAAA;AAAA,QAAC,mBAAA;AAAA,QAAA;AAAA,UAEC,OAAO,IAAA,CAAK,KAAA;AAAA,UACZ,SAAS,IAAA,CAAK,OAAA;AAAA,UACd,OAAO,IAAA,CAAK,KAAA;AAAA,UACZ,UAAU,IAAA,CAAK,QAAA;AAAA,UACf,SAAS,IAAA,CAAK,OAAA;AAAA,UACd,eAAe,IAAA,CAAK,aAAA;AAAA,UACpB,OAAA;AAAA,UACA,WAAW,IAAA,CAAK;AAAA,SAAA;AAAA,QARX;AAAA,OASP;AAAA,IAEJ;AAEA,IAAA,uBACEA,GAAAA;AAAA,MAAC,gBAAA;AAAA,MAAA;AAAA,QAEC,OAAO,IAAA,CAAK,KAAA;AAAA,QACZ,OAAA;AAAA,QACA,WAAW,IAAA,CAAK,SAAA;AAAA,QAEf,QAAA,EAAA,IAAA,CAAK,0BACJA,GAAAA,CAAC,SAAI,SAAA,EAAU,8CAAA,EAA+C,oBAE9DA,GAAAA;AAAA,UAAC,WAAA;AAAA,UAAA,cAAA,CAAA;AAAA,YACC,EAAA,EAAI,OAAA;AAAA,YACJ,SAAS,IAAA,CAAK,OAAA;AAAA,YACd,OAAO,IAAA,CAAK,KAAA;AAAA,YACZ,UAAU,IAAA,CAAK,QAAA;AAAA,YACf,aAAa,IAAA,CAAK;AAAA,WAAA,EACd,IAAA,CAAK,WAAA;AAAA;AACX,OAAA;AAAA,MAfG;AAAA,KAiBP;AAAA,EAEJ,CAAC,CAAA,EACH,CAAA;AAEJ;ACjHO,SAAS,iBAAA,CAAkB;AAAA,EAChC,OAAA;AAAA,EACA,OAAA;AAAA,EACA;AACF,CAAA,EAA2B;AACzB,EAAA,uBACEC,IAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,EAAA;AAAA,QACT,oEAAA;AAAA,QACA;AAAA,OACF;AAAA,MAEA,QAAA,EAAA;AAAA,wBAAAD,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,+BAAA,EAAiC,QAAA,EAAA,OAAA,EAAQ,CAAA;AAAA,QACvD,2BACCA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,qCAAqC,QAAA,EAAA,OAAA,EAAQ;AAAA;AAAA;AAAA,GAEhE;AAEJ;ACGA,SAAS,UAAA,CACP,SACA,UAAA,EACyB;AACzB,EAAA,MAAM,QAAiC,EAAC;AACxC,EAAA,MAAM6B,OAAAA,GAAS,CAAA;AACf,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,IAAK,UAAA,EAAY,CAAA,EAAA,EAAK;AACpC,IAAA,IACE,CAAA,KAAM,KACN,CAAA,KAAM,UAAA,IACL,KAAK,OAAA,GAAUA,OAAAA,IAAU,CAAA,IAAK,OAAA,GAAUA,OAAAA,EACzC;AACA,MAAA,KAAA,CAAM,KAAK,CAAC,CAAA;AAAA,IACd,WAAW,KAAA,CAAM,KAAA,CAAM,MAAA,GAAS,CAAC,MAAM,UAAA,EAAY;AACjD,MAAA,KAAA,CAAM,KAAK,UAAU,CAAA;AAAA,IACvB;AAAA,EACF;AACA,EAAA,OAAO,KAAA;AACT;AAEA,IAAMF,YAAAA,GACJ,qKAAA;AAEK,SAAS,eAAA,CAAgB;AAAA,EAC9B,IAAA;AAAA,EACA,QAAA;AAAA,EACA,KAAA;AAAA,EACA,YAAA;AAAA,EACA,gBAAA;AAAA,EACA,eAAA,GAAkB,CAAC,EAAA,EAAI,EAAA,EAAI,IAAI,GAAG,CAAA;AAAA,EAClC,QAAA,GAAW,IAAA;AAAA,EACX;AACF,CAAA,EAAyB;AACvB,EAAA,MAAM,UAAA,GAAa,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,IAAA,CAAK,KAAA,GAAQ,QAAQ,CAAC,CAAA;AAC1D,EAAA,MAAM,OAAA,GAAU,KAAK,GAAA,CAAI,IAAA,CAAK,IAAI,CAAA,EAAG,IAAI,GAAG,UAAU,CAAA;AACtD,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAIxB,SAAS,EAAE,CAAA;AAEnC,EAAA,MAAM,IAAA,GAAO,CAAC,CAAA,KAAc;AAC1B,IAAA,MAAM,IAAA,GAAO,KAAK,GAAA,CAAI,IAAA,CAAK,IAAI,CAAA,EAAG,CAAC,GAAG,UAAU,CAAA;AAChD,IAAA,IAAI,IAAA,KAAS,OAAA,EAAS,YAAA,CAAa,IAAI,CAAA;AAAA,EACzC,CAAA;AAEA,EAAA,MAAM,aAAa,MAAM;AACvB,IAAA,MAAM,CAAA,GAAI,OAAO,IAAI,CAAA;AACrB,IAAA,IAAI,MAAA,CAAO,QAAA,CAAS,CAAC,CAAA,IAAK,KAAK,CAAA,EAAG;AAChC,MAAA,IAAA,CAAK,IAAA,CAAK,KAAA,CAAM,CAAC,CAAC,CAAA;AAClB,MAAA,OAAA,CAAQ,EAAE,CAAA;AAAA,IACZ;AAAA,EACF,CAAA;AAEA,EAAA,MAAM,KAAA,GAAQ,UAAA,CAAW,OAAA,EAAS,UAAU,CAAA;AAE5C,EAAA,uBACEF,IAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,EAAA;AAAA,QACT,yDAAA;AAAA,QACA;AAAA,OACF;AAAA,MAGC,QAAA,EAAA;AAAA,QAAA,gBAAA,oBACCD,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,kEACb,QAAA,kBAAAA,GAAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,KAAA,EAAO,QAAA;AAAA,YACP,QAAA,EAAU,CAAC,CAAA,KAAM,gBAAA,CAAiB,OAAO,CAAA,CAAE,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,YACxD,SAAA,EAAW2B,YAAAA;AAAA,YACX,YAAA,EAAW,8CAAA;AAAA,YAEV,QAAA,EAAA,eAAA,CAAgB,IAAI,CAAC,GAAA,qBACpB1B,IAAAA,CAAC,QAAA,EAAA,EAAiB,OAAO,GAAA,EACtB,QAAA,EAAA;AAAA,cAAA,GAAA;AAAA,cAAI;AAAA,aAAA,EAAA,EADM,GAEb,CACD;AAAA;AAAA,SACH,EACF,CAAA;AAAA,wBAIFA,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,mCAAA,EACb,QAAA,EAAA;AAAA,0BAAAD,GAAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACC,OAAA,EAAQ,SAAA;AAAA,cACR,IAAA,EAAK,MAAA;AAAA,cACL,OAAA,EAAS,MAAM,IAAA,CAAK,CAAC,CAAA;AAAA,cACrB,UAAU,OAAA,IAAW,CAAA;AAAA,cACrB,YAAA,EAAW,2BAAA;AAAA,cAEX,QAAA,kBAAAA,GAAAA,CAAC,YAAA,EAAA,EAAa,SAAA,EAAU,QAAA,EAAS;AAAA;AAAA,WACnC;AAAA,0BACAA,GAAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACC,OAAA,EAAQ,SAAA;AAAA,cACR,IAAA,EAAK,MAAA;AAAA,cACL,OAAA,EAAS,MAAM,IAAA,CAAK,OAAA,GAAU,CAAC,CAAA;AAAA,cAC/B,UAAU,OAAA,IAAW,CAAA;AAAA,cACrB,YAAA,EAAW,iCAAA;AAAA,cAEX,QAAA,kBAAAA,GAAAA,CAAC8B,WAAAA,EAAA,EAAY,WAAU,QAAA,EAAS;AAAA;AAAA,WAClC;AAAA,UAEC,KAAA,CAAM,GAAA;AAAA,YAAI,CAAC,CAAA,EAAG,CAAA,KACb,CAAA,KAAM,6BACJ9B,GAAAA;AAAA,cAAC,MAAA;AAAA,cAAA;AAAA,gBAEC,SAAA,EAAU,sCAAA;AAAA,gBACX,QAAA,EAAA;AAAA,eAAA;AAAA,cAFM,KAAK,CAAC,CAAA;AAAA,gCAMbA,GAAAA;AAAA,cAAC,MAAA;AAAA,cAAA;AAAA,gBAEC,OAAA,EAAS,CAAA,KAAM,OAAA,GAAU,SAAA,GAAY,SAAA;AAAA,gBACrC,IAAA,EAAK,MAAA;AAAA,gBACL,OAAA,EAAS,MAAM,IAAA,CAAK,CAAC,CAAA;AAAA,gBACrB,cAAA,EAAc,CAAA,KAAM,OAAA,GAAU,MAAA,GAAS,MAAA;AAAA,gBAEtC,QAAA,EAAA;AAAA,eAAA;AAAA,cANI;AAAA;AAOP,WAEJ;AAAA,0BAEAA,GAAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACC,OAAA,EAAQ,SAAA;AAAA,cACR,IAAA,EAAK,MAAA;AAAA,cACL,OAAA,EAAS,MAAM,IAAA,CAAK,OAAA,GAAU,CAAC,CAAA;AAAA,cAC/B,UAAU,OAAA,IAAW,UAAA;AAAA,cACrB,YAAA,EAAW,iCAAA;AAAA,cAEX,QAAA,kBAAAA,GAAAA,CAACwB,YAAAA,EAAA,EAAa,WAAU,QAAA,EAAS;AAAA;AAAA,WACnC;AAAA,0BACAxB,GAAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACC,OAAA,EAAQ,SAAA;AAAA,cACR,IAAA,EAAK,MAAA;AAAA,cACL,OAAA,EAAS,MAAM,IAAA,CAAK,UAAU,CAAA;AAAA,cAC9B,UAAU,OAAA,IAAW,UAAA;AAAA,cACrB,YAAA,EAAW,uCAAA;AAAA,cAEX,QAAA,kBAAAA,GAAAA,CAAC,aAAA,EAAA,EAAc,SAAA,EAAU,QAAA,EAAS;AAAA;AAAA,WACpC;AAAA,UAEC,QAAA,oBACCC,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,8DAAA,EACb,QAAA,EAAA;AAAA,4BAAAD,GAAAA;AAAA,cAAC,KAAA;AAAA,cAAA;AAAA,gBACC,IAAA,EAAK,QAAA;AAAA,gBACL,GAAA,EAAK,CAAA;AAAA,gBACL,GAAA,EAAK,UAAA;AAAA,gBACL,KAAA,EAAO,IAAA;AAAA,gBACP,UAAU,CAAC,CAAA,KAAM,OAAA,CAAQ,CAAA,CAAE,OAAO,KAAK,CAAA;AAAA,gBACvC,SAAA,EAAW,CAAC,CAAA,KAAM;AAChB,kBAAA,IAAI,CAAA,CAAE,QAAQ,OAAA,EAAS;AACrB,oBAAA,CAAA,CAAE,cAAA,EAAe;AACjB,oBAAA,UAAA,EAAW;AAAA,kBACb;AAAA,gBACF,CAAA;AAAA,gBACA,WAAA,EAAa,OAAO,OAAO,CAAA;AAAA,gBAC3B,SAAA,EAAU,sBAAA;AAAA,gBACV,YAAA,EAAW;AAAA;AAAA,aACb;AAAA,4BACAA,IAAC,MAAA,EAAA,EAAO,IAAA,EAAK,UAAS,OAAA,EAAQ,SAAA,EAAU,OAAA,EAAS,UAAA,EAAY,QAAA,EAAA,cAAA,EAE7D;AAAA,WAAA,EACF;AAAA,SAAA,EAEJ;AAAA;AAAA;AAAA,GACF;AAEJ;AChFA,SAAS,KAAK,KAAA,EAA4C;AACxD,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,EAAU,OAAO,KAAA;AACtC,EAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,IAAA,MAAM,CAAA,GAAI,WAAW,KAAK,CAAA;AAC1B,IAAA,OAAO,MAAA,CAAO,QAAA,CAAS,CAAC,CAAA,GAAI,CAAA,GAAI,CAAA;AAAA,EAClC;AACA,EAAA,OAAO,CAAA;AACT;AA2EO,SAAS,kBAAkB,YAAA,EAA2C;AAC3E,EAAA,OAAO,MAAA,CAAO,KAAK,YAAY,CAAA,CAAE,OAAO,CAAC,GAAA,KAAQ,YAAA,CAAa,GAAG,CAAC,CAAA;AACpE;AAGA,IAAM+B,WAAAA,GAAa,EAAA;AACnB,IAAM,aAAA,GAAgB,EAAA;AAEtB,IAAM,UAAA,GAAa;AAAA,EACjB,IAAA,EAAM,WAAA;AAAA,EACN,MAAA,EAAQ,aAAA;AAAA,EACR,KAAA,EAAO;AACT,CAAA;AAGA,SAAS,QAAA,CAAS,EAAE,KAAA,EAAM,EAA+B;AACvD,EAAA,IAAI,UAAU,KAAA,EAAO,uBAAO/B,GAAAA,CAAC,SAAA,EAAA,EAAU,WAAU,UAAA,EAAW,CAAA;AAC5D,EAAA,IAAI,KAAA,KAAU,QAAQ,uBAAOA,IAACW,WAAAA,EAAA,EAAY,WAAU,UAAA,EAAW,CAAA;AAC/D,EAAA,uBAAOX,GAAAA,CAAC,cAAA,EAAA,EAAe,SAAA,EAAU,qBAAA,EAAsB,CAAA;AACzD;AAEO,SAAS,UAAA,CAAkB;AAAA,EAChC,OAAA;AAAA,EACA,IAAA;AAAA,EACA,kBAAA,GAAqB,KAAA;AAAA,EACrB,YAAA,EAAc,mBAAA;AAAA,EACd,oBAAA,EAAsB,kBAAA;AAAA,EACtB,QAAA;AAAA,EACA,OAAA,GAAU,KAAA;AAAA,EACV,YAAA,GAAe,oDAAA;AAAA,EACf,SAAA,GAAY,GAAA;AAAA,EACZ,IAAA;AAAA,EACA,YAAA;AAAA,EACA,UAAA;AAAA,EACA,OAAA;AAAA,EACA,SAAA;AAAA,EACA,MAAA;AAAA,EACA,OAAA;AAAA,EACA,cAAA;AAAA,EACA,gBAAA;AAAA,EACA,KAAA;AAAA,EACA,IAAA;AAAA,EACA,QAAA;AAAA,EACA,YAAA;AAAA,EACA,gBAAA;AAAA,EACA,eAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF,CAAA,EAA2B;AACzB,EAAA,MAAM,CAAC,iBAAA,EAAmB,oBAAoB,CAAA,GAC5CG,QAAAA,CAA4B,EAAE,CAAA;AAChC,EAAA,MAAM,eAAe,mBAAA,IAAA,IAAA,GAAA,mBAAA,GAAuB,iBAAA;AAC5C,EAAA,MAAM,uBAAuB,kBAAA,IAAA,IAAA,GAAA,kBAAA,GAAsB,oBAAA;AAEnD,EAAA,MAAM,UAAA,GAAa,OAAA,IAAW,IAAA,IAAQ,cAAA,IAAkB,IAAA;AACxD,EAAA,MAAM,aAAA,GACJ,UAAU,MAAA,IACV,IAAA,KAAS,UACT,QAAA,KAAa,MAAA,IACb,CAAC,CAAC,YAAA;AAOJ,EAAA,MAAM,cAAc,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAA,KAAM,EAAE,QAAQ,CAAA;AAClD,EAAA,MAAM,cAAc,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAA,KAAM,EAAE,KAAK,CAAA;AAG/C,EAAA,MAAM,YAAA,GAAeE,QAAqC,MAAM;AAC9D,IAAA,MAAM,MAAA,GAAsC,OAAA,CAAQ,GAAA,CAAI,CAAC,KAAK,CAAA,KAAG;AA5RrE,MAAA,IAAA,EAAA;AA4RyE,MAAA,OAAA;AAAA,QACnE,EAAA,EAAA,CACE,EAAA,GAAA,GAAA,CAAI,GAAA,KAAJ,IAAA,GAAA,EAAA,GACC,GAAA,CAAI,SAAA,IAAa,IAAA,GAAO,MAAA,CAAO,GAAA,CAAI,SAAS,CAAA,GAAI,CAAA,IAAA,EAAO,CAAC,CAAA,CAAA;AAAA,QAC3D,MAAA,EAAQ,MAAM,GAAA,CAAI,KAAA;AAAA,QAClB,IAAA,EAAM,CAAC,EAAE,GAAA,EAAI,KAAM;AAjSzB,UAAA,IAAAG,GAAAA;AAkSQ,UAAA,MAAM,KAAA,GACJ,IAAI,SAAA,IAAa,IAAA,GAAO,IAAI,QAAA,CAAS,GAAA,CAAI,SAAS,CAAA,GAAI,MAAA;AACxD,UAAA,IAAI,GAAA,CAAI,QAAQ,OAAO,GAAA,CAAI,OAAO,KAAA,EAAO,GAAA,CAAI,QAAA,EAAU,GAAA,CAAI,KAAK,CAAA;AAChE,UAAA,MAAM,YAAY,GAAA,CAAI,IAAA,GAClB,aAAa,GAAA,CAAI,IAAA,EAAM,KAAK,CAAA,GAC3B,KAAA;AACL,UAAA,IAAI,SAAA,KAAc,EAAA,IAAM,SAAA,IAAa,IAAA,EAAM;AACzC,YAAA,OAAA,CAAOA,GAAAA,GAAA,GAAA,CAAI,SAAA,KAAJ,IAAA,GAAAA,GAAAA,GAAiB,SAAA;AAAA,UAC1B;AACA,UAAA,OAAO,SAAA;AAAA,QACT,CAAA;AAAA,QACA,MAAM,OAAO,GAAA,CAAI,KAAA,KAAU,QAAA,GAAW,IAAI,KAAA,GAAQ,MAAA;AAAA,QAClD,aAAA,EAAe,KAAA;AAAA,QACf,IAAA,EAAM;AAAA,UACJ,OAAO,GAAA,CAAI,KAAA;AAAA,UACX,UAAU,GAAA,CAAI,QAAA;AAAA,UACd,OAAO,GAAA,CAAI,KAAA;AAAA,UACX,UAAU,GAAA,CAAI,QAAA;AAAA,UACd,OAAO,GAAA,CAAI,KAAA;AAAA,UACX,WAAW,GAAA,CAAI,SAAA;AAAA,UACf,iBAAiB,GAAA,CAAI;AAAA;AACvB,OACF;AAAA,IAAA,CAAE,CAAA;AAEF,IAAA,IAAI,CAAC,oBAAoB,OAAO,MAAA;AAGhC,IAAA,MAAM,eAAe,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,UAAU,MAAM,CAAA;AAE3D,IAAA,MAAM,eAAA,GAA6C;AAAA,MACjD,EAAA,EAAI,YAAA;AAAA,MACJ,IAAA,EAAM,EAAA;AAAA,MACN,QAAQ,CAAC,EAAE,KAAA,EAAAwB,MAAAA,uBACThC,GAAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UACC,OAAA,EACEgC,OAAM,wBAAA,EAAyB,GAC3B,OACAA,MAAAA,CAAM,yBAAA,KACJ,eAAA,GACA,KAAA;AAAA,UAER,iBAAiB,CAAC,KAAA,KAAUA,OAAM,yBAAA,CAA0B,CAAC,CAAC,KAAK,CAAA;AAAA,UACnE,YAAA,EAAW;AAAA;AAAA,OACb;AAAA,MAEF,IAAA,EAAM,CAAC,EAAE,GAAA,uBACPhC,GAAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UACC,OAAA,EAAS,IAAI,aAAA,EAAc;AAAA,UAC3B,iBAAiB,CAAC,KAAA,KAAU,IAAI,cAAA,CAAe,CAAC,CAAC,KAAK,CAAA;AAAA,UACtD,YAAA,EAAW,qBAAA;AAAA,UACX,OAAA,EAAS,CAAC,CAAA,KAAM,CAAA,CAAE,eAAA;AAAgB;AAAA,OACpC;AAAA,MAEF,aAAA,EAAe,KAAA;AAAA,MACf,IAAA,EAAM;AAAA,QACJ,KAAA,EAAO,QAAA;AAAA,QACP,KAAA,EAAO,EAAA;AAAA,QACP,KAAA,EAAO,eAAe,MAAA,GAAS;AAAA;AACjC,KACF;AACA,IAAA,OAAO,CAAC,eAAA,EAAiB,GAAG,MAAM,CAAA;AAAA,EACpC,CAAA,EAAG,CAAC,OAAA,EAAS,kBAAA,EAAoB,SAAS,CAAC,CAAA;AAG3C,EAAA,MAAM,SAAA,GAAYK,QAAQ,MAAM;AAC9B,IAAA,MAAM,MAAyD,EAAC;AAChE,IAAA,IAAI,OAAA,GAAU,CAAA;AACd,IAAA,KAAA,MAAW,OAAO,YAAA,EAAc;AAC9B,MAAA,MAAM,OAAO,GAAA,CAAI,IAAA;AACjB,MAAA,IAAA,CAAI,IAAA,IAAA,IAAA,GAAA,MAAA,GAAA,IAAA,CAAM,WAAU,MAAA,EAAQ;AAC1B,QAAA,GAAA,CAAI,GAAA,CAAI,EAAY,CAAA,GAAI,EAAE,MAAM,OAAA,EAAQ;AACxC,QAAA,OAAA,IAAW,IAAA,CAAK,KAAK,KAAK,CAAA;AAAA,MAC5B;AAAA,IACF;AACA,IAAA,IAAI,QAAA,GAAW,CAAA;AACf,IAAA,KAAA,IAAS,IAAI,YAAA,CAAa,MAAA,GAAS,CAAA,EAAG,CAAA,IAAK,GAAG,CAAA,EAAA,EAAK;AACjD,MAAA,MAAM,GAAA,GAAM,aAAa,CAAC,CAAA;AAC1B,MAAA,MAAM,OAAO,GAAA,CAAI,IAAA;AACjB,MAAA,IAAA,CAAI,IAAA,IAAA,IAAA,GAAA,MAAA,GAAA,IAAA,CAAM,WAAU,OAAA,EAAS;AAC3B,QAAA,GAAA,CAAI,GAAA,CAAI,EAAY,CAAA,GAAI,EAAE,OAAO,QAAA,EAAS;AAC1C,QAAA,QAAA,IAAY,IAAA,CAAK,KAAK,KAAK,CAAA;AAAA,MAC7B;AAAA,IACF;AACA,IAAA,OAAO,GAAA;AAAA,EACT,CAAA,EAAG,CAAC,YAAY,CAAC,CAAA;AAMjB,EAAA,MAAM,QAAQ,aAAA,CAAc;AAAA,IAC1B,IAAA;AAAA,IACA,OAAA,EAAS,YAAA;AAAA,IACT,KAAA,EAAO,EAAE,YAAA,EAAa;AAAA,IACtB,kBAAA;AAAA,IACA,oBAAA;AAAA,IACA,QAAA,EAAU,QAAA,GACN,CAAC,GAAA,EAAY,KAAA,KAAkB,OAAO,QAAA,CAAS,GAAA,EAAK,KAAK,CAAC,CAAA,GAC1D,MAAA;AAAA,IACJ,iBAAiB,eAAA;AAAgB,GAClC,CAAA;AAED,EAAA,MAAM,UAAU,YAAA,CAAa,MAAA;AAG7B,EAAA,MAAM,UAAA,GAAa,CAAC,KAAA,KAAkB;AACpC,IAAA,MAAM,GAAA,GAAA,CAAM,IAAA,IAAA,IAAA,GAAA,MAAA,GAAA,IAAA,CAAM,OAAA,MAAY,KAAA,GAAQ,KAAK,QAAA,GAAW,MAAA;AACtD,IAAA,MAAM,OAAO,GAAA,KAAQ,KAAA,GAAQ,MAAA,GAAS,GAAA,KAAQ,SAAS,MAAA,GAAY,KAAA;AACnE,IAAA,YAAA,IAAA,IAAA,GAAA,MAAA,GAAA,YAAA,CAAe,EAAE,OAAA,EAAS,IAAA,GAAO,KAAA,GAAQ,MAAA,EAAW,UAAU,IAAA,EAAK,CAAA;AAAA,EACrE,CAAA;AAEA,EAAA,MAAM,0BACJJ,IAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,EAAA;AAAA,QACT,mFAAA;AAAA,QACA,CAAC,UAAA,IAAc,CAAC,aAAA,IAAiB;AAAA,OACnC;AAAA,MAEA,QAAA,EAAA;AAAA,wBAAAD,GAAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAU,iBAAA;AAAA,YACV,OACE,OAAA,GACI,EAAE,WAAW,aAAA,GAAgB,OAAA,GAAU+B,aAAW,GAClD,MAAA;AAAA,YAGN,QAAA,kBAAA9B,KAAC,OAAA,EAAA,EAAM,SAAA,EAAW,GAAG,gBAAA,EAAA,CAAmB,WAAA,IAAe,WAAA,KAAgB,aAAa,CAAA,EAClF,QAAA,EAAA;AAAA,8BAAAD,IAAC,OAAA,EAAA,EAAM,SAAA,EAAU,mBAAA,EACd,QAAA,EAAA,KAAA,CAAM,iBAAgB,CAAE,GAAA,CAAI,CAAC,WAAA,qBAC5BA,GAAAA,CAAC,IAAA,EAAA,EACE,sBAAY,OAAA,CAAQ,GAAA,CAAI,CAAC,MAAA,KAAW;AAparD,gBAAA,IAAA,EAAA;AAqakB,gBAAA,MAAM,IAAA,GAAO,MAAA,CAAO,MAAA,CAAO,SAAA,CAAU,IAAA;AAGrC,gBAAA,MAAM,MAAA,GAAS,SAAA,CAAU,MAAA,CAAO,MAAA,CAAO,EAAE,CAAA;AACzC,gBAAA,uBACEA,GAAAA;AAAA,kBAAC,IAAA;AAAA,kBAAA;AAAA,oBAEC,SAAA,EAAW,EAAA;AAAA,sBACT,4EAAA;AAAA,sBACA,UAAA,CAAA,CAAW,EAAA,GAAA,IAAA,IAAA,IAAA,GAAA,MAAA,GAAA,IAAA,CAAM,KAAA,KAAN,IAAA,GAAA,EAAA,GAAe,MAAM,CAAA;AAAA,sBAAA,CAChC,6BAAM,QAAA,KAAY,UAAA;AAAA,sBAClB,MAAA,IAAU,sBAAA;AAAA,sBAAA,CACV,MAAA,IAAA,IAAA,GAAA,MAAA,GAAA,MAAA,CAAQ,UAAS,MAAA,IACf,0CAAA;AAAA,sBAAA,CACF,MAAA,IAAA,IAAA,GAAA,MAAA,GAAA,MAAA,CAAQ,WAAU,MAAA,IAChB,2CAAA;AAAA,sBACF,IAAA,IAAA,IAAA,GAAA,MAAA,GAAA,IAAA,CAAM;AAAA,qBACR;AAAA,oBACA,KAAA,EAAO;AAAA,sBACL,OAAO,IAAA,IAAA,IAAA,GAAA,MAAA,GAAA,IAAA,CAAM,KAAA;AAAA,sBACb,MAAM,MAAA,IAAA,IAAA,GAAA,MAAA,GAAA,MAAA,CAAQ,IAAA;AAAA,sBACd,OAAO,MAAA,IAAA,IAAA,GAAA,MAAA,GAAA,MAAA,CAAQ;AAAA,qBACjB;AAAA,oBACA,WAAA,EAAA,CACE,IAAA,IAAA,IAAA,GAAA,MAAA,GAAA,IAAA,CAAM,QAAA,IAAA,CACF,IAAA,IAAA,IAAA,GAAA,MAAA,GAAA,IAAA,CAAM,OAAA,MAAY,MAAA,CAAO,MAAA,CAAO,EAAA,GAC9B,IAAA,CAAK,QAAA,KAAa,KAAA,GAChB,WAAA,GACA,eACF,MAAA,GACF,MAAA;AAAA,oBAGL,QAAA,EAAA,MAAA,CAAO,aAAA,GAAgB,IAAA,GAAA,CAAO,IAAA,IAAA,IAAA,GAAA,MAAA,GAAA,IAAA,CAAM,4BACnCC,IAAAA;AAAA,sBAAC,QAAA;AAAA,sBAAA;AAAA,wBACC,IAAA,EAAK,QAAA;AAAA,wBACL,OAAA,EAAS,MAAM,UAAA,CAAW,MAAA,CAAO,OAAO,EAAE,CAAA;AAAA,wBAC1C,SAAA,EAAU,oFAAA;AAAA,wBAET,QAAA,EAAA;AAAA,0BAAA,UAAA;AAAA,4BACC,MAAA,CAAO,OAAO,SAAA,CAAU,MAAA;AAAA,4BACxB,OAAO,UAAA;AAAW,2BACpB;AAAA,0CACAD,GAAAA;AAAA,4BAAC,QAAA;AAAA,4BAAA;AAAA,8BACC,QACE,IAAA,IAAA,IAAA,GAAA,MAAA,GAAA,IAAA,CAAM,OAAA,MAAY,OAAO,MAAA,CAAO,EAAA,GAC5B,KAAK,QAAA,GACL;AAAA;AAAA;AAER;AAAA;AAAA,qBACF,GAEA,UAAA;AAAA,sBACE,MAAA,CAAO,OAAO,SAAA,CAAU,MAAA;AAAA,sBACxB,OAAO,UAAA;AAAW;AACpB,mBAAA;AAAA,kBAjDG,MAAA,CAAO;AAAA,iBAmDd;AAAA,cAEJ,CAAC,CAAA,EAAA,EA7DM,WAAA,CAAY,EA8DrB,CACD,CAAA,EACH,CAAA;AAAA,8BACAA,IAAC,OAAA,EAAA,EACE,QAAA,EAAA,OAAA,IAAW,MAAM,WAAA,EAAY,CAAE,KAAK,MAAA,KAAW,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gCAO9CA,IAAC,IAAA,EAAA,EACC,QAAA,kBAAAA,IAAC,IAAA,EAAA,EAAG,OAAA,EAAkB,SAAA,EAAU,MAAA,EAAO,CAAA,EACzC;AAAA,kBAEA,MAAM,WAAA,EAAY,CAAE,KAAK,GAAA,CAAI,CAAC,wBAC5BA,GAAAA;AAAA,gBAAC,IAAA;AAAA,gBAAA;AAAA,kBAEC,YAAA,EAAY,GAAA,CAAI,aAAA,EAAc,GAAI,UAAA,GAAa,MAAA;AAAA,kBAC/C,SACE,UAAA,GAAa,MAAM,UAAA,CAAW,GAAA,CAAI,QAAQ,CAAA,GAAI,MAAA;AAAA,kBAEhD,SAAA,EAAW,EAAA;AAAA,oBACT,sGAAA;AAAA,oBACA,UAAA,IAAc;AAAA,mBAChB;AAAA,kBAEC,QAAA,EAAA,GAAA,CAAI,eAAA,EAAgB,CAAE,GAAA,CAAI,CAAC,IAAA,KAAS;AA5fvD,oBAAA,IAAA,EAAA;AA6foB,oBAAA,MAAM,IAAA,GAAO,IAAA,CAAK,MAAA,CAAO,SAAA,CAAU,IAAA;AAGnC,oBAAA,MAAM,MAAA,GAAS,SAAA,CAAU,IAAA,CAAK,MAAA,CAAO,EAAE,CAAA;AACvC,oBAAA,uBACEA,GAAAA;AAAA,sBAAC,IAAA;AAAA,sBAAA;AAAA,wBAEC,SAAA,EAAW,EAAA;AAAA,0BACT,0BAAA;AAAA,0BACA,UAAA,CAAA,CAAW,EAAA,GAAA,IAAA,IAAA,IAAA,GAAA,MAAA,GAAA,IAAA,CAAM,KAAA,KAAN,IAAA,GAAA,EAAA,GAAe,MAAM,CAAA;AAAA,0BAAA,CAChC,IAAA,IAAA,IAAA,GAAA,MAAA,GAAA,IAAA,CAAM,YAAW,UAAA,GAAa,mBAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BAM9B,MAAA,IACE,iGAAA;AAAA,0BAAA,CACF,MAAA,IAAA,IAAA,GAAA,MAAA,GAAA,MAAA,CAAQ,UAAS,MAAA,IACf,0CAAA;AAAA,0BAAA,CACF,MAAA,IAAA,IAAA,GAAA,MAAA,GAAA,MAAA,CAAQ,WAAU,MAAA,IAChB,2CAAA;AAAA,0BACF,IAAA,IAAA,IAAA,GAAA,MAAA,GAAA,IAAA,CAAM;AAAA,yBACR;AAAA,wBACA,KAAA,EAAO;AAAA,0BACL,UAAU,IAAA,IAAA,IAAA,GAAA,MAAA,GAAA,IAAA,CAAM,KAAA;AAAA,0BAChB,MAAM,MAAA,IAAA,IAAA,GAAA,MAAA,GAAA,MAAA,CAAQ,IAAA;AAAA,0BACd,OAAO,MAAA,IAAA,IAAA,GAAA,MAAA,GAAA,MAAA,CAAQ;AAAA,yBACjB;AAAA,wBAEC,QAAA,EAAA,UAAA;AAAA,0BACC,IAAA,CAAK,OAAO,SAAA,CAAU,IAAA;AAAA,0BACtB,KAAK,UAAA;AAAW;AAClB,uBAAA;AAAA,sBA3BK,IAAA,CAAK;AAAA,qBA4BZ;AAAA,kBAEJ,CAAC;AAAA,iBAAA;AAAA,gBA/CI,GAAA,CAAI;AAAA,eAiDZ,CAAA,EAEL,CAAA;AAAA,cACC,MAAA,oBACCA,GAAAA,CAAC,OAAA,EAAA,EACC,QAAA,kBAAAA,GAAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,kBAAA,EACX,QAAA,EAAA,YAAA,CAAa,GAAA,CAAI,CAAC,GAAA,KAAQ;AAziB3C,gBAAA,IAAA,EAAA;AA0iBkB,gBAAA,MAAM,OAAO,GAAA,CAAI,IAAA;AACjB,gBAAA,MAAM,MAAA,GAAS,SAAA,CAAU,GAAA,CAAI,EAAY,CAAA;AACzC,gBAAA,uBACEA,GAAAA;AAAA,kBAAC,IAAA;AAAA,kBAAA;AAAA,oBAEC,SAAA,EAAW,EAAA;AAAA,sBACT,0BAAA;AAAA,sBACA,UAAA,CAAA,CAAW,EAAA,GAAA,IAAA,IAAA,IAAA,GAAA,MAAA,GAAA,IAAA,CAAM,KAAA,KAAN,IAAA,GAAA,EAAA,GAAe,MAAM,CAAA;AAAA,sBAChC,MAAA,IAAU,qBAAA;AAAA,sBAAA,CACV,MAAA,IAAA,IAAA,GAAA,MAAA,GAAA,MAAA,CAAQ,UAAS,MAAA,IACf,0CAAA;AAAA,sBAAA,CACF,MAAA,IAAA,IAAA,GAAA,MAAA,GAAA,MAAA,CAAQ,WAAU,MAAA,IAChB,2CAAA;AAAA,sBACF,IAAA,IAAA,IAAA,GAAA,MAAA,GAAA,IAAA,CAAM;AAAA,qBACR;AAAA,oBACA,KAAA,EAAO;AAAA,sBACL,UAAU,IAAA,IAAA,IAAA,GAAA,MAAA,GAAA,IAAA,CAAM,KAAA;AAAA,sBAChB,MAAM,MAAA,IAAA,IAAA,GAAA,MAAA,GAAA,MAAA,CAAQ,IAAA;AAAA,sBACd,OAAO,MAAA,IAAA,IAAA,GAAA,MAAA,GAAA,MAAA,CAAQ;AAAA,qBACjB;AAAA,oBAEC,QAAA,EAAA,MAAA,CAAO,IAAI,EAAY;AAAA,mBAAA;AAAA,kBAjBnB,GAAA,CAAI;AAAA,iBAkBX;AAAA,cAEJ,CAAC,GACH,CAAA,EACF;AAAA,aAAA,EAEJ;AAAA;AAAA,SACF;AAAA,QAAA,CAEE,WAAW,KAAA,CAAM,WAAA,GAAc,IAAA,CAAK,MAAA,KAAW,sBAC/CA,GAAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAU,uFAAA;AAAA,YAET,QAAA,EAAA,OAAA,mBACCC,IAAAA,CAAC,MAAA,EAAA,EAAK,WAAU,gCAAA,EACd,QAAA,EAAA;AAAA,8BAAAD,GAAAA,CAACiB,OAAAA,EAAA,EAAQ,SAAA,EAAU,qBAAA,EAAsB,CAAA;AAAA,cAAE;AAAA,aAAA,EAE7C,CAAA,GAEA;AAAA;AAAA;AAEJ;AAAA;AAAA,GAEJ;AAGF,EAAA,IAAI,CAAC,UAAA,IAAc,CAAC,aAAA,EAAe,OAAO,OAAA;AAE1C,EAAA,uBACEhB,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAW,EAAA,CAAG,WAAA,EAAa,SAAS,CAAA,EACtC,QAAA,EAAA;AAAA,IAAA,UAAA,oBACCD,GAAAA;AAAA,MAAC,iBAAA;AAAA,MAAA;AAAA,QACC,OAAA;AAAA,QACA,OAAA,EAAS,cAAA;AAAA,QACT,SAAA,EAAW;AAAA;AAAA,KACb;AAAA,IAED,OAAA;AAAA,IACA,iCACCA,GAAAA;AAAA,MAAC,eAAA;AAAA,MAAA;AAAA,QACC,IAAA;AAAA,QACA,QAAA;AAAA,QACA,KAAA;AAAA,QACA,YAAA;AAAA,QACA,gBAAA;AAAA,QACA,eAAA;AAAA,QACA,QAAA;AAAA,QACA,SAAA,EAAW;AAAA;AAAA;AACb,GAAA,EAEJ,CAAA;AAEJ;AC/lBA,SAAS,OAAO,KAAA,EAAoD;AAClE,EAAA,uBAAOA,GAAAA,CAAiBiC,cAAA,CAAA,IAAA,EAAhB,cAAA,CAAA,EAAqB,WAAA,EAAU,YAAa,KAAA,CAAO,CAAA;AAC7D;AAEA,SAAS,cACP,KAAA,EACA;AACA,EAAA,uBAAOjC,GAAAA,CAAiBiC,cAAA,CAAA,OAAA,EAAhB,cAAA,CAAA,EAAwB,WAAA,EAAU,oBAAqB,KAAA,CAAO,CAAA;AACxE;AAEA,SAAS,YAAY,KAAA,EAAqD;AACxE,EAAA,uBAAOjC,GAAAA,CAAiBiC,cAAA,CAAA,KAAA,EAAhB,cAAA,CAAA,EAAsB,WAAA,EAAU,kBAAmB,KAAA,CAAO,CAAA;AACpE;AAEA,SAAS,cAAc,EAAA,EAG4B;AAH5B,EAAA,IAAA,EAAA,GAAA,EAAA,EACrB;AAAA,IAAA;AAAA,GApCF,GAmCuB,EAAA,EAElB,KAAA,GAAA,SAAA,CAFkB,EAAA,EAElB;AAAA,IADH;AAAA,GAAA,CAAA;AAGA,EAAA,uBACEjC,GAAAA;AAAA,IAAiBiC,cAAA,CAAA,OAAA;AAAA,IAAhB,cAAA,CAAA;AAAA,MACC,WAAA,EAAU,gBAAA;AAAA,MACV,SAAA,EAAW,EAAA;AAAA,QACT,wJAAA;AAAA,QACA;AAAA;AACF,KAAA,EACI,KAAA;AAAA,GACN;AAEJ;AAEA,SAAS,cAAc,EAAA,EAKsD;AALtD,EAAA,IAAA,EAAA,GAAA,EAAA,EACrB;AAAA,IAAA,SAAA;AAAA,IACA,QAAA;AAAA,IACA,SAAA,GAAY;AAAA,GAtDd,GAmDuB,EAAA,EAIlB,KAAA,GAAA,SAAA,CAJkB,EAAA,EAIlB;AAAA,IAHH,WAAA;AAAA,IACA,UAAA;AAAA,IACA;AAAA,GAAA,CAAA;AAGA,EAAA,uBACEhC,IAAAA,CAAiBgC,cAAA,CAAA,MAAA,EAAhB,EAAuB,aAAU,eAAA,EAChC,QAAA,EAAA;AAAA,oBAAAjC,IAAC,aAAA,EAAA,EAAc,CAAA;AAAA,oBACfC,IAAAA;AAAA,MAAiBgC,cAAA,CAAA,OAAA;AAAA,MAAhB,aAAA,CAAA,cAAA,CAAA;AAAA,QACC,WAAA,EAAU,gBAAA;AAAA,QACV,SAAA,EAAW,EAAA;AAAA,UACT,uVAAA;AAAA,UACA;AAAA;AACF,OAAA,EACI,KAAA,CAAA,EANL;AAAA,QAQE,QAAA,EAAA;AAAA,UAAA,QAAA;AAAA,UACA,6BACChC,IAAAA,CAAiBgC,cAAA,CAAA,KAAA,EAAhB,EAAsB,WAAU,6MAAA,EAC/B,QAAA,EAAA;AAAA,4BAAAjC,GAAAA,CAACkC,KAAAA,EAAA,EAAM,SAAA,EAAU,QAAA,EAAS,CAAA;AAAA,4BAC1BlC,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,WAAU,QAAA,EAAA,cAAA,EAAE;AAAA,WAAA,EAC9B;AAAA;AAAA,OAAA;AAAA;AAEJ,GAAA,EACF,CAAA;AAEJ;AAEA,SAAS,aAAa,EAAA,EAAgD;AAAhD,EAAA,IAAA,EAAA,GAAA,EAAA,EAAE,EAAA,SAAA,EAhFxB,GAgFsB,EAAA,EAAgB,KAAA,GAAA,SAAA,CAAhB,IAAgB,CAAd,WAAA,CAAA,CAAA;AACtB,EAAA,uBACEA,GAAAA;AAAA,IAAC,KAAA;AAAA,IAAA,cAAA,CAAA;AAAA,MACC,WAAA,EAAU,eAAA;AAAA,MACV,SAAA,EAAW,EAAA,CAAG,iCAAA,EAAmC,SAAS;AAAA,KAAA,EACtD,KAAA;AAAA,GACN;AAEJ;AAEA,SAAS,aAAa,EAAA,EAAgD;AAAhD,EAAA,IAAA,EAAA,GAAA,EAAA,EAAE,EAAA,SAAA,EA1FxB,GA0FsB,EAAA,EAAgB,KAAA,GAAA,SAAA,CAAhB,IAAgB,CAAd,WAAA,CAAA,CAAA;AACtB,EAAA,uBACEA,GAAAA;AAAA,IAAC,KAAA;AAAA,IAAA,cAAA,CAAA;AAAA,MACC,WAAA,EAAU,eAAA;AAAA,MACV,SAAA,EAAW,EAAA;AAAA,QACT,wDAAA;AAAA,QACA;AAAA;AACF,KAAA,EACI,KAAA;AAAA,GACN;AAEJ;AAEA,SAAS,YAAY,EAAA,EAG4B;AAH5B,EAAA,IAAA,EAAA,GAAA,EAAA,EACnB;AAAA,IAAA;AAAA,GAxGF,GAuGqB,EAAA,EAEhB,KAAA,GAAA,SAAA,CAFgB,EAAA,EAEhB;AAAA,IADH;AAAA,GAAA,CAAA;AAGA,EAAA,uBACEA,GAAAA;AAAA,IAAiBiC,cAAA,CAAA,KAAA;AAAA,IAAhB,cAAA,CAAA;AAAA,MACC,WAAA,EAAU,cAAA;AAAA,MACV,SAAA,EAAW,EAAA,CAAG,uBAAA,EAAyB,SAAS;AAAA,KAAA,EAC5C,KAAA;AAAA,GACN;AAEJ;AAEA,SAAS,kBAAkB,EAAA,EAG4B;AAH5B,EAAA,IAAA,EAAA,GAAA,EAAA,EACzB;AAAA,IAAA;AAAA,GArHF,GAoH2B,EAAA,EAEtB,KAAA,GAAA,SAAA,CAFsB,EAAA,EAEtB;AAAA,IADH;AAAA,GAAA,CAAA;AAGA,EAAA,uBACEjC,GAAAA;AAAA,IAAiBiC,cAAA,CAAA,WAAA;AAAA,IAAhB,cAAA,CAAA;AAAA,MACC,WAAA,EAAU,oBAAA;AAAA,MACV,SAAA,EAAW,EAAA,CAAG,+BAAA,EAAiC,SAAS;AAAA,KAAA,EACpD,KAAA;AAAA,GACN;AAEJ;AC7DA,IAAM,IAAA,GAAuC;AAAA,EAC3C,EAAA,EAAI,UAAA;AAAA,EACJ,EAAA,EAAI,UAAA;AAAA,EACJ,EAAA,EAAI,UAAA;AAAA,EACJ,EAAA,EAAI,WAAA;AAAA,EACJ,GAAA,EAAK,WAAA;AAAA,EACL,IAAA,EAAM;AACR,CAAA;AAEO,SAAS,UAAA,CAAW;AAAA,EACzB,IAAA;AAAA,EACA,OAAA;AAAA,EACA,KAAA;AAAA,EACA,WAAA;AAAA,EACA,QAAA;AAAA,EACA,MAAA;AAAA,EACA,IAAA,GAAO,IAAA;AAAA,EACP,YAAA,GAAe,KAAA;AAAA,EACf,eAAA,GAAkB,KAAA;AAAA,EAClB,SAAA,GAAY,KAAA;AAAA,EACZ;AACF,CAAA,EAAoB;AAElB,EAAA,MAAM,iBAAiB,CAAC,CAAC,SAAA,IAAa,qBAAA,CAAsB,KAAK,SAAS,CAAA;AAE1E,EAAA,uBACEjC,GAAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,IAAA;AAAA,MACA,YAAA,EAAc,CAAC,IAAA,KAAS;AACtB,QAAA,IAAI,CAAC,MAAM,OAAA,EAAQ;AAAA,MACrB,CAAA;AAAA,MAEA,QAAA,kBAAAC,IAAAA;AAAA,QAAC,aAAA;AAAA,QAAA;AAAA,UACC,SAAA,EAAW,CAAC,eAAA,IAAmB,CAAC,YAAA;AAAA,UAEhC,SAAA,EAAW,EAAA;AAAA,YACT,sDAAA;AAAA;AAAA,YAEA,cAAA,GAAiB,YAAA,GAAe,IAAA,CAAK,IAAI,CAAA;AAAA,YACzC;AAAA,WACF;AAAA,UACA,mBACE,YAAA,GAAe,CAAC,CAAA,KAAM,CAAA,CAAE,gBAAe,GAAI,MAAA;AAAA,UAE7C,iBAAiB,YAAA,GAAe,CAAC,CAAA,KAAM,CAAA,CAAE,gBAAe,GAAI,MAAA;AAAA,UAC5D,iBAAiB,SAAA,GAAY,MAAA,GAAY,CAAC,CAAA,KAAM,EAAE,cAAA,EAAe;AAAA,UAE/D,QAAA,EAAA;AAAA,YAAA,CAAA,KAAA,IAAS,WAAA,qBACTA,IAAAA,CAAC,YAAA,EAAA,EAAa,WAAU,6BAAA,EACrB,QAAA,EAAA;AAAA,cAAA,KAAA,oBAASD,GAAAA,CAAC,WAAA,EAAA,EAAa,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,cAC7B,WAAA;AAAA;AAAA,8BAGCA,IAAC,iBAAA,EAAA,EAAkB,OAAA,EAAO,MACxB,QAAA,kBAAAA,GAAAA,CAAC,KAAA,EAAA,EAAK,QAAA,EAAA,WAAA,EAAY,CAAA,EACpB;AAAA,aAAA,EAEJ,CAAA;AAAA,4BAIFA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gDACZ,QAAA,EACH,CAAA;AAAA,YAEC,0BACCA,GAAAA,CAAC,YAAA,EAAA,EAAa,SAAA,EAAU,+BACrB,QAAA,EAAA,MAAA,EACH;AAAA;AAAA;AAAA;AAEJ;AAAA,GACF;AAEJ;ACvFA,IAAM,KAAA,GAAyC;AAAA,EAC7C,EAAA,EAAI,aAAA;AAAA,EACJ,EAAA,EAAI,aAAA;AAAA,EACJ,EAAA,EAAI,aAAA;AAAA,EACJ,EAAA,EAAI;AACN,CAAA;AAEO,SAAS,WAAA,CAAY;AAAA,EAC1B,IAAA;AAAA,EACA,OAAA;AAAA,EACA,IAAA,GAAO,OAAA;AAAA,EACP,KAAA;AAAA,EACA,WAAA;AAAA,EACA,QAAA;AAAA,EACA,MAAA;AAAA,EACA,IAAA,GAAO,IAAA;AAAA,EACP;AACF,CAAA,EAAqB;AACnB,EAAA,MAAM,YAAA,GAAe,IAAA,KAAS,MAAA,IAAU,IAAA,KAAS,OAAA;AAEjD,EAAA,MAAM,iBAAiB,CAAC,CAAC,SAAA,IAAa,qBAAA,CAAsB,KAAK,SAAS,CAAA;AAE1E,EAAA,uBACEA,GAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,IAAA;AAAA,MACA,YAAA,EAAc,CAAC,IAAA,KAAS;AACtB,QAAA,IAAI,CAAC,MAAM,OAAA,EAAQ;AAAA,MACrB,CAAA;AAAA,MAEA,QAAA,kBAAAC,IAAAA;AAAA,QAAC,YAAA;AAAA,QAAA;AAAA,UACC,IAAA;AAAA,UACA,SAAA,EAAW,EAAA;AAAA,YACT,YAAA,KACG,cAAA,GAAiB,eAAA,GAAkB,KAAA,CAAM,IAAI,CAAA,CAAA;AAAA,YAChD;AAAA,WACF;AAAA,UAEA,cAAA,EACE,KAAA,IAAS,WAAA,GAAc,yBAAA,GAA4B,MAAA;AAAA,UAIpD,QAAA,EAAA;AAAA,YAAA,KAAA,IAAS,WAAA,mBACRA,IAAAA,CAAC,WAAA,EAAA,EAAY,WAAU,YAAA,EACrB,QAAA,EAAA;AAAA,8BAAAD,GAAAA,CAAC,UAAA,EAAA,EAAW,SAAA,EAAU,mCAAA,EAAqC,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,cAChE,+BAAeA,GAAAA,CAAC,gBAAA,EAAA,EAAiB,SAAA,EAAU,aAAa,QAAA,EAAA,WAAA,EAAY;AAAA,aAAA,EACvE,oBAEAA,GAAAA,CAAC,UAAA,EAAA,EAAW,SAAA,EAAU,WAAU,QAAA,EAAA,cAAA,EAAE,CAAA;AAAA,4BAGpCA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,+BAA+B,QAAA,EAAS,CAAA;AAAA,YAEtD,MAAA,oBAAUA,GAAAA,CAAC,WAAA,EAAA,EAAa,QAAA,EAAA,MAAA,EAAO;AAAA;AAAA;AAAA;AAClC;AAAA,GACF;AAEJ;ACtDO,SAAS,aAAA,CAAc;AAAA,EAC5B,IAAA;AAAA,EACA,OAAA;AAAA,EACA,KAAA;AAAA,EACA,WAAA;AAAA,EACA,YAAA,GAAe,cAAA;AAAA,EACf,WAAA,GAAc,cAAA;AAAA,EACd,SAAA;AAAA,EACA,cAAA,GAAiB,SAAA;AAAA,EACjB,OAAA,GAAU,KAAA;AAAA,EACV;AACF,CAAA,EAAuB;AACrB,EAAA,uBACEA,GAAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,IAAA;AAAA,MACA,YAAA,EAAc,CAAC,IAAA,KAAS;AACtB,QAAA,IAAI,CAAC,IAAA,IAAQ,CAAC,OAAA,EAAS,OAAA,EAAQ;AAAA,MACjC,CAAA;AAAA,MAEA,QAAA,kBAAAC,IAAAA;AAAA,QAAC,aAAA;AAAA,QAAA;AAAA,UACC,SAAA,EAAW,KAAA;AAAA,UACX,WAAW,SAAA,IAAA,IAAA,GAAA,SAAA,GAAa,UAAA;AAAA,UACxB,mBAAmB,OAAA,GAAU,CAAC,CAAA,KAAM,CAAA,CAAE,gBAAe,GAAI,MAAA;AAAA,UACzD,iBAAiB,OAAA,GAAU,CAAC,CAAA,KAAM,CAAA,CAAE,gBAAe,GAAI,MAAA;AAAA,UAErD,QAAA,EAAA;AAAA,YAAA,CAAA,KAAA,IAAS,WAAA,qBACTA,IAAAA,CAAC,YAAA,EAAA,EACE,QAAA,EAAA;AAAA,cAAA,KAAA,oBAASD,GAAAA,CAAC,WAAA,EAAA,EAAa,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,cAC7B,WAAA,oBACCA,GAAAA,CAAC,iBAAA,EAAA,EAAmB,QAAA,EAAA,WAAA,EAAY;AAAA,aAAA,EAEpC,CAAA;AAAA,4BAEFC,KAAC,YAAA,EAAA,EACC,QAAA,EAAA;AAAA,8BAAAD,GAAAA,CAAC,UAAO,OAAA,EAAQ,SAAA,EAAU,SAAS,OAAA,EAAS,QAAA,EAAU,SACnD,QAAA,EAAA,WAAA,EACH,CAAA;AAAA,8BACAA,IAAC,MAAA,EAAA,EAAO,OAAA,EAAS,gBAAgB,OAAA,EAAkB,OAAA,EAAS,WACzD,QAAA,EAAA,YAAA,EACH;AAAA,aAAA,EACF;AAAA;AAAA;AAAA;AACF;AAAA,GACF;AAEJ;AC1CO,SAAS,aAAa,OAAA,EAA+C;AAC1E,EAAA,MAAM;AAAA,IACJ,KAAA;AAAA,IACA,WAAA;AAAA,IACA,YAAA,GAAe,cAAA;AAAA,IACf,WAAA,GAAc,cAAA;AAAA,IACd,SAAA;AAAA,IACA,QAAA;AAAA,IACA,cAAA,GAAiB,SAAA;AAAA,IACjB,QAAA,GAAW,QAAA;AAAA,IACX,QAAA,GAAW;AAAA,GACb,GAAI,OAAA;AAEJ,EAAA,OAAO,KAAA,CAAM,MAAA;AAAA,IACX,CAAC,EAAA,qBACCC,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,6DAAA,EACb,QAAA,EAAA;AAAA,sBAAAD,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,uCAAA,EAAyC,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,MAC7D,+BACCA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,sCACZ,QAAA,EAAA,WAAA,EACH,CAAA;AAAA,sBAEFC,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,6BAAA,EACb,QAAA,EAAA;AAAA,wBAAAD,GAAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,OAAA,EAAQ,SAAA;AAAA,YACR,IAAA,EAAK,IAAA;AAAA,YACL,SAAS,MAAM;AACb,cAAA,KAAA,CAAM,QAAQ,EAAE,CAAA;AAChB,cAAA,QAAA,IAAA,IAAA,GAAA,MAAA,GAAA,QAAA,EAAA;AAAA,YACF,CAAA;AAAA,YAEC,QAAA,EAAA;AAAA;AAAA,SACH;AAAA,wBACAA,GAAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,OAAA,EAAS,cAAA;AAAA,YACT,IAAA,EAAK,IAAA;AAAA,YACL,SAAS,MAAM;AACb,cAAA,KAAA,CAAM,QAAQ,EAAE,CAAA;AAChB,cAAA,SAAA,EAAU;AAAA,YACZ,CAAA;AAAA,YAEC,QAAA,EAAA;AAAA;AAAA;AACH,OAAA,EACF;AAAA,KAAA,EACF,CAAA;AAAA,IAEF,EAAE,UAAU,QAAA;AAAS,GACvB;AACF;AC9DA,IAAM,kBAAA,GAAqB,GAAA;AAE3B,SAAS,gBAAA,CAAiB;AAAA,EACxB,OAAA;AAAA,EACA;AACF,CAAA,EAGG;AACD,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAIG,SAAS,IAAI,CAAA;AACrC,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAIA,SAAS,KAAK,CAAA;AAE5C,EAAAO,UAAU,MAAM;AACd,IAAA,IAAI,IAAA,EAAM;AACV,IAAA,MAAM,KAAA,GAAQ,UAAA,CAAW,cAAA,EAAgB,kBAAkB,CAAA;AAC3D,IAAA,OAAO,MAAM,aAAa,KAAK,CAAA;AAAA,EACjC,CAAA,EAAG,CAAC,IAAA,EAAM,cAAc,CAAC,CAAA;AAEzB,EAAA,uBACEV,GAAAA;AAAA,IAAC,aAAA;AAAA,IAAA;AAAA,MACC,IAAA;AAAA,MACA,OAAA;AAAA,MACA,OAAO,OAAA,CAAQ,KAAA;AAAA,MACf,aAAa,OAAA,CAAQ,WAAA;AAAA,MACrB,cAAc,OAAA,CAAQ,YAAA;AAAA,MACtB,aAAa,OAAA,CAAQ,WAAA;AAAA,MACrB,gBAAgB,OAAA,CAAQ,cAAA;AAAA,MACxB,SAAS,MAAM;AAtErB,QAAA,IAAA,EAAA;AAuEQ,QAAA,OAAA,CAAQ,KAAK,CAAA;AACb,QAAA,CAAA,EAAA,GAAA,OAAA,CAAQ,QAAA,KAAR,IAAA,GAAA,MAAA,GAAA,EAAA,CAAA,IAAA,CAAA,OAAA,CAAA;AAAA,MACF,CAAA;AAAA,MACA,WAAW,YAAY;AACrB,QAAA,IAAI;AACF,UAAA,UAAA,CAAW,IAAI,CAAA;AACf,UAAA,MAAM,QAAQ,SAAA,EAAU;AACxB,UAAA,OAAA,CAAQ,KAAK,CAAA;AAAA,QACf,CAAA,SAAE;AACA,UAAA,UAAA,CAAW,KAAK,CAAA;AAAA,QAClB;AAAA,MACF;AAAA;AAAA,GACF;AAEJ;AAEO,SAAS,aAAa,OAAA,EAA8B;AACzD,EAAA,IAAI,OAAO,aAAa,WAAA,EAAa;AAErC,EAAA,MAAM,SAAA,GAAY,QAAA,CAAS,aAAA,CAAc,KAAK,CAAA;AAC9C,EAAA,QAAA,CAAS,IAAA,CAAK,YAAY,SAAS,CAAA;AACnC,EAAA,MAAM,IAAA,GAAO,WAAW,SAAS,CAAA;AAEjC,EAAA,MAAM,UAAU,MAAM;AACpB,IAAA,IAAA,CAAK,OAAA,EAAQ;AACb,IAAA,SAAA,CAAU,MAAA,EAAO;AAAA,EACnB,CAAA;AAEA,EAAA,IAAA,CAAK,MAAA;AAAA,oBACHA,GAAAA,CAAC,gBAAA,EAAA,EAAiB,OAAA,EAAkB,gBAAgB,OAAA,EAAS;AAAA,GAC/D;AACF;ACzEA,IAAM,kBAAA,GAAqBsB,cAA2B,MAAM,CAAA;AAE5D,SAAS,KAAK,EAAA,EAI4D;AAJ5D,EAAA,IAAA,EAAA,GAAA,EAAA,EACZ;AAAA,IAAA,SAAA;AAAA,IACA,OAAA,GAAU;AAAA,GAjCZ,GA+Bc,EAAA,EAGT,KAAA,GAAA,SAAA,CAHS,EAAA,EAGT;AAAA,IAFH,WAAA;AAAA,IACA;AAAA,GAAA,CAAA;AAGA,EAAA,uBACEtB,GAAAA,CAAC,kBAAA,CAAmB,UAAnB,EAA4B,KAAA,EAAO,SAClC,QAAA,kBAAAA,GAAAA;AAAA,IAAe,aAAA,CAAA,IAAA;AAAA,IAAd,cAAA,CAAA;AAAA,MACC,WAAA,EAAU,MAAA;AAAA,MACV,SAAA,EAAW,EAAA,CAAG,qBAAA,EAAuB,SAAS;AAAA,KAAA,EAC1C,KAAA;AAAA,GACN,EACF,CAAA;AAEJ;AAEA,SAAS,SAAS,EAAA,EAG4B;AAH5B,EAAA,IAAA,EAAA,GAAA,EAAA,EAChB;AAAA,IAAA;AAAA,GAhDF,GA+CkB,EAAA,EAEb,KAAA,GAAA,SAAA,CAFa,EAAA,EAEb;AAAA,IADH;AAAA,GAAA,CAAA;AAGA,EAAA,MAAM,OAAA,GAAUuB,WAAW,kBAAkB,CAAA;AAC7C,EAAA,uBACEvB,GAAAA;AAAA,IAAe,aAAA,CAAA,IAAA;AAAA,IAAd,cAAA,CAAA;AAAA,MACC,WAAA,EAAU,WAAA;AAAA,MACV,SAAA,EAAW,EAAA;AAAA,QACT,gCAAA;AAAA,QACA,OAAA,KAAY,YACR,sEAAA,GACA,OAAA;AAAA,QACJ;AAAA;AACF,KAAA,EACI,KAAA;AAAA,GACN;AAEJ;AAEA,SAAS,YAAY,EAAA,EAG4B;AAH5B,EAAA,IAAA,EAAA,GAAA,EAAA,EACnB;AAAA,IAAA;AAAA,GApEF,GAmEqB,EAAA,EAEhB,KAAA,GAAA,SAAA,CAFgB,EAAA,EAEhB;AAAA,IADH;AAAA,GAAA,CAAA;AAGA,EAAA,MAAM,OAAA,GAAUuB,WAAW,kBAAkB,CAAA;AAC7C,EAAA,uBACEvB,GAAAA;AAAA,IAAe,aAAA,CAAA,OAAA;AAAA,IAAd,cAAA,CAAA;AAAA,MACC,WAAA,EAAU,cAAA;AAAA,MACV,SAAA,EAAW,EAAA;AAAA,QACT,wPAAA;AAAA,QACA,OAAA,KAAY,YACR,mOAAA,GACA,+LAAA;AAAA,QACJ;AAAA;AACF,KAAA,EACI,KAAA;AAAA,GACN;AAEJ;AAEA,SAAS,YAAY,EAAA,EAG4B;AAH5B,EAAA,IAAA,EAAA,GAAA,EAAA,EACnB;AAAA,IAAA;AAAA,GAxFF,GAuFqB,EAAA,EAEhB,KAAA,GAAA,SAAA,CAFgB,EAAA,EAEhB;AAAA,IADH;AAAA,GAAA,CAAA;AAGA,EAAA,uBACEA,GAAAA;AAAA,IAAe,aAAA,CAAA,OAAA;AAAA,IAAd,cAAA,CAAA;AAAA,MACC,WAAA,EAAU,cAAA;AAAA,MACV,SAAA,EAAW,EAAA,CAAG,qBAAA,EAAuB,SAAS;AAAA,KAAA,EAC1C,KAAA;AAAA,GACN;AAEJ;ACnDO,SAAS,SAAA,CAAU;AAAA,EACxB,KAAA;AAAA,EACA,IAAA,GAAO,MAAA;AAAA,EACP,KAAA;AAAA,EACA,YAAA;AAAA,EACA,aAAA;AAAA,EACA,SAAA;AAAA,EACA,aAAA;AAAA,EACA;AACF,CAAA,EAAmB;AAxDnB,EAAA,IAAA,EAAA;AAyDE,EAAA,uBACEC,IAAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACC,OAAA,EAAS,IAAA;AAAA,MACT,KAAA;AAAA,MACA,YAAA,EAAc,YAAA,IAAA,IAAA,GAAA,YAAA,GAAA,CAAgB,EAAA,GAAA,KAAA,CAAM,CAAC,MAAP,IAAA,GAAA,MAAA,GAAA,EAAA,CAAU,KAAA;AAAA,MACxC,aAAA;AAAA,MACA,SAAA;AAAA,MAEA,QAAA,EAAA;AAAA,wBAAAD,GAAAA,CAAC,QAAA,EAAA,EAAS,SAAA,EAAW,EAAA,CAAG,QAAA,EAAU,aAAa,CAAA,EAC5C,QAAA,EAAA,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,qBACVA,IAAC,WAAA,EAAA,EAA6B,KAAA,EAAO,IAAA,CAAK,KAAA,EAAO,QAAA,EAAU,IAAA,CAAK,QAAA,EAC7D,QAAA,EAAA,IAAA,CAAK,KAAA,EAAA,EADU,IAAA,CAAK,KAEvB,CACD,CAAA,EACH,CAAA;AAAA,QACC,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,qBACVA,GAAAA;AAAA,UAAC,WAAA;AAAA,UAAA;AAAA,YAEC,OAAO,IAAA,CAAK,KAAA;AAAA,YACZ,SAAA,EAAW,gBAAA;AAAA,YAEV,QAAA,EAAA,IAAA,CAAK;AAAA,WAAA;AAAA,UAJD,IAAA,CAAK;AAAA,SAMb;AAAA;AAAA;AAAA,GACH;AAEJ;ACxBA,IAAM,WAAA,GAA8C;AAAA,EAClD,EAAA,EAAI,gBAAA;AAAA,EACJ,EAAA,EAAI;AACN,CAAA;AAEA,IAAMmC,UAAAA,GAA4C;AAAA,EAChD,EAAA,EAAI,QAAA;AAAA,EACJ,EAAA,EAAI;AACN,CAAA;AAEA,IAAM,UAAA,GAA6C;AAAA,EACjD,EAAA,EAAI,SAAA;AAAA,EACJ,EAAA,EAAI;AACN,CAAA;AAEO,SAAS,UAAA,CAAW;AAAA,EACzB,KAAA;AAAA,EACA,OAAA;AAAA,EACA,MAAA,GAAS,SAAA;AAAA,EACT,QAAA;AAAA,EACA,SAAA,GAAY,YAAA;AAAA,EACZ,IAAA,GAAO,IAAA;AAAA,EACP;AACF,CAAA,EAAoB;AAClB,EAAA,MAAM,WAAW,WAAA,EAAY;AAE7B,EAAA,IAAI,QAAA,IAAY,cAAc,YAAA,EAAc;AAC1C,IAAA,uBACEnC,GAAAA;AAAA,MAAC,WAAA;AAAA,MAAA;AAAA,QACC,KAAA;AAAA,QACA,OAAA;AAAA,QACA,MAAA;AAAA,QACA;AAAA;AAAA,KACF;AAAA,EAEJ;AAEA,EAAA,MAAM,aAAa,SAAA,KAAc,UAAA;AAEjC,EAAA,uBACEA,GAAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,EAAA;AAAA,QACT,aAAA;AAAA,QACA,aAAa,UAAA,GAAa,cAAA;AAAA,QAC1B;AAAA,OACF;AAAA,MAEC,QAAA,EAAA,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,EAAM,KAAA,KAAU;AAC1B,QAAA,MAAM,MAAA,GAAS,KAAA,KAAU,KAAA,CAAM,MAAA,GAAS,CAAA;AACxC,QAAA,MAAM,SAAS,KAAA,GAAQ,OAAA;AACvB,QAAA,MAAM,YAAY,KAAA,KAAU,OAAA;AAC5B,QAAA,MAAM,OAAA,GAAU,aAAa,MAAA,KAAW,OAAA;AACxC,QAAA,MAAM,WAAW,CAAC,CAAC,QAAA,IAAY,CAAC,KAAK,QAAA,IAAY,MAAA;AACjD,QAAA,MAAM,kBAAkB,KAAA,GAAQ,OAAA;AAEhC,QAAA,MAAM,yBACJA,GAAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAW,EAAA;AAAA,cACT,2EAAA;AAAA,cACA,YAAY,IAAI,CAAA;AAAA,cAChB,OAAA,GACI,+DAAA,GACA,MAAA,GACA,mDAAA,GACA,YACA,mDAAA,GACA;AAAA,aACN;AAAA,YAEC,QAAA,EAAA,MAAA,mBAASA,GAAAA,CAAC4B,KAAAA,EAAA,EAAM,WAAWO,UAAAA,CAAU,IAAI,CAAA,EAAG,CAAA,GAAK,KAAA,GAAQ;AAAA;AAAA,SAC5D;AAGF,QAAA,MAAM,KAAA,mBACJlC,IAAAA,CAAC,MAAA,EAAA,EAAK,WAAU,iCAAA,EACd,QAAA,EAAA;AAAA,0BAAAD,GAAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACC,SAAA,EAAW,EAAA;AAAA,gBACT,WAAW,IAAI,CAAA;AAAA,gBACf,UAAA;AAAA,gBACA,OAAA,GACI,gCAAA,GACA,SAAA,GACA,+BAAA,GACA,SACA,6BAAA,GACA;AAAA,eACN;AAAA,cAEC,QAAA,EAAA,IAAA,CAAK;AAAA;AAAA,WACR;AAAA,UACC,IAAA,CAAK,+BACJA,GAAAA,CAAC,UAAK,SAAA,EAAU,wCAAA,EACb,eAAK,WAAA,EACR;AAAA,SAAA,EAEJ,CAAA;AAGF,QAAA,MAAM,0BACJC,IAAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,QAAA;AAAA,YACL,UAAU,CAAC,QAAA;AAAA,YACX,cAAA,EAAc,YAAY,MAAA,GAAS,MAAA;AAAA,YACnC,OAAA,EAAS,QAAA,GAAW,MAAM,QAAA,IAAA,IAAA,GAAA,MAAA,GAAA,QAAA,CAAW,KAAA,CAAA,GAAS,MAAA;AAAA,YAC9C,SAAA,EAAW,EAAA;AAAA,cACT,yEAAA;AAAA,cACA,WAAW,iCAAA,GAAoC;AAAA,aACjD;AAAA,YAEC,QAAA,EAAA;AAAA,cAAA,MAAA;AAAA,cACA;AAAA;AAAA;AAAA,SACH;AAGF,QAAA,IAAI,UAAA,EAAY;AACd,UAAA,uBACEA,KAAC,IAAA,EAAA,EAAe,SAAA,EAAW,GAAG,YAAA,EAAc,CAAC,MAAA,IAAU,MAAM,CAAA,EAC3D,QAAA,EAAA;AAAA,4BAAAA,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,4BAAA,EACZ,QAAA,EAAA;AAAA,cAAA,MAAA;AAAA,cACA,CAAC,0BACAD,GAAAA;AAAA,gBAAC,MAAA;AAAA,gBAAA;AAAA,kBACC,SAAA,EAAW,EAAA;AAAA,oBACT,kBAAA;AAAA,oBACA,kBAAkB,YAAA,GAAe;AAAA;AACnC;AAAA;AACF,aAAA,EAEJ,CAAA;AAAA,4BACAA,GAAAA;AAAA,cAAC,QAAA;AAAA,cAAA;AAAA,gBACC,IAAA,EAAK,QAAA;AAAA,gBACL,UAAU,CAAC,QAAA;AAAA,gBACX,cAAA,EAAc,YAAY,MAAA,GAAS,MAAA;AAAA,gBACnC,OAAA,EAAS,QAAA,GAAW,MAAM,QAAA,IAAA,IAAA,GAAA,MAAA,GAAA,QAAA,CAAW,KAAA,CAAA,GAAS,MAAA;AAAA,gBAC9C,SAAA,EAAW,EAAA;AAAA,kBACT,4CAAA;AAAA,kBACA,WAAW,iCAAA,GAAoC;AAAA,iBACjD;AAAA,gBAEC,QAAA,EAAA;AAAA;AAAA;AACH,WAAA,EAAA,EAvBO,KAwBT,CAAA;AAAA,QAEJ;AAEA,QAAA,uBACEC,IAAAA,CAAC,IAAA,EAAA,EAAe,SAAA,EAAU,kCAAA,EACvB,QAAA,EAAA;AAAA,UAAA,OAAA;AAAA,UACA,CAAC,0BACAD,GAAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACC,SAAA,EAAW,EAAA;AAAA,gBACT,kBAAA;AAAA,gBACA,kBAAkB,YAAA,GAAe;AAAA;AACnC;AAAA;AACF,SAAA,EAAA,EARK,KAUT,CAAA;AAAA,MAEJ,CAAC;AAAA;AAAA,GACH;AAEJ;AAEA,SAAS,WAAA,CAAY;AAAA,EACnB,KAAA;AAAA,EACA,OAAA;AAAA,EACA,MAAA;AAAA,EACA;AACF,CAAA,EAKG;AACD,EAAA,MAAM,QAAQ,KAAA,CAAM,MAAA;AACpB,EAAA,MAAM,UAAA,GAAa,MAAM,OAAO,CAAA;AAChC,EAAA,MAAM,UAAU,MAAA,KAAW,OAAA;AAC3B,EAAA,MAAM,UAAU,KAAA,GAAQ,CAAA,GAAA,CAAM,OAAA,GAAU,CAAA,IAAK,QAAS,GAAA,GAAM,CAAA;AAE5D,EAAA,uBACEC,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAW,EAAA,CAAG,QAAA,EAAU,SAAS,CAAA,EACpC,QAAA,EAAA;AAAA,oBAAAA,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,yCAAA,EACb,QAAA,EAAA;AAAA,sBAAAA,IAAAA;AAAA,QAAC,MAAA;AAAA,QAAA;AAAA,UACC,SAAA,EAAW,EAAA;AAAA,YACT,uBAAA;AAAA,YACA,UAAU,kBAAA,GAAqB;AAAA,WACjC;AAAA,UAEC,QAAA,EAAA;AAAA,YAAA,OAAA,GAAU,CAAA;AAAA,YAAE,IAAA;AAAA,YAAG,UAAA,IAAA,IAAA,GAAA,MAAA,GAAA,UAAA,CAAY;AAAA;AAAA;AAAA,OAC9B;AAAA,sBACAA,IAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,wCAAA,EACb,QAAA,EAAA;AAAA,QAAA,OAAA,GAAU,CAAA;AAAA,QAAE,KAAA;AAAA,QAAI;AAAA,OAAA,EACnB;AAAA,KAAA,EACF,CAAA;AAAA,IAAA,CACC,UAAA,IAAA,IAAA,GAAA,MAAA,GAAA,UAAA,CAAY,gCACXD,GAAAA,CAAC,OAAE,SAAA,EAAU,sCAAA,EACV,qBAAW,WAAA,EACd,CAAA;AAAA,oBAEFA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,2DACb,QAAA,kBAAAA,GAAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAW,EAAA;AAAA,UACT,oCAAA;AAAA,UACA,UAAU,gBAAA,GAAmB;AAAA,SAC/B;AAAA,QACA,KAAA,EAAO,EAAE,KAAA,EAAO,CAAA,EAAG,OAAO,CAAA,CAAA,CAAA;AAAI;AAAA,KAChC,EACF;AAAA,GAAA,EACF,CAAA;AAEJ;ACvMO,SAAS,WAAA,CAAY;AAAA,EAC1B,KAAA;AAAA,EACA,OAAA,GAAU,OAAA;AAAA,EACV,OAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA,GAAY,cAAA;AAAA,EACZ,SAAA,GAAY,cAAA;AAAA,EACZ,IAAA,GAAO,IAAA;AAAA,EACP,SAAA;AAAA,EACA,gBAAA;AAAA,EACA,OAAA,GAAU;AACZ,CAAA,EAAqB;AAhFrB,EAAA,IAAA,EAAA,EAAA,EAAA;AAiFE,EAAA,IAAI,YAAY,MAAA,EAAQ;AACtB,IAAA,uBACEA,GAAAA;AAAA,MAAC,SAAA;AAAA,MAAA;AAAA,QACC,SAAA;AAAA,QACA,gBAAA;AAAA,QACA,KAAA,EAAA,CAAO,EAAA,GAAA,KAAA,CAAM,OAAO,CAAA,KAAb,IAAA,GAAA,MAAA,GAAA,EAAA,CAAgB,GAAA;AAAA,QACvB,aAAA,EAAe,CAAC,KAAA,KAAU;AACxB,UAAA,MAAM,QAAQ,KAAA,CAAM,SAAA,CAAU,CAAC,IAAA,KAAS,IAAA,CAAK,QAAQ,KAAK,CAAA;AAC1D,UAAA,IAAI,KAAA,KAAU,EAAA,EAAI,QAAA,CAAS,KAAK,CAAA;AAAA,QAClC,CAAA;AAAA,QACA,KAAA,EAAO,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,MAAU;AAAA,UAC1B,OAAO,IAAA,CAAK,GAAA;AAAA,UACZ,OAAO,IAAA,CAAK,KAAA;AAAA,UACZ,SAAS,IAAA,CAAK,OAAA;AAAA,UACd,UAAU,IAAA,CAAK;AAAA,SACjB,CAAE;AAAA;AAAA,KACJ;AAAA,EAEJ;AAEA,EAAA,MAAM,UAAU,OAAA,KAAY,CAAA;AAC5B,EAAA,MAAM,MAAA,GAAS,OAAA,KAAY,KAAA,CAAM,MAAA,GAAS,CAAA;AAE1C,EAAA,uBACEC,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EACH,QAAA,EAAA;AAAA,oBAAAD,GAAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAU,MAAA;AAAA,QACV,IAAA;AAAA,QACA,OAAA;AAAA,QACA,QAAA;AAAA,QACA,KAAA,EAAO,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,MAAU;AAAA,UAC1B,OAAO,IAAA,CAAK,KAAA;AAAA,UACZ,aAAa,IAAA,CAAK,WAAA;AAAA,UAClB,UAAU,IAAA,CAAK;AAAA,SACjB,CAAE;AAAA;AAAA,KACJ;AAAA,oBACAA,IAAC,KAAA,EAAA,EAAI,SAAA,EAAW,kBAAmB,QAAA,EAAA,CAAA,EAAA,GAAA,KAAA,CAAM,OAAO,CAAA,KAAb,IAAA,GAAA,MAAA,GAAA,EAAA,CAAgB,OAAA,EAAQ,CAAA;AAAA,IAC1D,CAAC,OAAA,oBACAC,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,yCAAA,EACb,QAAA,EAAA;AAAA,sBAAAD,GAAAA;AAAA,QAAC,MAAA;AAAA,QAAA;AAAA,UACC,IAAA,EAAK,QAAA;AAAA,UACL,OAAA,EAAQ,SAAA;AAAA,UACR,QAAA,EAAU,OAAA;AAAA,UACV,OAAA,EAAS,MAAM,QAAA,CAAS,IAAA,CAAK,IAAI,OAAA,GAAU,CAAA,EAAG,CAAC,CAAC,CAAA;AAAA,UAE/C,QAAA,EAAA;AAAA;AAAA,OACH;AAAA,sBACAA,GAAAA;AAAA,QAAC,MAAA;AAAA,QAAA;AAAA,UACC,IAAA,EAAK,QAAA;AAAA,UACL,QAAA,EAAU,MAAA;AAAA,UACV,OAAA,EAAS,MAAM,QAAA,CAAS,IAAA,CAAK,GAAA,CAAI,UAAU,CAAA,EAAG,KAAA,CAAM,MAAA,GAAS,CAAC,CAAC,CAAA;AAAA,UAE9D,QAAA,EAAA;AAAA;AAAA;AACH,KAAA,EACF;AAAA,GAAA,EAEJ,CAAA;AAEJ;ACjEO,SAAS,aAAA,CAAc;AAAA,EAC5B,UAAA;AAAA,EACA,UAAA;AAAA,EACA,QAAA;AAAA,EACA,MAAA,GAAS,CAAC,cAAA,EAAM,oBAAK,CAAA;AAAA,EACrB,UAAA,GAAa,IAAA;AAAA,EACb,iBAAA,GAAoB,iBAAA;AAAA,EACpB,UAAA,GAAa,GAAA;AAAA,EACb,QAAA;AAAA,EACA,OAAA;AAAA,EACA,MAAA;AAAA,EACA;AACF,CAAA,EAAuB;AACrB,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAIG,QAAAA,CAAmB,EAAE,CAAA;AAEnD,EAAA,MAAM,SAAA,GAAY,IAAI,GAAA,CAAI,UAAU,CAAA;AACpC,EAAA,MAAM,SAAA,GAAY,UAAA,CAAW,MAAA,CAAO,CAAC,CAAA,KAAM,CAAC,SAAA,CAAU,GAAA,CAAI,CAAA,CAAE,GAAG,CAAC,CAAA;AAChE,EAAA,MAAM,UAAA,GAAa,WAAW,MAAA,CAAO,CAAC,MAAM,SAAA,CAAU,GAAA,CAAI,CAAA,CAAE,GAAG,CAAC,CAAA;AAEhE,EAAA,MAAM,UAAA,GAAa,IAAI,GAAA,CAAI,OAAO,CAAA;AAClC,EAAA,MAAM,cAAc,SAAA,CAAU,MAAA;AAAA,IAC5B,CAAC,MAAM,UAAA,CAAW,GAAA,CAAI,EAAE,GAAG,CAAA,IAAK,CAAC,CAAA,CAAE;AAAA,GACrC;AACA,EAAA,MAAM,eAAe,UAAA,CAAW,MAAA;AAAA,IAC9B,CAAC,MAAM,UAAA,CAAW,GAAA,CAAI,EAAE,GAAG,CAAA,IAAK,CAAC,CAAA,CAAE;AAAA,GACrC;AAEA,EAAA,MAAM,YAAY,MAAM;AACtB,IAAA,MAAM,SAAS,WAAA,CAAY,GAAA,CAAI,CAAC,CAAA,KAAM,EAAE,GAAG,CAAA;AAC3C,IAAA,QAAA,CAAS,CAAC,GAAG,UAAA,EAAY,GAAG,MAAM,CAAC,CAAA;AACnC,IAAA,UAAA,CAAW,CAAC,CAAA,KAAM,CAAA,CAAE,MAAA,CAAO,CAAC,CAAA,KAAM,CAAC,MAAA,CAAO,QAAA,CAAS,CAAC,CAAC,CAAC,CAAA;AAAA,EACxD,CAAA;AACA,EAAA,MAAM,WAAW,MAAM;AACrB,IAAA,MAAM,MAAA,GAAS,IAAI,GAAA,CAAI,YAAA,CAAa,IAAI,CAAC,CAAA,KAAM,CAAA,CAAE,GAAG,CAAC,CAAA;AACrD,IAAA,QAAA,CAAS,UAAA,CAAW,OAAO,CAAC,CAAA,KAAM,CAAC,MAAA,CAAO,GAAA,CAAI,CAAC,CAAC,CAAC,CAAA;AACjD,IAAA,UAAA,CAAW,CAAC,CAAA,KAAM,CAAA,CAAE,MAAA,CAAO,CAAC,CAAA,KAAM,CAAC,MAAA,CAAO,GAAA,CAAI,CAAC,CAAC,CAAC,CAAA;AAAA,EACnD,CAAA;AAEA,EAAA,MAAM,MAAA,GAAS,CAAC,GAAA,KACd,UAAA;AAAA,IAAW,CAAC,CAAA,KACV,CAAA,CAAE,QAAA,CAAS,GAAG,IAAI,CAAA,CAAE,MAAA,CAAO,CAAC,CAAA,KAAM,MAAM,GAAG,CAAA,GAAI,CAAC,GAAG,GAAG,GAAG;AAAA,GAC3D;AAEF,EAAA,MAAM,YAAY,CAAC,IAAA,EAAgB,IAAA,KACjC,UAAA,CAAW,CAAC,CAAA,KAAM;AAChB,IAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,CAAC,CAAA;AACrB,IAAA,IAAI,IAAA,OAAW,OAAA,CAAQ,CAAC,MAAM,GAAA,CAAI,GAAA,CAAI,CAAC,CAAC,CAAA;AAAA,cAC9B,OAAA,CAAQ,CAAC,MAAM,GAAA,CAAI,MAAA,CAAO,CAAC,CAAC,CAAA;AACtC,IAAA,OAAO,CAAC,GAAG,GAAG,CAAA;AAAA,EAChB,CAAC,CAAA;AAEH,EAAA,MAAM,UAAA,GAAa;AAAA,IACjB,WAAA,EAAa,UAAA;AAAA,IACb,QAAA,EAAU,MAAA;AAAA,IACV,WAAA,EAAa,SAAA;AAAA,IACb,UAAA;AAAA,IACA,iBAAA;AAAA,IACA,UAAA;AAAA,IACA,QAAA;AAAA,IACA,OAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAA,uBACEF,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAW,EAAA,CAAG,0BAAA,EAA4B,SAAS,CAAA,EACtD,QAAA,EAAA;AAAA,oBAAAD,GAAAA,CAAC,gCAAc,KAAA,EAAO,MAAA,CAAO,CAAC,CAAA,EAAG,KAAA,EAAO,aAAe,UAAA,CAAY,CAAA;AAAA,oBAEnEC,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,oCAAA,EACb,QAAA,EAAA;AAAA,sBAAAD,GAAAA;AAAA,QAAC,MAAA;AAAA,QAAA;AAAA,UACC,IAAA,EAAK,QAAA;AAAA,UAEL,OAAA,EAAS,WAAA,CAAY,MAAA,GAAS,CAAA,GAAI,SAAA,GAAY,SAAA;AAAA,UAC9C,IAAA,EAAK,MAAA;AAAA,UACL,YAAA,EAAW,6CAAA;AAAA,UACX,QAAA,EAAU,YAAY,MAAA,KAAW,CAAA;AAAA,UACjC,OAAA,EAAS,SAAA;AAAA,UACT,SAAA,EAAU,qBAAA;AAAA,UAEV,QAAA,kBAAAA,GAAAA,CAACwB,YAAAA,EAAA,EAAa,WAAU,QAAA,EAAS;AAAA;AAAA,OACnC;AAAA,sBACAxB,GAAAA;AAAA,QAAC,MAAA;AAAA,QAAA;AAAA,UACC,IAAA,EAAK,QAAA;AAAA,UACL,OAAA,EAAS,YAAA,CAAa,MAAA,GAAS,CAAA,GAAI,SAAA,GAAY,SAAA;AAAA,UAC/C,IAAA,EAAK,MAAA;AAAA,UACL,YAAA,EAAW,uCAAA;AAAA,UACX,QAAA,EAAU,aAAa,MAAA,KAAW,CAAA;AAAA,UAClC,OAAA,EAAS,QAAA;AAAA,UACT,SAAA,EAAU,qBAAA;AAAA,UAEV,QAAA,kBAAAA,GAAAA,CAAC8B,WAAAA,EAAA,EAAY,WAAU,QAAA,EAAS;AAAA;AAAA;AAClC,KAAA,EACF,CAAA;AAAA,oBAEA9B,IAAC,aAAA,EAAA,cAAA,CAAA,EAAc,KAAA,EAAO,OAAO,CAAC,CAAA,EAAG,KAAA,EAAO,UAAA,EAAA,EAAgB,UAAA,CAAY;AAAA,GAAA,EACtE,CAAA;AAEJ;AAiBA,SAAS,QAAA,CAAS,MAAoB,OAAA,EAAoC;AA3L1E,EAAA,IAAA,EAAA,EAAA,EAAA;AA4LE,EAAA,IAAI,mCAAS,MAAA,EAAQ;AACnB,IAAA,OAAO,OAAA,CACJ,GAAA,CAAI,CAAC,CAAA,KAAG;AA9Lf,MAAA,IAAAQ,GAAAA;AA8LmB,MAAA,OAAA,CAAA,CAAE,SAAA,GAAY,MAAA,CAAA,CAAOA,GAAAA,GAAA,IAAA,CAAK,CAAA,CAAE,SAAS,CAAA,KAAhB,IAAA,GAAAA,GAAAA,GAAqB,EAAE,CAAA,GAAI,EAAA;AAAA,IAAA,CAAG,CAAA,CAC/D,KAAK,GAAG,CAAA;AAAA,EACb;AACA,EAAA,OAAO,CAAA,EAAA,CAAG,UAAK,KAAA,KAAL,IAAA,GAAA,EAAA,GAAc,EAAE,CAAA,CAAA,EAAA,CAAI,EAAA,GAAA,IAAA,CAAK,WAAA,KAAL,IAAA,GAAA,EAAA,GAAoB,EAAE,CAAA,CAAA;AACtD;AAEA,SAAS,aAAA,CAAc;AAAA,EACrB,KAAA;AAAA,EACA,KAAA;AAAA,EACA,WAAA;AAAA,EACA,QAAA;AAAA,EACA,WAAA;AAAA,EACA,UAAA;AAAA,EACA,iBAAA;AAAA,EACA,UAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAAA,EACA;AACF,CAAA,EAAuB;AACrB,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAIL,SAAS,EAAE,CAAA;AACvC,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAIA,SAAS,CAAC,CAAA;AAElC,EAAA,MAAM,CAAA,GAAI,MAAA,CAAO,IAAA,EAAK,CAAE,WAAA,EAAY;AACpC,EAAA,MAAM,OAAA,GAAU,CAAA,GACZ,KAAA,CAAM,MAAA,CAAO,CAAC,CAAA,KAAM,QAAA,CAAS,CAAA,EAAG,OAAO,EAAE,WAAA,EAAY,CAAE,QAAA,CAAS,CAAC,CAAC,CAAA,GAClE,KAAA;AAGJ,EAAA,MAAM,UAAA,GAAa,CAAC,EAAC,OAAA,IAAA,IAAA,GAAA,MAAA,GAAA,OAAA,CAAS,MAAA,CAAA;AAC9B,EAAA,MAAM,eAAe,UAAA,GACjB;AAAA,IACE,QAAA;AAAA,IACA,GAAG,OAAA,CAAS,GAAA;AAAA,MAAI,CAAC,CAAA,KACf,CAAA,CAAE,KAAA,IAAS,OACP,eAAA,GACA,OAAO,CAAA,CAAE,KAAA,KAAU,QAAA,GACjB,CAAA,EAAG,CAAA,CAAE,KAAK,OACV,CAAA,CAAE;AAAA;AACV,GACF,CAAE,IAAA,CAAK,GAAG,CAAA,GACV,MAAA;AAGJ,EAAA,MAAM,UAAU,OAAA,CAAQ,MAAA,CAAO,CAAC,CAAA,KAAM,CAAC,EAAE,QAAQ,CAAA;AACjD,EAAA,MAAM,YAAA,GAAe,OAAA,CAAQ,MAAA,CAAO,CAAC,CAAA,KAAM,YAAY,GAAA,CAAI,CAAA,CAAE,GAAG,CAAC,CAAA,CAAE,MAAA;AACnE,EAAA,MAAM,UAAA,GACJ,OAAA,CAAQ,MAAA,GAAS,CAAA,IAAK,OAAA,CAAQ,KAAA,CAAM,CAAC,CAAA,KAAM,WAAA,CAAY,GAAA,CAAI,CAAA,CAAE,GAAG,CAAC,CAAA;AACnE,EAAA,MAAM,WAAA,GAAc,YAAA,GAAe,CAAA,IAAK,CAAC,UAAA;AAGzC,EAAA,MAAM,OAAA,GAAU,QAAA,GAAW,IAAA,CAAK,GAAA,CAAI,MAAM,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,KAAK,OAAA,CAAQ,MAAA,GAAS,QAAQ,CAAC,CAAC,CAAA,GAAI,CAAA;AAC/F,EAAA,MAAM,IAAA,GAAO,WACT,OAAA,CAAQ,KAAA,CAAA,CAAO,UAAU,CAAA,IAAK,QAAA,EAAU,OAAA,GAAU,QAAQ,CAAA,GAC1D,OAAA;AAEJ,EAAA,uBACEF,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,+EAAA,EAEb,QAAA,EAAA;AAAA,oBAAAA,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,2CAAA,EACb,QAAA,EAAA;AAAA,sBAAAD,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,aAAA,EAAe,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,sBACrCC,IAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,uCAAA,EAAwC,QAAA,EAAA;AAAA,QAAA,SAAA;AAAA,wBACpDD,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,iBAAA,EAAmB,kBAAQ,MAAA,EAAO,CAAA;AAAA,QAAI,QAAA;AAAA,QACpD,YAAA,GAAe,CAAA,oBACdC,IAAAA,CAAAG,UAAA,EACG,QAAA,EAAA;AAAA,UAAA,qBAAA;AAAA,0BACDJ,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,mBAAmB,QAAA,EAAA,YAAA,EAAa;AAAA,SAAA,EAC/C;AAAA,OAAA,EAEJ;AAAA,KAAA,EACF,CAAA;AAAA,IAGC,UAAA,oBACCA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,sBACb,QAAA,kBAAAC,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,qKAAA,EACb,QAAA,EAAA;AAAA,sBAAAD,GAAAA,CAACoC,MAAAA,EAAA,EAAO,SAAA,EAAU,uCAAA,EAAwC,CAAA;AAAA,sBAC1DpC,GAAAA;AAAA,QAAC,OAAA;AAAA,QAAA;AAAA,UACC,KAAA,EAAO,MAAA;AAAA,UACP,QAAA,EAAU,CAAC,CAAA,KAAM;AACf,YAAA,SAAA,CAAU,CAAA,CAAE,OAAO,KAAK,CAAA;AACxB,YAAA,OAAA,CAAQ,CAAC,CAAA;AAAA,UACX,CAAA;AAAA,UACA,WAAA,EAAa,iBAAA;AAAA,UACb,SAAA,EAAU;AAAA;AAAA;AACZ,KAAA,EACF,CAAA,EACF,CAAA;AAAA,IAID,6BACCC,IAAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAU,0GAAA;AAAA,QACV,KAAA,EAAO,EAAE,mBAAA,EAAqB,YAAA,EAAa;AAAA,QAE3C,QAAA,EAAA;AAAA,0BAAAD,GAAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cACC,OAAA,EAAS,UAAA,GAAa,IAAA,GAAO,WAAA,GAAc,eAAA,GAAkB,KAAA;AAAA,cAC7D,eAAA,EAAiB,CAAC,CAAA,KAChB,WAAA;AAAA,gBACE,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,KAAM,EAAE,GAAG,CAAA;AAAA,gBACxB,CAAC,CAAC;AAAA,eACJ;AAAA,cAEF,YAAA,EAAW,2BAAA;AAAA,cACX,QAAA,EAAU,QAAQ,MAAA,KAAW;AAAA;AAAA,WAC/B;AAAA,UACC,OAAA,CAAS,GAAA,CAAI,CAAC,CAAA,EAAG,EAAA,qBAChBA,GAAAA,CAAC,MAAA,EAAA,EAAc,SAAA,EAAU,UAAA,EACtB,QAAA,EAAA,CAAA,CAAE,KAAA,EAAA,EADM,EAEX,CACD;AAAA;AAAA;AAAA,KACH,mBAEAC,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,wGAAA,EACb,QAAA,EAAA;AAAA,sBAAAD,GAAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UACC,OAAA,EAAS,UAAA,GAAa,IAAA,GAAO,WAAA,GAAc,eAAA,GAAkB,KAAA;AAAA,UAC7D,eAAA,EAAiB,CAAC,CAAA,KAChB,WAAA;AAAA,YACE,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,KAAM,EAAE,GAAG,CAAA;AAAA,YACxB,CAAC,CAAC;AAAA,WACJ;AAAA,UAEF,YAAA,EAAW,2BAAA;AAAA,UACX,QAAA,EAAU,QAAQ,MAAA,KAAW;AAAA;AAAA,OAC/B;AAAA,sBACAA,GAAAA,CAAC,MAAA,EAAA,EAAK,QAAA,EAAA,cAAA,EAAE,CAAA;AAAA,sBACRC,IAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,SAAA,EACb,QAAA,EAAA;AAAA,QAAA,YAAA;AAAA,QAAa,GAAA;AAAA,QAAE,OAAA,CAAQ;AAAA,OAAA,EAC1B;AAAA,KAAA,EACF,CAAA;AAAA,oBAIFD,GAAAA;AAAA,MAAC,IAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAU,iBAAA;AAAA,QACV,KAAA,EAAO,EAAE,MAAA,EAAQ,UAAA,EAAW;AAAA,QAE3B,eAAK,MAAA,KAAW,CAAA,mBACfA,GAAAA,CAAC,IAAA,EAAA,EAAG,WAAU,2EAAA,EAA4E,QAAA,EAAA,8CAAA,EAE1F,IAEA,IAAA,CAAK,GAAA,CAAI,CAAC,IAAA,qBACRA,IAAC,IAAA,EAAA,EAAkB,SAAA,EAAU,0BAC3B,QAAA,kBAAAC,IAAAA;AAAA,UAAC,OAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAW,EAAA;AAAA,cACT,6DAAA;AAAA,cACA,aACI,qCAAA,GACA,mCAAA;AAAA,cACJ,KAAK,QAAA,IAAY;AAAA,aACnB;AAAA,YACA,KAAA,EACE,UAAA,GACI,EAAE,mBAAA,EAAqB,cAAa,GACpC,MAAA;AAAA,YAGN,QAAA,EAAA;AAAA,8BAAAD,GAAAA;AAAA,gBAAC,QAAA;AAAA,gBAAA;AAAA,kBACC,OAAA,EAAS,WAAA,CAAY,GAAA,CAAI,IAAA,CAAK,GAAG,CAAA;AAAA,kBACjC,eAAA,EAAiB,MAAM,QAAA,CAAS,IAAA,CAAK,GAAG,CAAA;AAAA,kBACxC,UAAU,IAAA,CAAK;AAAA;AAAA,eACjB;AAAA,cACC,UAAA,GACC,OAAA,CAAS,GAAA,CAAI,CAAC,GAAG,EAAA,qBACfA,GAAAA,CAAC,MAAA,EAAA,EAAc,WAAU,kBAAA,EACtB,QAAA,EAAA,CAAA,CAAE,MAAA,GACC,CAAA,CAAE,OAAO,IAAI,CAAA,GACb,CAAA,CAAE,SAAA,GACC,IAAA,CAAK,CAAA,CAAE,SAAS,CAAA,GACjB,QALG,EAMX,CACD,CAAA,GACC,MAAA,GACF,OAAO,IAAI,CAAA,mBAEXC,IAAAA,CAAAG,UAAA,EACG,QAAA,EAAA;AAAA,gBAAA,IAAA,CAAK,KAAA;AAAA,gCAEJJ,GAAAA;AAAA,kBAAC,KAAA;AAAA,kBAAA;AAAA,oBACC,KAAK,IAAA,CAAK,KAAA;AAAA,oBACV,GAAA,EAAI,EAAA;AAAA,oBACJ,SAAA,EAAU;AAAA;AAAA,iBACZ;AAAA,gCAEFC,IAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,gBAAA,EACd,QAAA,EAAA;AAAA,kCAAAD,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,gBAAA,EAAkB,eAAK,KAAA,EAAM,CAAA;AAAA,kBAC5C,IAAA,CAAK,+BACJA,GAAAA,CAAC,UAAK,SAAA,EAAU,8CAAA,EACb,eAAK,WAAA,EACR;AAAA,iBAAA,EAEJ;AAAA,eAAA,EACF;AAAA;AAAA;AAAA,SAEJ,EAAA,EApDO,IAAA,CAAK,GAqDd,CACD;AAAA;AAAA,KAEL;AAAA,IAGC,QAAA,IAAY,QAAQ,MAAA,GAAS,QAAA,oBAC5BA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,oBAAA,EACb,QAAA,kBAAAA,GAAAA;AAAA,MAAC,eAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAM,OAAA;AAAA,QACN,QAAA;AAAA,QACA,OAAO,OAAA,CAAQ,MAAA;AAAA,QACf,YAAA,EAAc,OAAA;AAAA,QACd,QAAA,EAAU;AAAA;AAAA,KACZ,EACF;AAAA,GAAA,EAEJ,CAAA;AAEJ;ACzWO,SAAS,WAAW,EAAA,EAUP;AAVO,EAAA,IAAA,EAAA,GAAA,EAAA,EACzB;AAAA,IAAA,GAAA;AAAA,IACA,GAAA,GAAM,EAAA;AAAA,IACN,UAAA;AAAA,IACA,OAAA,GAAU,IAAA;AAAA,IACV,YAAA,GAAe,IAAA;AAAA,IACf,WAAA,GAAc,iCAAA;AAAA,IACd,SAAA,GAAY,6EAAA;AAAA,IACZ;AAAA,GApDF,GA4C2B,EAAA,EAStB,KAAA,GAAA,SAAA,CATsB,EAAA,EAStB;AAAA,IARH,KAAA;AAAA,IACA,KAAA;AAAA,IACA,YAAA;AAAA,IACA,SAAA;AAAA,IACA,cAAA;AAAA,IACA,aAAA;AAAA,IACA,WAAA;AAAA,IACA;AAAA,GAAA,CAAA;AAGA,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAIG,SAAS,KAAK,CAAA;AAEtC,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAIA,SAAwB,IAAI,CAAA;AAC5D,EAAA,MAAM,OAAA,GAAU,CAAC,CAAC,GAAA,IAAO,QAAA,KAAa,GAAA;AAGtC,EAAA,IAAI,CAAC,OAAO,OAAA,EAAS;AACnB,IAAA,MAAM,GAAA,GAAM,CAAC,GAAA,GAAM,WAAA,GAAc,SAAA;AACjC,IAAA,uBACEF,IAAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,KAAA,EAAO,GAAA;AAAA,QACP,YAAA,EAAY,GAAA;AAAA,QACZ,SAAA,EAAW,EAAA;AAAA,UACT,kGAAA;AAAA,UACA;AAAA,SACF;AAAA,QAEA,QAAA,EAAA;AAAA,0BAAAD,GAAAA,CAAC,QAAA,EAAA,EAAS,SAAA,EAAU,iBAAA,EAAkB,CAAA;AAAA,0BACtCA,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,kEACb,QAAA,EAAA,GAAA,EACH;AAAA;AAAA;AAAA,KACF;AAAA,EAEJ;AAEA,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA;AAAA;AAAA,sBAEEA,GAAAA;AAAA,QAAC,KAAA;AAAA,QAAA,cAAA,CAAA;AAAA,UACC,GAAA;AAAA,UACA,GAAA;AAAA,UACA,OAAA,EAAS,MAAM,WAAA,CAAY,GAAG,CAAA;AAAA,UAC9B;AAAA,SAAA,EACI,KAAA;AAAA;AACN;AAAA,EAEJ;AAEA,EAAA,uBACEC,IAAAA,CAAAG,QAAAA,EAAA,EACE,QAAA,EAAA;AAAA,oBAAAH,IAAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,QAAA;AAAA,QACL,OAAA,EAAS,MAAM,OAAA,CAAQ,IAAI,CAAA;AAAA,QAC3B,SAAA,EAAU,gIAAA;AAAA,QACV,YAAA,EAAW,iCAAA;AAAA,QAGX,QAAA,EAAA;AAAA,0BAAAD,GAAAA;AAAA,YAAC,KAAA;AAAA,YAAA,cAAA,CAAA;AAAA,cACC,GAAA;AAAA,cACA,GAAA;AAAA,cACA,OAAA,EAAS,MAAM,WAAA,CAAY,GAAG,CAAA;AAAA,cAC9B,SAAA,EAAW,EAAA,CAAG,cAAA,EAAgB,SAAS;AAAA,aAAA,EACnC,KAAA;AAAA,WACN;AAAA,UACC,YAAA,oBACCA,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,6FAAA,EACd,QAAA,kBAAAA,GAAAA,CAACqC,MAAAA,EAAA,EAAO,SAAA,EAAU,QAAA,EAAS,CAAA,EAC7B;AAAA;AAAA;AAAA,KAEJ;AAAA,oBAEArC,GAAAA,CAAiBsC,cAAA,CAAA,IAAA,EAAhB,EAAqB,IAAA,EAAY,cAAc,OAAA,EAC9C,QAAA,kBAAArC,IAAAA,CAAiBqC,cAAA,CAAA,MAAA,EAAhB,EACC,QAAA,EAAA;AAAA,sBAAAtC,GAAAA,CAAiBsC,cAAA,CAAA,OAAA,EAAhB,EAAwB,SAAA,EAAU,wJAAA,EAAyJ,CAAA;AAAA,sBAC5LrC,IAAAA;AAAA,QAAiBqC,cAAA,CAAA,OAAA;AAAA,QAAhB;AAAA,UACC,OAAA,EAAS,MAAM,OAAA,CAAQ,KAAK,CAAA;AAAA,UAC5B,SAAA,EAAU,sEAAA;AAAA,UAEV,QAAA,EAAA;AAAA,4BAAAtC,GAAAA,CAAiBsC,cAAA,CAAA,KAAA,EAAhB,EAAsB,SAAA,EAAU,WAAU,QAAA,EAAA,8CAAA,EAE3C,CAAA;AAAA,4BAEAtC,GAAAA;AAAA,cAAC,KAAA;AAAA,cAAA;AAAA,gBACC,KAAK,UAAA,IAAA,IAAA,GAAA,UAAA,GAAc,GAAA;AAAA,gBACnB,GAAA;AAAA,gBACA,OAAA,EAAS,CAAC,CAAA,KAAM,CAAA,CAAE,eAAA,EAAgB;AAAA,gBAClC,SAAA,EAAU;AAAA;AAAA,aACZ;AAAA,4BACAC,IAAAA,CAAiBqC,cAAA,CAAA,KAAA,EAAhB,EAAsB,WAAU,+JAAA,EAC/B,QAAA,EAAA;AAAA,8BAAAtC,GAAAA,CAACgB,CAAAA,EAAA,EAAE,SAAA,EAAU,QAAA,EAAS,CAAA;AAAA,8BACtBhB,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,WAAU,QAAA,EAAA,cAAA,EAAE;AAAA,aAAA,EAC9B;AAAA;AAAA;AAAA;AACF,KAAA,EACF,CAAA,EACF;AAAA,GAAA,EACF,CAAA;AAEJ;ACvGA,SAAS,kBAAkB,OAAA,EAA6B;AACtD,EAAA,OACE,cAAA,CAAe,OAAO,CAAA,IACrB,OAAA,CAAQ,MAAiC,QAAA,KAAa,IAAA;AAE3D;AA4CO,SAAS,iBAAA,CAAkB;AAAA,EAChC,QAAQ,EAAC;AAAA,EACT,KAAA;AAAA,EACA,MAAA,GAAS,KAAA;AAAA,EACT,OAAA,GAAU,CAAA;AAAA,EACV,QAAA,GAAW,IAAA;AAAA,EACX,UAAA,GAAa,MAAA;AAAA,EACb,SAAA;AAAA,EACA,OAAA,GAAU,KAAA;AAAA,EACV;AACF,CAAA,EAA2B;AAlG3B,EAAA,IAAA,EAAA;AAmGE,EAAA,MAAM,OAAA,GAAU,wBACdA,GAAAA,CAAC,SAAI,SAAA,EAAU,4CAAA,EAA8C,iBAAM,CAAA,GACjE,IAAA;AAEJ,EAAA,IAAI,IAAA;AAGJ,EAAA,IAAI,QAAA,EAAU;AACZ,IAAA,IAAA,mBACEC,IAAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAW,EAAA;AAAA,UACT,QAAA,IAAY,qCAAA;AAAA,UACZ;AAAA,SACF;AAAA,QAEC,QAAA,EAAA;AAAA,UAAA,OAAA;AAAA,UACA;AAAA;AAAA;AAAA,KACH;AAAA,EAEJ,CAAA,MAAA,IAAW,WAAW,SAAA,EAAW;AAC/B,IAAA,IAAA,mBACEA,IAAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAW,EAAA;AAAA,UACT,QAAA,IAAY,qCAAA;AAAA,UACZ;AAAA,SACF;AAAA,QAEC,QAAA,EAAA;AAAA,UAAA,OAAA;AAAA,0BACDD,GAAAA;AAAA,YAAC,KAAA;AAAA,YAAA;AAAA,cACC,SAAA,EAAU,sBAAA;AAAA,cACV,KAAA,EAAO,EAAE,mBAAA,EAAqB,CAAA,OAAA,EAAU,OAAO,CAAA,iBAAA,CAAA,EAAoB;AAAA,cAElE,QAAA,EAAA,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,EAAM,CAAA,KAAM;AAnIlC,gBAAA,IAAAQ,GAAAA,EAAA,EAAA;AAoIY,gBAAA,MAAM,IAAA,GAAO,KAAK,GAAA,CAAA,CAAIA,GAAAA,GAAA,KAAK,IAAA,KAAL,IAAA,GAAAA,GAAAA,GAAa,CAAA,EAAG,OAAO,CAAA;AAC7C,gBAAA,uBACEP,IAAAA;AAAA,kBAAC,KAAA;AAAA,kBAAA;AAAA,oBAEC,KAAA,EAAO,OAAO,CAAA,GAAI,EAAE,YAAY,CAAA,KAAA,EAAQ,IAAI,IAAG,GAAI,MAAA;AAAA,oBAEnD,QAAA,EAAA;AAAA,sCAAAA,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,+BAAA,EACZ,QAAA,EAAA;AAAA,wBAAA,IAAA,CAAK,KAAA;AAAA,wBAAA,CAAA,CACJ,EAAA,GAAA,IAAA,CAAK,QAAA,KAAL,IAAA,GAAA,EAAA,GAAiB,iBAAA,CAAkB,IAAA,CAAK,OAAO,CAAA,qBAC/CD,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,yBAAA,EAA0B,QAAA,EAAA,GAAA,EAAC;AAAA,uBAAA,EAE/C,CAAA;AAAA,sCACAA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,8BAAA,EACZ,eAAK,OAAA,EACR;AAAA;AAAA,mBAAA;AAAA,kBAXK;AAAA,iBAYP;AAAA,cAEJ,CAAC;AAAA;AAAA;AACH;AAAA;AAAA,KACF;AAAA,EAEJ,CAAA,MAAO;AAIL,IAAA,MAAM,OAAmB,EAAC;AAC1B,IAAA,IAAI,MAAgB,EAAC;AACrB,IAAA,IAAI,IAAA,GAAO,CAAA;AACX,IAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,MAAA,MAAM,IAAA,GAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,GAAA,CAAA,CAAI,EAAA,GAAA,IAAA,CAAK,IAAA,KAAL,IAAA,GAAA,EAAA,GAAa,CAAA,EAAG,CAAC,CAAA,EAAG,OAAO,CAAA;AAE1D,MAAA,IAAI,IAAA,GAAO,OAAO,OAAA,EAAS;AACzB,QAAA,IAAI,GAAA,CAAI,QAAQ,GAAA,CAAI,GAAA,CAAI,SAAS,CAAC,CAAA,CAAE,QAAQ,OAAA,GAAU,IAAA;AACtD,QAAA,IAAA,CAAK,KAAK,GAAG,CAAA;AACb,QAAA,GAAA,GAAM,EAAC;AACP,QAAA,IAAA,GAAO,CAAA;AAAA,MACT;AACA,MAAA,GAAA,CAAI,IAAA,CAAK,aAAA,CAAA,cAAA,CAAA,EAAA,EAAK,IAAA,CAAA,EAAL,EAAW,MAAK,CAAC,CAAA;AAC1B,MAAA,IAAA,IAAQ,IAAA;AACR,MAAA,IAAI,SAAS,OAAA,EAAS;AACpB,QAAA,IAAA,CAAK,KAAK,GAAG,CAAA;AACb,QAAA,GAAA,GAAM,EAAC;AACP,QAAA,IAAA,GAAO,CAAA;AAAA,MACT;AAAA,IACF;AACA,IAAA,IAAI,IAAI,MAAA,EAAQ;AACd,MAAA,GAAA,CAAI,GAAA,CAAI,MAAA,GAAS,CAAC,CAAA,CAAE,QAAQ,OAAA,GAAU,IAAA;AACtC,MAAA,IAAA,CAAK,KAAK,GAAG,CAAA;AAAA,IACf;AAEA,IAAA,MAAM,UAAA,GAAa,WAAW,sBAAA,GAAyB,EAAA;AAEvD,IAAA,IAAA,mBACEC,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EACF,QAAA,EAAA;AAAA,MAAA,OAAA;AAAA,sBACDD,GAAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UACC,SAAA,EAAW,EAAA;AAAA,YACT,oCAAA;AAAA,YACA,CAAC,QAAA,IAAY;AAAA,WACf;AAAA,UAEA,QAAA,kBAAAA,IAAC,OAAA,EAAA,EAAM,SAAA,EAAU,0BACf,QAAA,kBAAAA,GAAAA,CAAC,WACE,QAAA,EAAA,IAAA,CAAK,GAAA,CAAI,CAAC,GAAA,EAAK,EAAA,qBACdA,GAAAA,CAAC,IAAA,EAAA,EACE,cAAI,GAAA,CAAI,CAAC,MAAM,EAAA,KAAI;AArMtC,YAAA,IAAAQ,GAAAA;AAsMoB,YAAA,uBAAAP,IAAAA,CAACG,YAAA,EACC,QAAA,EAAA;AAAA,8BAAAH,IAAAA;AAAA,gBAAC,IAAA;AAAA,gBAAA;AAAA,kBACC,KAAA,EAAM,KAAA;AAAA,kBACN,KAAA,EAAO,EAAE,KAAA,EAAO,UAAA,EAAW;AAAA,kBAC3B,SAAA,EAAW,EAAA;AAAA,oBACT,iEAAA;AAAA,oBACA,WAAW,UAAA,GAAa,UAAA;AAAA,oBACxB;AAAA,mBACF;AAAA,kBAEC,QAAA,EAAA;AAAA,oBAAA,IAAA,CAAK,KAAA;AAAA,oBAAA,CAAA,CACJO,GAAAA,GAAA,IAAA,CAAK,QAAA,KAAL,IAAA,GAAAA,MAAiB,iBAAA,CAAkB,IAAA,CAAK,OAAO,CAAA,qBAC/CR,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,2BAA0B,QAAA,EAAA,GAAA,EAAC;AAAA;AAAA;AAAA,eAE/C;AAAA,8BACAA,GAAAA;AAAA,gBAAC,IAAA;AAAA,gBAAA;AAAA,kBACC,OAAA,EAAS,IAAA,CAAK,IAAA,GAAO,CAAA,GAAI,CAAA;AAAA,kBACzB,SAAA,EAAW,EAAA;AAAA,oBACT,qCAAA;AAAA,oBACA,WAAW,SAAA,GAAY,UAAA;AAAA,oBACvB;AAAA,mBACF;AAAA,kBAEC,QAAA,EAAA,IAAA,CAAK;AAAA;AAAA;AACR,aAAA,EAAA,EAxBa,EAyBf,CAAA;AAAA,UAAA,CACD,CAAA,EAAA,EA5BM,EA6BT,CACD,CAAA,EACH,CAAA,EACF;AAAA;AAAA;AACF,KAAA,EACF,CAAA;AAAA,EAEJ;AAEA,EAAA,IAAI,CAAC,SAAS,OAAO,IAAA;AAErB,EAAA,uBACEC,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,UAAA,EACb,QAAA,EAAA;AAAA,oBAAAD,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gCAAA,EAAkC,QAAA,EAAA,IAAA,EAAK,CAAA;AAAA,oBACtDA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,mDAAA,EACb,QAAA,kBAAAA,GAAAA,CAACiB,OAAAA,EAAA,EAAQ,SAAA,EAAU,2CAAA,EAA4C,CAAA,EACjE;AAAA,GAAA,EACF,CAAA;AAEJ;ACxMA,IAAM,MAAA,GAAqC;AAAA,EACzC,IAAA,EAAM,8CAAA;AAAA,EACN,OAAA,EAAS,8CAAA;AAAA,EACT,KAAA,EACE,4HAAA;AAAA,EACF,GAAA,EAAK,oGAAA;AAAA,EACL,KAAA,EACE,gHAAA;AAAA,EACF,MAAA,EACE,sHAAA;AAAA,EACF,IAAA,EAAM;AACR,CAAA;AAEA,IAAMsB,KAAAA,GAAkC;AAAA,EACtC,EAAA,EAAI,wBAAA;AAAA,EACJ,EAAA,EAAI,kBAAA;AAAA,EACJ,EAAA,EAAI;AACN,CAAA;AAEO,SAASC,OAAM,EAAA,EAQP;AARO,EAAA,IAAA,EAAA,GAAA,EAAA,EACpB;AAAA,IAAA,IAAA;AAAA,IACA,QAAA;AAAA,IACA,KAAA,GAAQ,MAAA;AAAA,IACR,IAAA,GAAO,IAAA;AAAA,IACP,SAAA;AAAA,IACA;AAAA,GArEF,GA+DsB,EAAA,EAOjB,KAAA,GAAA,SAAA,CAPiB,EAAA,EAOjB;AAAA,IANH,MAAA;AAAA,IACA,UAAA;AAAA,IACA,OAAA;AAAA,IACA,MAAA;AAAA,IACA,WAAA;AAAA,IACA;AAAA,GAAA,CAAA;AAGA,EAAA,MAAM,WAAA,GAAc,OAAO,KAAmB,CAAA;AAC9C,EAAA,MAAM,QAAA,GAAW,QAAQ,WAAW,CAAA;AAIpC,EAAA,MAAM,WAAA,GAAyC,WAC3C,MAAA,GACA;AAAA,IACE,KAAA,EAAO,uBAAuB,KAAK,CAAA,YAAA,CAAA;AAAA,IACnC,eAAA,EAAiB,sBAAsB,KAAK,CAAA,kBAAA,CAAA;AAAA,IAC5C,WAAA,EAAa,sBAAsB,KAAK,CAAA,kBAAA;AAAA,GAC1C;AAEJ,EAAA,uBACExC,GAAAA;AAAA,IAAC,MAAA;AAAA,IAAA,aAAA,CAAA,cAAA,CAAA;AAAA,MACC,WAAA,EAAU,OAAA;AAAA,MACV,SAAA,EAAW,EAAA;AAAA,QACT,iGAAA;AAAA,QACAuC,MAAK,IAAI,CAAA;AAAA,QACT,QAAA,IAAY,WAAA;AAAA,QACZ;AAAA,OACF;AAAA,MACA,KAAA,EAAO,kCAAK,WAAA,CAAA,EAAgB,KAAA;AAAA,KAAA,EACxB,KAAA,CAAA,EATL;AAAA,MAWE,QAAA,EAAA,IAAA,IAAA,IAAA,GAAA,IAAA,GAAQ;AAAA,KAAA;AAAA,GACX;AAEJ;AC/CA,SAAS,SAAA,CAAU,GAAY,KAAA,EAAyB;AACpD,EAAA,IAAI,CAAC,OAAO,OAAO,CAAA;AACnB,EAAA,OAAO,MAAM,IAAA,IAAQ,CAAA,KAAM,MAAA,IAAa,CAAA,KAAM,KAAK,IAAA,GAAO,CAAA;AAC9D;AAOA,SAAS,aAAa,CAAA,EAAqB;AACvC,EAAA,IAAI,OAAO,CAAA,KAAM,QAAA,EAAU,OAAO,CAAA;AAClC,EAAA,MAAM,OAAA,GAAU,EAAE,IAAA,EAAK;AACvB,EAAA,IAAI,OAAA,CAAQ,CAAC,CAAA,KAAM,GAAA,IAAO,QAAQ,CAAC,CAAA,KAAM,KAAK,OAAO,CAAA;AACrD,EAAA,IAAI;AACA,IAAA,OAAO,IAAA,CAAK,MAAM,OAAO,CAAA;AAAA,EAC7B,CAAA,CAAA,OAAQ,CAAA,EAAA;AACJ,IAAA,OAAO,CAAA;AAAA,EACX;AACJ;AAEA,SAAS,SAAA,CAAU,CAAA,EAAY,CAAA,EAAY,YAAA,EAAgC;AACvE,EAAA,MAAM,EAAA,GAAK,SAAA,CAAU,CAAA,EAAG,YAAY,CAAA;AACpC,EAAA,MAAM,EAAA,GAAK,SAAA,CAAU,CAAA,EAAG,YAAY,CAAA;AAEpC,EAAA,IAAI,EAAA,KAAO,IAAI,OAAO,IAAA;AACtB,EAAA,IAAI,EAAA,KAAO,IAAA,IAAQ,EAAA,KAAO,IAAA,EAAM,OAAO,KAAA;AAQvC,EAAA,MAAM,EAAA,GAAK,aAAa,EAAE,CAAA;AAC1B,EAAA,MAAM,EAAA,GAAK,aAAa,EAAE,CAAA;AAC1B,EAAA,IAAI,EAAA,KAAO,IAAI,OAAO,IAAA;AAEtB,EAAA,IAAI,OAAO,EAAA,KAAO,QAAA,IAAY,OAAO,OAAO,QAAA,EAAU;AAClD,IAAA,OAAO,MAAA,CAAO,EAAE,CAAA,KAAM,MAAA,CAAO,EAAE,CAAA;AAAA,EACnC;AACA,EAAA,IAAI,OAAO,EAAA,KAAO,QAAA,IAAY,OAAO,EAAA,KAAO,UAAU,OAAO,KAAA;AAE7D,EAAA,IAAI,KAAA,CAAM,QAAQ,EAAE,CAAA,KAAM,MAAM,OAAA,CAAQ,EAAE,GAAG,OAAO,KAAA;AAEpD,EAAA,IAAI,MAAM,OAAA,CAAQ,EAAE,KAAK,KAAA,CAAM,OAAA,CAAQ,EAAE,CAAA,EAAG;AACxC,IAAA,IAAI,EAAA,CAAG,MAAA,KAAW,EAAA,CAAG,MAAA,EAAQ,OAAO,KAAA;AACpC,IAAA,OAAO,EAAA,CAAG,KAAA,CAAM,CAAC,CAAA,EAAG,CAAA,KAAM,SAAA,CAAU,CAAA,EAAG,EAAA,CAAG,CAAC,CAAA,EAAG,YAAY,CAAC,CAAA;AAAA,EAC/D;AAEA,EAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,IAAA,CAAK,EAAY,CAAA;AACtC,EAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,IAAA,CAAK,EAAY,CAAA;AACtC,EAAA,MAAM,OAAA,uBAAc,GAAA,CAAI,CAAC,GAAG,KAAA,EAAO,GAAG,KAAK,CAAC,CAAA;AAE5C,EAAA,KAAA,MAAW,KAAK,OAAA,EAAS;AACrB,IAAA,IAAI,CAAC,SAAA,CAAW,EAAA,CAAc,CAAC,CAAA,EAAI,GAAc,CAAC,CAAA,EAAG,YAAY,CAAA,EAAG,OAAO,KAAA;AAAA,EAC/E;AACA,EAAA,OAAO,IAAA;AACX;AA4BO,SAAS,aAAA,CACZ,QAAA,EACA,OAAA,EACA,OAAA,GAA6B,EAAC,EACX;AA/IvB,EAAA,IAAA,EAAA;AAgJI,EAAA,MAAM,YAAA,GAAA,CAAe,EAAA,GAAA,OAAA,CAAQ,cAAA,KAAR,IAAA,GAAA,EAAA,GAA0B,KAAA;AAE/C,EAAA,IAAI,CAAC,QAAA,EAAU;AACX,IAAA,OAAO,EAAE,SAAS,KAAA,EAAO,WAAA,EAAa,EAAC,EAAG,IAAA,EAAM,EAAC,EAAE;AAAA,EACvD;AAEA,EAAA,MAAM,cAAc,EAAC;AACrB,EAAA,MAAM,OAAO,EAAC;AAEd,EAAA,MAAM,IAAA,GAAO,MAAA,CAAO,IAAA,CAAK,OAAO,CAAA;AAEhC,EAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACpB,IAAA,IAAI,CAAC,UAAU,QAAA,CAAS,GAAG,GAAG,OAAA,CAAQ,GAAG,CAAA,EAAG,YAAY,CAAA,EAAG;AACvD,MAAA,WAAA,CAAY,GAAG,CAAA,GAAI,IAAA;AACnB,MAAA,IAAA,CAAK,GAAG,CAAA,GAAI,OAAA,CAAQ,GAAG,CAAA;AAAA,IAC3B;AAAA,EACJ;AAEA,EAAA,OAAO;AAAA,IACH,OAAA,EAAS,MAAA,CAAO,IAAA,CAAK,WAAW,EAAE,MAAA,GAAS,CAAA;AAAA,IAC3C,WAAA;AAAA,IACA;AAAA,GACJ;AACJ;AAQO,SAAS,aAAA,CACZ,QAAA,EACA,OAAA,EACA,OAAA,GAA6B,EAAC,EACX;AACnB,EAAA,OAAOlC,OAAAA;AAAA,IACH,MAAM,aAAA,CAAc,QAAA,EAAU,OAAA,EAAS,OAAO,CAAA;AAAA;AAAA;AAAA,IAG9C,CAAC,QAAA,EAAU,OAAA,EAAS,OAAA,CAAQ,cAAc;AAAA,GAC9C;AACJ;ACnIO,IAAM,kBAAA,GAAqB,CAAC,MAAA,KAAqC;AACpE,EAAA,MAAM,EAAE,eAAA,GAAkB,EAAA,EAAI,QAAA,EAAU,WAAA,GAAc,EAAC,EAAG,MAAA,GAAS,EAAC,EAAE,GAAI,MAAA;AAC1E,EAAA,MAAM,SAAS,SAAA,EAAU;AACzB,EAAA,MAAM,WAAW,WAAA,EAAY;AAC7B,EAAA,MAAM,eAAe,eAAA,EAAgB;AAErC,EAAA,MAAM,EAAE,cAAA,EAAgB,QAAA,EAAU,WAAA,EAAY,GAAIA,QAAQ,MAAM;AA7DpE,IAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA;AA8DQ,IAAA,MAAM,OAAO,MAAA,CAAA,CAAO,EAAA,GAAA,YAAA,CAAa,IAAI,MAAM,CAAA,KAAvB,YAA4B,GAAG,CAAA;AACnD,IAAA,MAAM,QAAA,GAAW,QAAO,EAAA,GAAA,YAAA,CAAa,GAAA,CAAI,UAAU,CAAA,KAA3B,IAAA,GAAA,EAAA,GAAgC,eAAA,CAAgB,QAAA,EAAU,CAAA;AAClF,IAAA,MAAM,OAAA,GAAA,CAAU,EAAA,GAAA,YAAA,CAAa,GAAA,CAAI,SAAS,MAA1B,IAAA,GAAA,EAAA,GAA+B,MAAA;AAC/C,IAAA,MAAM,QAAA,GAAA,CAAY,EAAA,GAAA,YAAA,CAAa,GAAA,CAAI,UAAU,MAA3B,IAAA,GAAA,EAAA,GAA0D,MAAA;AAC5E,IAAA,MAAM,WAAU,EAAA,GAAA,YAAA,CAAa,GAAA,CAAI,SAAS,CAAA,KAA1B,YAA+B,QAAA,CAAS,OAAA;AACxD,IAAA,MAAM,eAAc,EAAA,GAAA,YAAA,CAAa,GAAA,CAAI,aAAa,CAAA,KAA9B,YAAmC,QAAA,CAAS,WAAA;AAChE,IAAA,MAAM,aAAY,EAAA,GAAA,YAAA,CAAa,GAAA,CAAI,WAAW,CAAA,KAA5B,YAAiC,QAAA,CAAS,SAAA;AAC5D,IAAA,MAAM,WAAU,EAAA,GAAA,YAAA,CAAa,GAAA,CAAI,SAAS,CAAA,KAA1B,YAA+B,QAAA,CAAS,OAAA;AACxD,IAAA,MAAM,YAAW,EAAA,GAAA,YAAA,CAAa,GAAA,CAAI,UAAU,CAAA,KAA3B,YAAgC,QAAA,CAAS,QAAA;AAC1D,IAAA,MAAM,gBAAA,GAAmB,mBAAK,QAAA,CAAS,OAAA,CAAA;AACvC,IAAA,MAAA,CAAO,IAAA,CAAK,SAAS,OAAA,IAAW,EAAE,CAAA,CAAE,OAAA,CAAQ,CAAC,GAAA,KAAQ;AACjD,MAAA,MAAM,UAAA,GAAa,QAAA,CAAS,OAAA,CAAQ,GAAG,CAAA;AACvC,MAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,UAAU,CAAA,EAAG;AAC3B,QAAA,MAAM,GAAA,GAAM,YAAA,CAAa,MAAA,CAAO,GAAG,CAAA;AACnC,QAAA,IAAI,GAAA,CAAI,SAAS,CAAA,EAAG;AAChB,UAAA,gBAAA,CAAiB,GAAG,CAAA,GAAI,GAAA;AAAA,QAC5B;AAAA,MACJ,CAAA,MAAO;AACH,QAAA,MAAM,CAAA,GAAI,YAAA,CAAa,GAAA,CAAI,GAAG,CAAA;AAC9B,QAAA,IAAI,MAAM,IAAA,EAAM;AACZ,UAAA,gBAAA,CAAiB,GAAG,CAAA,GAAI,CAAA;AAAA,QAC5B;AAAA,MACJ;AAAA,IACJ,CAAC,CAAA;AACD,IAAA,OAAO;AAAA,MACH,cAAA,EAAgB,EAAE,IAAA,EAAM,QAAA,EAAS;AAAA,MACjC,QAAA,EAAU,EAAE,OAAA,EAAS,QAAA,EAAS;AAAA,MAC9B,WAAA,EAAa;AAAA,QACT,OAAA;AAAA,QACA,WAAA;AAAA,QACA,SAAA;AAAA,QACA,OAAA;AAAA,QACA,QAAA;AAAA,QACA,OAAA,EAAS;AAAA;AACb,KACJ;AAAA,EAEJ,GAAG,CAAC,YAAA,EAAc,MAAA,EAAQ,QAAA,EAAU,eAAe,CAAC,CAAA;AAEpD,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAIF,SAAyB,cAAc,CAAA;AAC3E,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAIA,SAAmB,QAAQ,CAAA;AACnD,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAIA,SAAqB,WAAW,CAAA;AAE9D,EAAA,MAAM,iBAAA,GAAoB,CACtB,cAAA,EACA,WAAA,EACA,QAAA,KACC;AACD,IAAA,MAAM,EAAA,GAAK,IAAI,eAAA,EAAgB;AAC/B,IAAA,EAAA,CAAG,GAAA,CAAI,MAAA,EAAQ,cAAA,CAAe,IAAA,CAAK,UAAU,CAAA;AAC7C,IAAA,EAAA,CAAG,GAAA,CAAI,UAAA,EAAY,cAAA,CAAe,QAAA,CAAS,UAAU,CAAA;AAGrD,IAAA,IAAI,YAAY,OAAA,EAAS,EAAA,CAAG,GAAA,CAAI,SAAA,EAAW,YAAY,OAAO,CAAA;AAC9D,IAAA,IAAI,YAAY,WAAA,EAAa,EAAA,CAAG,GAAA,CAAI,aAAA,EAAe,YAAY,WAAW,CAAA;AAC1E,IAAA,IAAI,YAAY,QAAA,EAAU,EAAA,CAAG,GAAA,CAAI,UAAA,EAAY,YAAY,QAAQ,CAAA;AACjE,IAAA,IAAI,YAAY,SAAA,EAAW,EAAA,CAAG,GAAA,CAAI,WAAA,EAAa,YAAY,SAAS,CAAA;AACpE,IAAA,IAAI,YAAY,OAAA,EAAS,EAAA,CAAG,GAAA,CAAI,SAAA,EAAW,YAAY,OAAO,CAAA;AAC9D,IAAA,MAAA,CAAO,OAAA,CAAQ,WAAA,CAAY,OAAA,IAAW,EAAE,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAC,GAAA,EAAK,KAAK,CAAA,KAAM;AAChE,MAAA,IAAI,KAAA,KAAU,MAAA,IAAa,KAAA,KAAU,IAAA,IAAQ,UAAU,EAAA,EAAI;AAC3D,MAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG;AACtB,QAAA,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA,KAAM,EAAA,CAAG,OAAO,GAAA,EAAK,MAAA,CAAO,CAAC,CAAC,CAAC,CAAA;AAAA,MAClD,CAAA,MAAO;AACH,QAAA,EAAA,CAAG,GAAA,CAAI,GAAA,EAAK,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,MAC7B;AAAA,IACJ,CAAC,CAAA;AAED,IAAA,IAAI,SAAS,OAAA,EAAS,EAAA,CAAG,GAAA,CAAI,SAAA,EAAW,SAAS,OAAO,CAAA;AACxD,IAAA,IAAI,SAAS,QAAA,EAAU,EAAA,CAAG,GAAA,CAAI,UAAA,EAAY,SAAS,QAAQ,CAAA;AAC3D,IAAA,IAAI,MAAA,EAAQ;AACR,MAAA,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAC,GAAA,EAAK,KAAK,CAAA,KAAM;AAC7C,QAAA,IAAI,KAAA,KAAU,MAAA,IAAa,KAAA,KAAU,IAAA,IAAQ,UAAU,EAAA,EAAI;AAC3D,QAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG;AACtB,UAAA,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA,KAAM,EAAA,CAAG,OAAO,GAAA,EAAK,MAAA,CAAO,CAAC,CAAC,CAAC,CAAA;AAAA,QAClD,CAAA,MAAO;AACH,UAAA,EAAA,CAAG,GAAA,CAAI,GAAA,EAAK,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,QAC7B;AAAA,MACJ,CAAC,CAAA;AAAA,IACL;AACA,IAAA,OAAO,EAAA;AAAA,EACX,CAAA;AAEA,EAAA,MAAM,OAAA,GAAU,CACZ,cAAA,EACA,WAAA,EACA,QAAA,KACC;AACD,IAAA,MAAM,EAAA,GAAK,iBAAA,CAAkB,cAAA,EAAgB,WAAA,EAAa,QAAQ,CAAA;AAClE,IAAA,MAAM,OAAO,CAAA,EAAG,QAAQ,CAAA,CAAA,EAAI,EAAA,CAAG,UAAU,CAAA,CAAA;AACzC,IAAA,MAAA,CAAO,OAAA,CAAQ,IAAA,EAAM,EAAE,MAAA,EAAQ,OAAO,CAAA;AAAA,EAC1C,CAAA;AAEA,EAAA,MAAM,oBAAA,GAAuB,CACzB,OAAA,KACC;AACD,IAAA,MAAM,OACF,OAAO,OAAA,KAAY,UAAA,GACZ,OAAA,CAAqD,UAAU,CAAA,GAChE,OAAA;AACV,IAAA,aAAA,CAAc,IAAI,CAAA;AAClB,IAAA,OAAA,CAAQ,IAAA,EAAM,SAAS,IAAI,CAAA;AAAA,EAC/B,CAAA;AAEA,EAAA,MAAM,iBAAA,GAAoB,CACtB,OAAA,KACC;AACD,IAAA,MAAM,OACF,OAAO,OAAA,KAAY,UAAA,GACZ,OAAA,CAA6C,OAAO,CAAA,GACrD,OAAA;AACV,IAAA,UAAA,CAAW,IAAI,CAAA;AACf,IAAA,OAAA,CAAQ,UAAA,EAAY,MAAM,IAAI,CAAA;AAAA,EAClC,CAAA;AAEA,EAAA,MAAM,cAAA,GAAiB,CAAC,OAAA,KAAuD;AAC3E,IAAA,MAAM,OACF,OAAO,OAAA,KAAY,UAAA,GACZ,OAAA,CAAyC,IAAI,CAAA,GAC9C,OAAA;AACV,IAAA,OAAA,CAAQ,IAAI,CAAA;AACZ,IAAA,OAAA,CAAQ,UAAA,EAAY,SAAS,IAAI,CAAA;AAAA,EACrC,CAAA;AAKA,EAAA,MAAM,eAAe,MAAM;AACvB,IAAA,MAAM,QAAoB,aAAA,CAAA,cAAA,CAAA,EAAA,EAAK,QAAA,CAAA,EAAL,EAAe,OAAA,EAAS,SAAS,OAAA,EAAQ,CAAA;AACnE,IAAA,MAAM,kBAAkB,EAAE,IAAA,EAAM,CAAA,EAAG,QAAA,EAAU,WAAW,QAAA,EAAS;AACjE,IAAA,UAAA,CAAW,KAAK,CAAA;AAChB,IAAA,aAAA,CAAc,eAAe,CAAA;AAC7B,IAAA,OAAA,CAAQ,WAAW,CAAA;AACnB,IAAA,OAAA,CAAQ,eAAA,EAAiB,OAAO,WAAW,CAAA;AAAA,EAC/C,CAAA;AAEA,EAAA,OAAO;AAAA,IACH,UAAA;AAAA,IACA,IAAA;AAAA,IACA,OAAA;AAAA;AAAA,IAGA,aAAA;AAAA,IACA,UAAA;AAAA,IACA,OAAA;AAAA;AAAA,IAGA,oBAAA;AAAA,IACA,iBAAA;AAAA,IACA,cAAA;AAAA,IAEA,YAAA;AAAA,IACA;AAAA,GACJ;AACJ","file":"index.mjs","sourcesContent":["import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * cn — Tailwind 클래스 병합 유틸리티\n *\n * clsx로 조건부 클래스를 합친 뒤 tailwind-merge로 중복/충돌 클래스를 정리한다.\n * (예: cn(\"px-2\", isActive && \"px-4\") => \"px-4\")\n *\n * @example\n * cn(\"rounded border\", isOpen && \"bg-accent\", className)\n */\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs));\n}\n","\"use client\";\n\n/**\n * useIsMobile — 현재 뷰포트가 모바일 크기인지 여부를 반환하는 훅.\n *\n * matchMedia로 브레이크포인트를 감지하며, 리사이즈에 반응한다.\n * 데스크탑/모바일 UI를 분기할 때 사용한다. (기본 768px 미만 = 모바일)\n *\n * @param breakpoint 모바일로 간주할 최대 px (기본 768)\n * @example\n * const isMobile = useIsMobile();\n * return isMobile ? <MobileNav /> : <DesktopNav />;\n */\nimport { useEffect, useState } from \"react\";\n\nexport function useIsMobile(breakpoint = 768) {\n  // SSR 단계에서는 undefined → 클라이언트 마운트 후 실제 값으로 결정한다.\n  const [isMobile, setIsMobile] = useState<boolean | undefined>(\n    undefined\n  );\n\n  useEffect(() => {\n    const mql = window.matchMedia(`(max-width: ${breakpoint - 1}px)`);\n    const onChange = () => setIsMobile(mql.matches);\n    onChange();\n    mql.addEventListener(\"change\", onChange);\n    return () => mql.removeEventListener(\"change\", onChange);\n  }, [breakpoint]);\n\n  return !!isMobile;\n}\n","\"use client\";\n\n/**\n * Sheet — 화면 가장자리에서 슬라이드되어 나오는 패널 (Radix Dialog 기반)\n *\n * 모바일 환경에서 사이드 메뉴/필터를 Drawer 형태로 띄울 때 사용한다.\n * side prop으로 등장 방향을 정한다. (top / right / bottom / left)\n *\n * @example\n * <Sheet open={open} onOpenChange={setOpen}>\n *   <SheetContent side=\"left\">\n *     <SheetHeader><SheetTitle>메뉴</SheetTitle></SheetHeader>\n *     ...\n *   </SheetContent>\n * </Sheet>\n */\nimport { type ComponentProps } from \"react\";\nimport * as SheetPrimitive from \"@radix-ui/react-dialog\";\nimport { XIcon } from \"lucide-react\";\n\nimport { cn } from \"../../lib/utils\";\n\nfunction Sheet(props: ComponentProps<typeof SheetPrimitive.Root>) {\n  return <SheetPrimitive.Root data-slot=\"sheet\" {...props} />;\n}\n\nfunction SheetTrigger(\n  props: ComponentProps<typeof SheetPrimitive.Trigger>\n) {\n  return <SheetPrimitive.Trigger data-slot=\"sheet-trigger\" {...props} />;\n}\n\nfunction SheetClose(props: ComponentProps<typeof SheetPrimitive.Close>) {\n  return <SheetPrimitive.Close data-slot=\"sheet-close\" {...props} />;\n}\n\nfunction SheetOverlay({\n  className,\n  ...props\n}: ComponentProps<typeof SheetPrimitive.Overlay>) {\n  return (\n    <SheetPrimitive.Overlay\n      data-slot=\"sheet-overlay\"\n      className={cn(\n        \"fixed inset-0 z-50 bg-black/50 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\",\n        className\n      )}\n      {...props}\n    />\n  );\n}\n\nfunction SheetContent({\n  className,\n  children,\n  side = \"right\",\n  closeClassName,\n  ...props\n}: ComponentProps<typeof SheetPrimitive.Content> & {\n  side?: \"top\" | \"right\" | \"bottom\" | \"left\";\n  /** 닫기(X) 버튼에 추가할 클래스 (예: 색칠한 헤더 위에서 text-primary-foreground) */\n  closeClassName?: string;\n}) {\n  return (\n    <SheetPrimitive.Portal data-slot=\"sheet-portal\">\n      <SheetOverlay />\n      <SheetPrimitive.Content\n        data-slot=\"sheet-content\"\n        className={cn(\n          \"bg-background fixed z-50 flex flex-col gap-4 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500\",\n          side === \"right\" &&\n            \"data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm\",\n          side === \"left\" &&\n            \"data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm\",\n          side === \"top\" &&\n            \"data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top inset-x-0 top-0 h-auto border-b\",\n          side === \"bottom\" &&\n            \"data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom inset-x-0 bottom-0 h-auto border-t\",\n          className\n        )}\n        {...props}\n      >\n        {children}\n        <SheetPrimitive.Close\n          className={cn(\n            \"ring-offset-background focus:ring-ring absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none\",\n            closeClassName\n          )}\n        >\n          <XIcon className=\"size-4\" />\n          <span className=\"sr-only\">닫기</span>\n        </SheetPrimitive.Close>\n      </SheetPrimitive.Content>\n    </SheetPrimitive.Portal>\n  );\n}\n\nfunction SheetHeader({ className, ...props }: ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"sheet-header\"\n      className={cn(\"flex flex-col gap-1.5 p-4\", className)}\n      {...props}\n    />\n  );\n}\n\nfunction SheetFooter({ className, ...props }: ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"sheet-footer\"\n      className={cn(\"mt-auto flex flex-col gap-2 p-4\", className)}\n      {...props}\n    />\n  );\n}\n\nfunction SheetTitle({\n  className,\n  ...props\n}: ComponentProps<typeof SheetPrimitive.Title>) {\n  return (\n    <SheetPrimitive.Title\n      data-slot=\"sheet-title\"\n      className={cn(\"text-foreground font-semibold\", className)}\n      {...props}\n    />\n  );\n}\n\nfunction SheetDescription({\n  className,\n  ...props\n}: ComponentProps<typeof SheetPrimitive.Description>) {\n  return (\n    <SheetPrimitive.Description\n      data-slot=\"sheet-description\"\n      className={cn(\"text-muted-foreground text-sm\", className)}\n      {...props}\n    />\n  );\n}\n\nexport {\n  Sheet,\n  SheetTrigger,\n  SheetClose,\n  SheetContent,\n  SheetHeader,\n  SheetFooter,\n  SheetTitle,\n  SheetDescription,\n};\n","\"use client\";\n\n/**\n * Tooltip — 마우스 오버 시 나타나는 설명 (Radix Tooltip 기반)\n *\n * 사이드바를 아이콘만 보이도록 접었을 때 메뉴 라벨을 보여주는 용도로 사용한다.\n * 앱 루트에서 TooltipProvider로 한 번 감싸면 하위 Tooltip이 동작한다.\n *\n * @example\n * <Tooltip>\n *   <TooltipTrigger asChild><button>?</button></TooltipTrigger>\n *   <TooltipContent>도움말</TooltipContent>\n * </Tooltip>\n */\nimport { type ComponentProps } from \"react\";\nimport * as TooltipPrimitive from \"@radix-ui/react-tooltip\";\n\nimport { cn } from \"../../lib/utils\";\n\nfunction TooltipProvider({\n  delayDuration = 0,\n  ...props\n}: ComponentProps<typeof TooltipPrimitive.Provider>) {\n  return (\n    <TooltipPrimitive.Provider\n      data-slot=\"tooltip-provider\"\n      delayDuration={delayDuration}\n      {...props}\n    />\n  );\n}\n\nfunction Tooltip(props: ComponentProps<typeof TooltipPrimitive.Root>) {\n  return (\n    <TooltipProvider>\n      <TooltipPrimitive.Root data-slot=\"tooltip\" {...props} />\n    </TooltipProvider>\n  );\n}\n\nfunction TooltipTrigger(\n  props: ComponentProps<typeof TooltipPrimitive.Trigger>\n) {\n  return <TooltipPrimitive.Trigger data-slot=\"tooltip-trigger\" {...props} />;\n}\n\nfunction TooltipContent({\n  className,\n  sideOffset = 4,\n  children,\n  ...props\n}: ComponentProps<typeof TooltipPrimitive.Content>) {\n  return (\n    <TooltipPrimitive.Portal>\n      <TooltipPrimitive.Content\n        data-slot=\"tooltip-content\"\n        sideOffset={sideOffset}\n        className={cn(\n          \"bg-primary text-primary-foreground z-50 w-fit rounded-md px-3 py-1.5 text-xs text-balance data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95\",\n          className\n        )}\n        {...props}\n      >\n        {children}\n        <TooltipPrimitive.Arrow className=\"bg-primary fill-primary z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]\" />\n      </TooltipPrimitive.Content>\n    </TooltipPrimitive.Portal>\n  );\n}\n\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };\n","\"use client\";\n\n/**\n * Avatar — 사용자 프로필 이미지 (Radix Avatar 기반)\n *\n * 이미지 로드 실패 시 AvatarFallback(이니셜 등)을 표시한다.\n *\n * @example\n * <Avatar>\n *   <AvatarImage src={user.avatarUrl} alt={user.name} />\n *   <AvatarFallback>{user.name.slice(0, 2)}</AvatarFallback>\n * </Avatar>\n */\nimport { type ComponentProps } from \"react\";\nimport * as AvatarPrimitive from \"@radix-ui/react-avatar\";\n\nimport { cn } from \"../../lib/utils\";\n\nfunction Avatar({\n  className,\n  ...props\n}: ComponentProps<typeof AvatarPrimitive.Root>) {\n  return (\n    <AvatarPrimitive.Root\n      data-slot=\"avatar\"\n      className={cn(\n        \"relative flex size-8 shrink-0 overflow-hidden rounded-full\",\n        className\n      )}\n      {...props}\n    />\n  );\n}\n\nfunction AvatarImage({\n  className,\n  ...props\n}: ComponentProps<typeof AvatarPrimitive.Image>) {\n  return (\n    <AvatarPrimitive.Image\n      data-slot=\"avatar-image\"\n      className={cn(\"aspect-square size-full\", className)}\n      {...props}\n    />\n  );\n}\n\nfunction AvatarFallback({\n  className,\n  ...props\n}: ComponentProps<typeof AvatarPrimitive.Fallback>) {\n  return (\n    <AvatarPrimitive.Fallback\n      data-slot=\"avatar-fallback\"\n      className={cn(\n        \"bg-muted flex size-full items-center justify-center rounded-full text-xs font-medium\",\n        className\n      )}\n      {...props}\n    />\n  );\n}\n\nexport { Avatar, AvatarImage, AvatarFallback };\n","\"use client\";\n\n/**\n * Button — shadcn/ui 기반 버튼 프리미티브\n *\n * variant: 시각 스타일 (default / destructive / outline / secondary / ghost / link)\n * size: 크기 (default / sm / lg / icon)\n * asChild: true 이면 <button> 대신 자식 엘리먼트(예: <a>, <Link>)에 스타일을 입힌다.\n * loading: true 이면 스피너를 표시하고 버튼을 자동으로 비활성화한다.\n *\n * @example\n * <Button>저장</Button>\n * <Button variant=\"outline\" size=\"sm\">취소</Button>\n * <Button loading={isSaving}>저장 중</Button>\n * <Button disabled>비활성</Button>\n * <Button asChild><Link href=\"/new\">등록</Link></Button>\n */\nimport { type ComponentProps } from \"react\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { Loader2 } from \"lucide-react\";\n\nimport { cn } from \"../../lib/utils\";\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:ring-ring/50 focus-visible:ring-[3px] focus-visible:border-ring aria-invalid:ring-destructive/20 aria-invalid:border-destructive\",\n  {\n    variants: {\n      variant: {\n        default:\n          \"bg-primary text-primary-foreground shadow-xs hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-destructive-foreground shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20\",\n        outline:\n          \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground\",\n        secondary:\n          \"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80\",\n        ghost: \"hover:bg-accent hover:text-accent-foreground\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-10 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5\",\n        lg: \"h-12 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-10\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n);\n\nfunction Button({\n    className,\n    variant,\n    size,\n    asChild = false,\n    loading = false,\n    disabled,\n    children,\n    ...props\n}: ComponentProps<\"button\"> &\n    VariantProps<typeof buttonVariants> & {\n        asChild?: boolean;\n        /** true 이면 스피너를 표시하고 버튼을 자동 비활성화 */\n        loading?: boolean;\n    }) {\n    const Comp = asChild ? Slot : \"button\";\n    return (\n        <Comp\n            data-slot=\"button\"\n            disabled={disabled || loading}\n            className={cn(buttonVariants({ variant, size, className }))}\n            {...props}\n        >\n            {loading && <Loader2 className=\"animate-spin\" />}\n            {children}\n        </Comp>\n    );\n}\n\nexport { Button, buttonVariants };\n","\"use client\";\n\n/**\n * DropdownMenu — 클릭 시 펼쳐지는 메뉴 (Radix DropdownMenu 기반)\n *\n * 헤더의 사용자 메뉴(프로필/로그아웃 등)에 사용한다.\n *\n * @example\n * <DropdownMenu>\n *   <DropdownMenuTrigger asChild><Button>메뉴</Button></DropdownMenuTrigger>\n *   <DropdownMenuContent>\n *     <DropdownMenuLabel>내 계정</DropdownMenuLabel>\n *     <DropdownMenuSeparator />\n *     <DropdownMenuItem onSelect={logout}>로그아웃</DropdownMenuItem>\n *   </DropdownMenuContent>\n * </DropdownMenu>\n */\nimport { type ComponentProps } from \"react\";\nimport * as DropdownMenuPrimitive from \"@radix-ui/react-dropdown-menu\";\n\nimport { cn } from \"../../lib/utils\";\n\nfunction DropdownMenu(\n  props: ComponentProps<typeof DropdownMenuPrimitive.Root>\n) {\n  return <DropdownMenuPrimitive.Root data-slot=\"dropdown-menu\" {...props} />;\n}\n\nfunction DropdownMenuTrigger(\n  props: ComponentProps<typeof DropdownMenuPrimitive.Trigger>\n) {\n  return (\n    <DropdownMenuPrimitive.Trigger\n      data-slot=\"dropdown-menu-trigger\"\n      {...props}\n    />\n  );\n}\n\nfunction DropdownMenuContent({\n  className,\n  sideOffset = 4,\n  ...props\n}: ComponentProps<typeof DropdownMenuPrimitive.Content>) {\n  return (\n    <DropdownMenuPrimitive.Portal>\n      <DropdownMenuPrimitive.Content\n        data-slot=\"dropdown-menu-content\"\n        sideOffset={sideOffset}\n        className={cn(\n          \"bg-popover text-popover-foreground z-50 min-w-[8rem] overflow-hidden rounded-md border p-1 shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95\",\n          className\n        )}\n        {...props}\n      />\n    </DropdownMenuPrimitive.Portal>\n  );\n}\n\nfunction DropdownMenuItem({\n  className,\n  inset,\n  variant = \"default\",\n  ...props\n}: ComponentProps<typeof DropdownMenuPrimitive.Item> & {\n  inset?: boolean;\n  variant?: \"default\" | \"destructive\";\n}) {\n  return (\n    <DropdownMenuPrimitive.Item\n      data-slot=\"dropdown-menu-item\"\n      data-inset={inset}\n      data-variant={variant}\n      className={cn(\n        \"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0\",\n        className\n      )}\n      {...props}\n    />\n  );\n}\n\nfunction DropdownMenuLabel({\n  className,\n  inset,\n  ...props\n}: ComponentProps<typeof DropdownMenuPrimitive.Label> & {\n  inset?: boolean;\n}) {\n  return (\n    <DropdownMenuPrimitive.Label\n      data-slot=\"dropdown-menu-label\"\n      data-inset={inset}\n      className={cn(\n        \"px-2 py-1.5 text-sm font-medium data-[inset]:pl-8\",\n        className\n      )}\n      {...props}\n    />\n  );\n}\n\nfunction DropdownMenuSeparator({\n  className,\n  ...props\n}: ComponentProps<typeof DropdownMenuPrimitive.Separator>) {\n  return (\n    <DropdownMenuPrimitive.Separator\n      data-slot=\"dropdown-menu-separator\"\n      className={cn(\"bg-border -mx-1 my-1 h-px\", className)}\n      {...props}\n    />\n  );\n}\n\nexport {\n  DropdownMenu,\n  DropdownMenuTrigger,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuLabel,\n  DropdownMenuSeparator,\n};\n","\"use client\";\n\n/**\n * Separator — 영역을 구분하는 구분선 (Radix Separator 기반)\n *\n * orientation: 방향 (horizontal / vertical)\n *\n * @example\n * <Separator />\n * <Separator orientation=\"vertical\" className=\"h-6\" />\n */\nimport { type ComponentProps } from \"react\";\nimport * as SeparatorPrimitive from \"@radix-ui/react-separator\";\n\nimport { cn } from \"../../lib/utils\";\n\nfunction Separator({\n  className,\n  orientation = \"horizontal\",\n  decorative = true,\n  ...props\n}: ComponentProps<typeof SeparatorPrimitive.Root>) {\n  return (\n    <SeparatorPrimitive.Root\n      data-slot=\"separator\"\n      decorative={decorative}\n      orientation={orientation}\n      className={cn(\n        \"bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px\",\n        className\n      )}\n      {...props}\n    />\n  );\n}\n\nexport { Separator };\n","\"use client\";\n\n/**\n * AdminLayout 내부에서 사이드바/헤더가 공유하는 상태 컨텍스트.\n *\n * - collapsed: 데스크탑 사이드바 접힘(아이콘 전용) 여부\n * - mobileOpen: 모바일 Drawer(Sheet) 열림 여부\n * - isMobile: 현재 모바일 뷰포트 여부\n *\n * 직접 사용하기보다 useAdminLayout() 훅으로 접근한다.\n */\nimport { type ReactNode, createContext, useContext } from \"react\";\n\ninterface AdminLayoutContextValue {\n  collapsed: boolean;\n  setCollapsed: (v: boolean) => void;\n  toggleCollapsed: () => void;\n  mobileOpen: boolean;\n  setMobileOpen: (v: boolean) => void;\n  isMobile: boolean;\n}\n\nconst AdminLayoutContext = createContext<AdminLayoutContextValue | null>(\n  null\n);\n\nexport function useAdminLayout() {\n  const ctx = useContext(AdminLayoutContext);\n  if (!ctx) {\n    throw new Error(\"useAdminLayout 은 <AdminLayout> 내부에서만 사용할 수 있습니다.\");\n  }\n  return ctx;\n}\n\nexport function AdminLayoutProvider({\n  value,\n  children,\n}: {\n  value: AdminLayoutContextValue;\n  children: ReactNode;\n}) {\n  return (\n    <AdminLayoutContext.Provider value={value}>\n      {children}\n    </AdminLayoutContext.Provider>\n  );\n}\n","\"use client\";\n\n/**\n * AdminHeader — 관리자 상단 헤더\n *\n * - 모바일: 좌측 햄버거 버튼으로 사이드 메뉴 Drawer 를 연다.\n * - 데스크탑: 사이드바 접기/펼치기 토글 버튼을 제공한다.\n * - 우측에는 사용자 지정 액션(actions)과 사용자 메뉴(user)를 배치한다.\n *\n * 비즈니스 로직(로그아웃 처리 등)은 콜백(onLogout)으로 외부에서 주입한다.\n *\n * @example\n * <AdminHeader title=\"대시보드\" user={user} onLogout={signOut} />\n *\n * @example\n * // 헤더 색 커스터마이징 + 프로필 클릭 시 이동\n * <AdminHeader\n *   user={user}\n *   theme={{ background: \"#111827\", foreground: \"#fff\" }}\n *   profileHref=\"/profile\"\n *   LinkComponent={Link}\n *   onLogout={signOut}\n * />\n */\nimport { type CSSProperties, type ElementType, type ReactNode, useState } from \"react\";\nimport { ChevronDown, LogOut, Menu, PanelLeft, User } from \"lucide-react\";\n\nimport { cn } from \"../../lib/utils\";\nimport type { AdminUser, HeaderTheme, LinkComponent } from \"../../types\";\nimport { Avatar, AvatarFallback, AvatarImage } from \"../ui/avatar\";\nimport { Button } from \"../ui/button\";\nimport {\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuLabel,\n  DropdownMenuSeparator,\n  DropdownMenuTrigger,\n} from \"../ui/dropdown-menu\";\nimport { Separator } from \"../ui/separator\";\nimport { useAdminLayout } from \"./admin-layout-context\";\n\n/** HeaderTheme 값을 헤더 루트에 적용할 인라인 style 로 변환한다. 지정한 값만 덮어쓴다. */\nfunction headerThemeToStyle(theme?: HeaderTheme): CSSProperties {\n  if (!theme) return {};\n  const style: CSSProperties = {};\n  if (theme.background) style.backgroundColor = theme.background;\n  if (theme.foreground) style.color = theme.foreground;\n  if (theme.border) style.borderColor = theme.border;\n  return style;\n}\n\nexport interface AdminHeaderProps {\n  /** 헤더 좌측 타이틀 (페이지명 등) */\n  title?: ReactNode;\n  /** 로그인 사용자 정보. 있으면 우측에 사용자 메뉴를 표시한다 */\n  user?: AdminUser;\n  /** 사용자 메뉴 우측에 추가로 배치할 액션 (알림, 테마 토글 등) */\n  actions?: ReactNode;\n  /** 로그아웃 클릭 콜백 */\n  onLogout?: () => void;\n  /** 사용자 드롭다운에 추가할 커스텀 메뉴 항목. 지정하지 않으면 profileHref 로 이동하는 기본 \"프로필\" 항목을 보여준다 */\n  userMenuItems?: ReactNode;\n  /** 기본 \"프로필\" 메뉴 클릭 시 이동할 경로. userMenuItems 를 직접 넘기면 무시된다 */\n  profileHref?: string;\n  /** 라우팅 링크 컴포넌트 (Next.js: next/link 의 Link, 기본: <a>) */\n  LinkComponent?: LinkComponent;\n  /** 헤더 색상 테마. 지정하지 않으면 기본 색상(bg-muted/60)을 사용한다 */\n  theme?: HeaderTheme;\n  className?: string;\n}\n\n/** 이름에서 아바타 폴백용 이니셜을 만든다. */\nfunction initials(name: string) {\n  return name\n    .trim()\n    .split(/\\s+/)\n    .slice(0, 2)\n    .map((w) => w[0]?.toUpperCase() ?? \"\")\n    .join(\"\");\n}\n\nexport function AdminHeader({\n  title,\n  user,\n  actions,\n  onLogout,\n  userMenuItems,\n  profileHref,\n  LinkComponent,\n  theme,\n  className,\n}: AdminHeaderProps) {\n  const { isMobile, setMobileOpen, toggleCollapsed } = useAdminLayout();\n  const [userMenuOpen, setUserMenuOpen] = useState(false);\n  const Link = (LinkComponent ?? \"a\") as ElementType;\n\n  return (\n    <header\n      style={headerThemeToStyle(theme)}\n      className={cn(\n        \"sticky top-0 z-30 flex h-14 shrink-0 items-center gap-2 border-b bg-muted/60 px-4\",\n        className\n      )}\n    >\n      {isMobile ? (\n        <Button\n          variant=\"ghost\"\n          size=\"icon\"\n          aria-label=\"메뉴 열기\"\n          onClick={() => setMobileOpen(true)}\n        >\n          <Menu className=\"size-5\" />\n        </Button>\n      ) : (\n        <Button\n          variant=\"ghost\"\n          size=\"icon\"\n          aria-label=\"사이드바 토글\"\n          onClick={toggleCollapsed}\n        >\n          <PanelLeft className=\"size-5\" />\n        </Button>\n      )}\n\n      {title != null && (\n        <>\n          <Separator orientation=\"vertical\" className=\"mr-1 h-6\" />\n          <div className=\"text-base font-semibold\">{title}</div>\n        </>\n      )}\n\n      <div className=\"ml-auto flex items-center gap-2\">\n        {actions}\n        {user && (\n          <DropdownMenu open={userMenuOpen} onOpenChange={setUserMenuOpen}>\n            <DropdownMenuTrigger asChild>\n              <Button\n                variant=\"ghost\"\n                className=\"h-9 gap-2 px-1.5 sm:pr-3\"\n                aria-label=\"사용자 메뉴\"\n              >\n                <Avatar>\n                  {user.avatarUrl && (\n                    <AvatarImage src={user.avatarUrl} alt={user.name} />\n                  )}\n                  <AvatarFallback className=\"bg-black font-bold text-white\">\n                    {initials(user.name)}\n                  </AvatarFallback>\n                </Avatar>\n                <span className=\"hidden text-left text-sm leading-tight sm:block\">\n                  <span className=\"block font-medium\">{user.name}</span>\n                  {user.role && (\n                    <span className=\"block text-xs text-muted-foreground\">\n                      {user.role}\n                    </span>\n                  )}\n                </span>\n                <ChevronDown\n                  className={cn(\n                    \"size-4 shrink-0 text-muted-foreground transition-transform\",\n                    userMenuOpen && \"rotate-180\"\n                  )}\n                />\n              </Button>\n            </DropdownMenuTrigger>\n            <DropdownMenuContent align=\"end\" className=\"min-w-48\">\n              <DropdownMenuLabel>\n                <div className=\"flex flex-col\">\n                  <span>{user.name}</span>\n                  {user.email && (\n                    <span className=\"text-xs font-normal text-muted-foreground\">\n                      {user.email}\n                    </span>\n                  )}\n                </div>\n              </DropdownMenuLabel>\n              <DropdownMenuSeparator />\n              {userMenuItems ??\n                (profileHref ? (\n                  <DropdownMenuItem asChild>\n                    <Link href={profileHref}>\n                      <User className=\"size-4\" />\n                      프로필\n                    </Link>\n                  </DropdownMenuItem>\n                ) : (\n                  <DropdownMenuItem>\n                    <User className=\"size-4\" />\n                    프로필\n                  </DropdownMenuItem>\n                ))}\n              {onLogout && (\n                <>\n                  <DropdownMenuSeparator />\n                  <DropdownMenuItem variant=\"destructive\" onSelect={onLogout}>\n                    <LogOut className=\"size-4\" />\n                    로그아웃\n                  </DropdownMenuItem>\n                </>\n              )}\n            </DropdownMenuContent>\n          </DropdownMenu>\n        )}\n      </div>\n    </header>\n  );\n}\n","\"use client\";\n\n/**\n * AdminSidebar — 관리자 사이드 메뉴\n *\n * 도메인에 종속되지 않도록 메뉴 구성(nav)과 현재 경로(pathname)를 props로 주입받는다.\n * 라우팅은 LinkComponent 주입으로 처리한다. (Next.js: next/link 의 Link, 기본값: <a>)\n *\n * - NavItem[] 또는 NavGroup[] 둘 다 받는다.\n * - 하위 메뉴(items)가 있으면 접고 펼 수 있는 그룹으로 렌더링한다.\n * - collapsed=true 이면 아이콘 전용 모드로 축소되고 라벨은 Tooltip 으로 보여준다.\n *\n * @example\n * <AdminSidebar nav={nav} pathname={pathname} LinkComponent={Link} logo={<Logo/>} />\n */\nimport { type CSSProperties, type ElementType, type ReactNode, useState } from \"react\";\nimport { ChevronRight } from \"lucide-react\";\n\nimport { cn } from \"../../lib/utils\";\nimport type {\n  LinkComponent,\n  NavGroup,\n  NavItem,\n  SidebarTheme,\n} from \"../../types\";\nimport {\n  Tooltip,\n  TooltipContent,\n  TooltipTrigger,\n} from \"../ui/tooltip\";\n\n/**\n * SidebarTheme 값을 사이드바 루트에 적용할 CSS 변수 스타일로 변환한다.\n * 지정한 값만 덮어쓰고, 나머지는 전역 --sidebar* 기본값을 사용한다.\n */\nexport function sidebarThemeToStyle(\n  theme?: SidebarTheme\n): CSSProperties {\n  if (!theme) return {};\n  const style: Record<string, string> = {};\n  if (theme.background) style[\"--sidebar\"] = theme.background;\n  if (theme.foreground) style[\"--sidebar-foreground\"] = theme.foreground;\n  if (theme.accent) style[\"--sidebar-accent\"] = theme.accent;\n  if (theme.accentForeground)\n    style[\"--sidebar-accent-foreground\"] = theme.accentForeground;\n  if (theme.border) style[\"--sidebar-border\"] = theme.border;\n  if (theme.primary) style[\"--sidebar-primary\"] = theme.primary;\n  if (theme.primaryForeground)\n    style[\"--sidebar-primary-foreground\"] = theme.primaryForeground;\n  if (theme.ring) style[\"--sidebar-ring\"] = theme.ring;\n  return style as CSSProperties;\n}\n\nexport interface AdminSidebarProps {\n  /** 메뉴 구성. 평면 항목 배열 또는 그룹 배열 */\n  nav: NavItem[] | NavGroup[];\n  /** 현재 활성 경로 (Next.js: usePathname()) */\n  pathname?: string;\n  /** 라우팅 링크 컴포넌트 (기본: <a>) */\n  LinkComponent?: LinkComponent;\n  /**\n   * 상단 로고/브랜드 영역.\n   * 함수를 넘기면 접힘 상태(collapsed)를 인자로 받아 다르게 렌더링할 수 있다.\n   * (예: 펼침=풀네임, 접힘=아이콘/이니셜)\n   */\n  logo?: ReactNode | ((collapsed: boolean) => ReactNode);\n  /** 하단 고정 영역 (예: 버전, 사용자 요약) */\n  footer?: ReactNode;\n  /** 아이콘 전용 축소 모드 */\n  collapsed?: boolean;\n  /** 메뉴 클릭(이동) 시 콜백. 모바일에서 Drawer 닫기 등에 사용 */\n  onNavigate?: () => void;\n  /** 사이드바 색상 테마 (프로젝트별 컬러 주입) */\n  theme?: SidebarTheme;\n  className?: string;\n  style?: CSSProperties;\n}\n\n/**\n * nav prop을 항상 NavGroup[] 형태로 정규화한다.\n *\n * 정적 섹션 그룹(NavGroup)과 클릭해서 펼치는 대메뉴(items 를 가진 NavItem)는\n * 구조가 비슷하므로 다음 규칙으로 구분한다:\n * - 최상위 항목이 모두 \"items 가 있고 / href 없고 / icon 없는\" 순수 섹션이면 NavGroup[] 로 본다.\n * - 그 외(아이콘이 있거나 링크 항목이 섞여 있으면)는 평면 NavItem[] 로 보고\n *   라벨 없는 단일 그룹으로 감싼다. → 아이콘 있는 대메뉴는 접이식으로 렌더링된다.\n */\nfunction normalizeGroups(nav: NavItem[] | NavGroup[]): NavGroup[] {\n  if (nav.length === 0) return [];\n  const looksLikeGroups = nav.every(\n    (entry) =>\n      Array.isArray((entry as NavGroup).items) &&\n      (entry as NavItem).href === undefined &&\n      (entry as NavItem).icon === undefined\n  );\n  if (looksLikeGroups) return nav as NavGroup[];\n  return [{ items: nav as NavItem[] }];\n}\n\n/** 해당 항목(또는 하위 항목)이 현재 경로와 매칭되는지 판단 */\nfunction isItemActive(item: NavItem, pathname?: string): boolean {\n  if (!pathname) return false;\n  if (item.href) {\n    if (item.exact) return pathname === item.href;\n    if (pathname === item.href) return true;\n    if (item.href !== \"/\" && pathname.startsWith(item.href + \"/\")) return true;\n  }\n  return item.items?.some((child) => isItemActive(child, pathname)) ?? false;\n}\n\nconst linkBaseClass =\n  \"group/menu flex items-center gap-3 rounded-md px-3 py-2 text-sm font-medium text-sidebar-foreground/80 transition-colors hover:bg-sidebar-accent hover:text-sidebar-accent-foreground outline-none focus-visible:ring-2 focus-visible:ring-sidebar-ring\";\nconst linkActiveClass =\n  \"bg-sidebar-accent text-sidebar-accent-foreground font-semibold\";\n\nfunction Badge({ value }: { value: string | number }) {\n  return (\n    <span className=\"ml-auto inline-flex h-5 min-w-5 items-center justify-center rounded-full bg-primary px-1.5 text-xs font-medium text-primary-foreground\">\n      {value}\n    </span>\n  );\n}\n\n/** 단일 링크 항목 */\nfunction SidebarLink({\n  item,\n  pathname,\n  LinkComponent,\n  collapsed,\n  onNavigate,\n  nested,\n}: {\n  item: NavItem;\n  pathname?: string;\n  LinkComponent?: LinkComponent;\n  collapsed?: boolean;\n  onNavigate?: () => void;\n  nested?: boolean;\n}) {\n  const active = isItemActive(item, pathname);\n  const Icon = item.icon;\n  const Link = (LinkComponent ?? \"a\") as ElementType;\n\n  const content = (\n    <>\n      {Icon ? <Icon className=\"size-4 shrink-0\" /> : null}\n      {!collapsed && <span className=\"truncate\">{item.title}</span>}\n      {!collapsed && item.badge != null && <Badge value={item.badge} />}\n    </>\n  );\n\n  const className = cn(\n    linkBaseClass,\n    nested && !collapsed && \"pl-9 text-[13px]\",\n    collapsed && \"justify-center px-2\",\n    active && linkActiveClass,\n    item.disabled && \"pointer-events-none opacity-50\"\n  );\n\n  const linkEl = item.href ? (\n    <Link\n      href={item.href}\n      className={className}\n      aria-current={active ? \"page\" : undefined}\n      onClick={onNavigate}\n    >\n      {content}\n    </Link>\n  ) : (\n    <span className={className}>{content}</span>\n  );\n\n  // 축소 모드에서는 라벨을 Tooltip 으로 표시한다.\n  if (collapsed && item.icon) {\n    return (\n      <Tooltip>\n        <TooltipTrigger asChild>{linkEl}</TooltipTrigger>\n        <TooltipContent side=\"right\">{item.title}</TooltipContent>\n      </Tooltip>\n    );\n  }\n  return linkEl;\n}\n\n/** 하위 메뉴를 가진 접이식 그룹 항목 */\nfunction SidebarCollapsible({\n  item,\n  pathname,\n  LinkComponent,\n  onNavigate,\n}: {\n  item: NavItem;\n  pathname?: string;\n  LinkComponent?: LinkComponent;\n  onNavigate?: () => void;\n}) {\n  const active = isItemActive(item, pathname);\n  const Icon = item.icon;\n\n  // 사용자가 직접 토글하기 전에는 활성 상태(active)에 따라 자동으로 펼친다.\n  // (effect 로 동기화하지 않고 파생값으로 계산해 불필요한 재렌더를 피한다.)\n  const [userOpen, setUserOpen] = useState<boolean | null>(null);\n  const open = userOpen ?? active;\n\n  return (\n    <li>\n      <button\n        type=\"button\"\n        onClick={() => setUserOpen(!open)}\n        aria-expanded={open}\n        className={cn(linkBaseClass, \"w-full\", active && \"text-sidebar-foreground\")}\n      >\n        {Icon ? <Icon className=\"size-4 shrink-0\" /> : null}\n        <span className=\"truncate\">{item.title}</span>\n        <ChevronRight\n          className={cn(\n            \"ml-auto size-4 shrink-0 transition-transform\",\n            open && \"rotate-90\"\n          )}\n        />\n      </button>\n      {open && (\n        <ul className=\"mt-1 space-y-1\">\n          {item.items!.map((child) => (\n            <li key={child.title}>\n              <SidebarLink\n                item={child}\n                pathname={pathname}\n                LinkComponent={LinkComponent}\n                onNavigate={onNavigate}\n                nested\n              />\n            </li>\n          ))}\n        </ul>\n      )}\n    </li>\n  );\n}\n\nexport function AdminSidebar({\n  nav,\n  pathname,\n  LinkComponent,\n  logo,\n  footer,\n  collapsed = false,\n  onNavigate,\n  theme,\n  className,\n  style,\n}: AdminSidebarProps) {\n  const groups = normalizeGroups(nav);\n  const resolvedLogo = typeof logo === \"function\" ? logo(collapsed) : logo;\n\n  return (\n    <div\n      style={{ ...sidebarThemeToStyle(theme), ...style }}\n      className={cn(\n        \"flex h-full flex-col bg-sidebar text-sidebar-foreground\",\n        className\n      )}\n    >\n      {resolvedLogo != null && (\n        <div\n          className={cn(\n            \"flex h-14 shrink-0 items-center gap-2 overflow-hidden px-4\",\n            collapsed && \"justify-center px-3\"\n          )}\n        >\n          {resolvedLogo}\n        </div>\n      )}\n\n      <nav className=\"flex-1 overflow-y-auto px-2 py-3\">\n        {groups.map((group, gi) => (\n          <div key={group.title ?? gi} className={cn(gi > 0 && \"mt-4\")}>\n            {group.title && !collapsed && (\n              <p className=\"px-3 pb-1.5 text-xs font-semibold uppercase tracking-wider text-sidebar-foreground/50\">\n                {group.title}\n              </p>\n            )}\n            <ul className=\"space-y-1\">\n              {group.items.map((item) =>\n                item.items && item.items.length > 0 && !collapsed ? (\n                  <SidebarCollapsible\n                    key={item.title}\n                    item={item}\n                    pathname={pathname}\n                    LinkComponent={LinkComponent}\n                    onNavigate={onNavigate}\n                  />\n                ) : (\n                  <li key={item.title}>\n                    <SidebarLink\n                      item={item}\n                      pathname={pathname}\n                      LinkComponent={LinkComponent}\n                      collapsed={collapsed}\n                      onNavigate={onNavigate}\n                    />\n                  </li>\n                )\n              )}\n            </ul>\n          </div>\n        ))}\n      </nav>\n\n      {footer != null && (\n        <div className=\"shrink-0 border-t border-sidebar-border p-3\">\n          {footer}\n        </div>\n      )}\n    </div>\n  );\n}\n","\"use client\";\n\n/**\n * AdminContainer — 관리자 통합 컨테이너 (반응형 자동 전환)\n *\n * - 데스크탑: 좌측 사이드바 + 헤더\n * - 모바일: 상단 헤더 + 햄버거 Drawer\n * 뷰포트 너비에 따라 자동으로 전환된다.\n *\n * nav 없이 사용하면 순수 컨테이너로 동작 (로그인 페이지 등).\n * maxWidth 로 모바일 웹뷰 너비를 제한할 수 있다.\n *\n * @example\n * // app/layout.tsx — 로그인 포함 모든 페이지 (모바일 너비 제한)\n * <AdminContainer maxWidth={430}>{children}</AdminContainer>\n *\n * @example\n * // app/(admin)/layout.tsx — 관리자 레이아웃\n * <AdminContainer\n *   nav={nav}\n *   pathname={pathname}\n *   LinkComponent={Link}\n *   user={user}\n *   onLogout={() => signOut()}\n * >\n *   {children}\n * </AdminContainer>\n */\nimport { type CSSProperties, type ReactNode, useMemo, useState } from \"react\";\n\nimport { cn } from \"../../lib/utils\";\nimport type {\n  AdminUser,\n  HeaderTheme,\n  LinkComponent,\n  NavGroup,\n  NavItem,\n  SidebarTheme,\n} from \"../../types\";\nimport { useIsMobile } from \"../../hooks/use-is-mobile\";\nimport { Sheet, SheetContent, SheetTitle } from \"../ui/sheet\";\nimport { TooltipProvider } from \"../ui/tooltip\";\nimport { AdminHeader } from \"./admin-header\";\nimport { AdminLayoutProvider } from \"./admin-layout-context\";\nimport { AdminSidebar, sidebarThemeToStyle } from \"./admin-sidebar\";\n\nexport interface AdminContainerProps {\n  // ── 컨테이너 옵션 ──────────────────────────────────────────────────────────\n  /** 최대 너비 (px 또는 CSS 값). 모바일 웹뷰 너비 제한 시 사용. */\n  maxWidth?: number | string;\n  /** 컨테이너 클래스 */\n  containerClassName?: string;\n\n  // ── 메뉴/헤더 (nav 없으면 순수 컨테이너로 동작) ────────────────────────────\n  /** 사이드 메뉴 구성. 없으면 메뉴/헤더를 렌더하지 않는다. */\n  nav?: NavItem[] | NavGroup[];\n  /** 현재 활성 경로 (Next.js: usePathname()) */\n  pathname?: string;\n  /** 라우팅 링크 컴포넌트 */\n  LinkComponent?: LinkComponent;\n  /** 사이드바 로고/브랜드 영역 */\n  logo?: ReactNode | ((collapsed: boolean) => ReactNode);\n  /** 사이드바 하단 고정 영역 */\n  sidebarFooter?: ReactNode;\n  /** 사이드바 색상 테마 */\n  sidebarTheme?: SidebarTheme;\n\n  /** 헤더 타이틀 */\n  title?: ReactNode;\n  /** 로그인 사용자 정보 */\n  user?: AdminUser;\n  /** 헤더 우측 추가 액션 */\n  headerActions?: ReactNode;\n  /** 로그아웃 콜백 */\n  onLogout?: () => void;\n  /** 사용자 드롭다운 커스텀 항목 */\n  userMenuItems?: ReactNode;\n  /** 기본 \"프로필\" 메뉴 클릭 시 이동할 경로 */\n  profileHref?: string;\n  /** 헤더 색상 테마 */\n  headerTheme?: HeaderTheme;\n  /** 기본 헤더 대신 완전히 커스텀한 헤더 */\n  header?: ReactNode;\n\n  /** 초기 사이드바 접힘 상태 */\n  defaultCollapsed?: boolean;\n  /** 본문 영역 클래스 */\n  contentClassName?: string;\n\n  children: ReactNode;\n}\n\nexport function AdminContainer({\n  maxWidth,\n  containerClassName,\n  nav,\n  pathname,\n  LinkComponent,\n  logo,\n  sidebarFooter,\n  sidebarTheme,\n  title,\n  user,\n  headerActions,\n  onLogout,\n  userMenuItems,\n  profileHref,\n  headerTheme,\n  header,\n  defaultCollapsed = false,\n  contentClassName,\n  children,\n}: AdminContainerProps) {\n  const isMobile = useIsMobile();\n  const [collapsed, setCollapsed] = useState(defaultCollapsed);\n  const [mobileOpen, setMobileOpen] = useState(false);\n\n  const ctxValue = useMemo(\n    () => ({\n      collapsed,\n      setCollapsed,\n      toggleCollapsed: () => setCollapsed((v) => !v),\n      mobileOpen,\n      setMobileOpen,\n      isMobile,\n    }),\n    [collapsed, mobileOpen, isMobile]\n  );\n\n  const containerStyle: CSSProperties =\n    maxWidth != null\n      ? typeof maxWidth === \"number\"\n        ? { maxWidth: `${maxWidth}px` }\n        : { maxWidth }\n      : {};\n\n  // nav 없으면 순수 컨테이너 — 로그인 페이지 등\n  if (!nav) {\n    return (\n      <div\n        style={containerStyle}\n        className={cn(\n          maxWidth != null && \"mx-auto\",\n          \"min-h-screen w-full\",\n          containerClassName\n        )}\n      >\n        {children}\n      </div>\n    );\n  }\n\n  // nav 있으면 풀 관리자 레이아웃\n  return (\n    <div\n      style={containerStyle}\n      className={cn(maxWidth != null && \"mx-auto\", \"w-full\", containerClassName)}\n    >\n      <TooltipProvider>\n        <AdminLayoutProvider value={ctxValue}>\n          <div className=\"flex min-h-screen w-full bg-background\">\n            {/* 데스크탑 사이드바 */}\n            {!isMobile && (\n              <aside\n                data-collapsed={collapsed}\n                style={sidebarThemeToStyle(sidebarTheme)}\n                className={cn(\n                  \"sticky top-0 h-screen shrink-0 border-r border-sidebar-border transition-[width] duration-200\",\n                  collapsed ? \"w-16\" : \"w-64\"\n                )}\n              >\n                <AdminSidebar\n                  nav={nav}\n                  pathname={pathname}\n                  LinkComponent={LinkComponent}\n                  logo={logo}\n                  footer={collapsed ? undefined : sidebarFooter}\n                  collapsed={collapsed}\n                  theme={sidebarTheme}\n                />\n              </aside>\n            )}\n\n            {/* 모바일 Drawer */}\n            <Sheet open={isMobile && mobileOpen} onOpenChange={setMobileOpen}>\n              <SheetContent side=\"left\" className=\"w-72 p-0\">\n                <SheetTitle className=\"sr-only\">사이드 메뉴</SheetTitle>\n                <AdminSidebar\n                  nav={nav}\n                  pathname={pathname}\n                  LinkComponent={LinkComponent}\n                  logo={logo}\n                  footer={sidebarFooter}\n                  theme={sidebarTheme}\n                  onNavigate={() => setMobileOpen(false)}\n                />\n              </SheetContent>\n            </Sheet>\n\n            {/* 본문 컬럼 */}\n            <div className=\"flex min-w-0 flex-1 flex-col\">\n              {header ?? (\n                <AdminHeader\n                  title={title}\n                  user={user}\n                  actions={headerActions}\n                  onLogout={onLogout}\n                  userMenuItems={userMenuItems}\n                  profileHref={profileHref}\n                  LinkComponent={LinkComponent}\n                  theme={headerTheme}\n                />\n              )}\n              <main\n                className={cn(\n                  \"flex-1 bg-muted/40 px-4 py-4 sm:px-8 sm:py-6\",\n                  contentClassName\n                )}\n              >\n                {children}\n              </main>\n            </div>\n          </div>\n        </AdminLayoutProvider>\n      </TooltipProvider>\n    </div>\n  );\n}\n","\"use client\";\n\n/**\n * AdminLayout — 관리자 페이지 메뉴 + 헤더 레이아웃\n *\n * `type` prop 으로 데스크탑/모바일 레이아웃을 명시적으로 지정한다.\n * - `\"desktop\"` : 좌측 고정 사이드바 + 상단 헤더. 사이드바 접기/펼치기 가능.\n * - `\"mobile\"`  : 사이드바 없이 상단 헤더 + 햄버거 Drawer 메뉴.\n * - 미지정      : useIsMobile() 결과에 따라 자동 전환 (반응형).\n *\n * 페이지 전체 모바일 너비 제한이 필요하면 루트 layout.tsx 에서\n * MobileContainer 로 감싼다. (AdminLayout 과 별개로 동작)\n *\n * @example\n * // 데스크탑 관리자\n * <AdminLayout type=\"desktop\" nav={nav} pathname={pathname} LinkComponent={Link}>\n *   {children}\n * </AdminLayout>\n *\n * @example\n * // 모바일 웹뷰 관리자 (루트에 MobileContainer 적용 후)\n * <AdminLayout type=\"mobile\" nav={nav} pathname={pathname} LinkComponent={Link}>\n *   {children}\n * </AdminLayout>\n */\nimport { type ReactNode, useMemo, useState } from \"react\";\n\nimport { cn } from \"../../lib/utils\";\nimport type {\n  AdminUser,\n  HeaderTheme,\n  LinkComponent,\n  NavGroup,\n  NavItem,\n  SidebarTheme,\n} from \"../../types\";\nimport { useIsMobile } from \"../../hooks/use-is-mobile\";\nimport { Sheet, SheetContent, SheetTitle } from \"../ui/sheet\";\nimport { TooltipProvider } from \"../ui/tooltip\";\nimport { AdminHeader } from \"./admin-header\";\nimport { AdminLayoutProvider } from \"./admin-layout-context\";\nimport { AdminSidebar, sidebarThemeToStyle } from \"./admin-sidebar\";\n\nexport interface AdminLayoutProps {\n  /**\n   * 레이아웃 모드.\n   * - `\"desktop\"` : 사이드바 + 헤더 (PC 관리자 페이지)\n   * - `\"mobile\"`  : 헤더 + 햄버거 Drawer (모바일 웹뷰)\n   * - 미지정      : 뷰포트 너비에 따라 자동 전환 (반응형)\n   */\n  type?: \"desktop\" | \"mobile\";\n  /** 사이드 메뉴 구성 */\n  nav: NavItem[] | NavGroup[];\n  /** 현재 활성 경로 (Next.js: usePathname()) */\n  pathname?: string;\n  /** 라우팅 링크 컴포넌트 (Next.js: next/link 의 Link, 기본: <a>) */\n  LinkComponent?: LinkComponent;\n  /**\n   * 사이드바 상단 로고/브랜드 영역.\n   * 함수를 넘기면 접힘 상태(collapsed)를 받아 다르게 렌더링할 수 있다.\n   */\n  logo?: ReactNode | ((collapsed: boolean) => ReactNode);\n  /** 사이드바 하단 고정 영역 */\n  sidebarFooter?: ReactNode;\n  /** 사이드바 색상 테마 */\n  sidebarTheme?: SidebarTheme;\n\n  /** 헤더 타이틀 */\n  title?: ReactNode;\n  /** 로그인 사용자 정보 */\n  user?: AdminUser;\n  /** 헤더 우측 추가 액션 */\n  headerActions?: ReactNode;\n  /** 로그아웃 콜백 */\n  onLogout?: () => void;\n  /** 사용자 드롭다운 커스텀 항목 */\n  userMenuItems?: ReactNode;\n  /** 기본 \"프로필\" 메뉴 클릭 시 이동할 경로 */\n  profileHref?: string;\n  /** 헤더 색상 테마 */\n  headerTheme?: HeaderTheme;\n  /** 기본 AdminHeader 대신 완전히 커스텀한 헤더를 쓸 때 */\n  header?: ReactNode;\n\n  /** 초기 사이드바 접힘 상태 (데스크탑 전용) */\n  defaultCollapsed?: boolean;\n  /** 본문 영역 컨테이너 클래스 */\n  contentClassName?: string;\n  children: ReactNode;\n}\n\nexport function AdminLayout({\n  type,\n  nav,\n  pathname,\n  LinkComponent,\n  logo,\n  sidebarFooter,\n  sidebarTheme,\n  title,\n  user,\n  headerActions,\n  onLogout,\n  userMenuItems,\n  profileHref,\n  headerTheme,\n  header,\n  defaultCollapsed = false,\n  contentClassName,\n  children,\n}: AdminLayoutProps) {\n  const isMobileViewport = useIsMobile();\n  const [collapsed, setCollapsed] = useState(defaultCollapsed);\n  const [mobileOpen, setMobileOpen] = useState(false);\n\n  // type prop 으로 강제 지정하거나 뷰포트로 자동 결정\n  const isMobile =\n    type === \"mobile\" ? true : type === \"desktop\" ? false : isMobileViewport;\n\n  const ctxValue = useMemo(\n    () => ({\n      collapsed,\n      setCollapsed,\n      toggleCollapsed: () => setCollapsed((v) => !v),\n      mobileOpen,\n      setMobileOpen,\n      isMobile,\n    }),\n    [collapsed, mobileOpen, isMobile]\n  );\n\n  return (\n    <TooltipProvider>\n      <AdminLayoutProvider value={ctxValue}>\n        <div className=\"flex min-h-screen w-full bg-background\">\n          {/* 데스크탑 사이드바 */}\n          {!isMobile && (\n            <aside\n              data-collapsed={collapsed}\n              style={sidebarThemeToStyle(sidebarTheme)}\n              className={cn(\n                \"sticky top-0 h-screen shrink-0 border-r border-sidebar-border transition-[width] duration-200\",\n                collapsed ? \"w-16\" : \"w-64\"\n              )}\n            >\n              <AdminSidebar\n                nav={nav}\n                pathname={pathname}\n                LinkComponent={LinkComponent}\n                logo={logo}\n                footer={collapsed ? undefined : sidebarFooter}\n                collapsed={collapsed}\n                theme={sidebarTheme}\n              />\n            </aside>\n          )}\n\n          {/* 모바일 Drawer — isMobile 일 때만 렌더 */}\n          <Sheet open={isMobile && mobileOpen} onOpenChange={setMobileOpen}>\n            <SheetContent side=\"left\" className=\"w-72 p-0\">\n              <SheetTitle className=\"sr-only\">사이드 메뉴</SheetTitle>\n              <AdminSidebar\n                nav={nav}\n                pathname={pathname}\n                LinkComponent={LinkComponent}\n                logo={logo}\n                footer={sidebarFooter}\n                theme={sidebarTheme}\n                onNavigate={() => setMobileOpen(false)}\n              />\n            </SheetContent>\n          </Sheet>\n\n          {/* 본문 컬럼 */}\n          <div className=\"flex min-w-0 flex-1 flex-col\">\n            {header ?? (\n              <AdminHeader\n                title={title}\n                user={user}\n                actions={headerActions}\n                onLogout={onLogout}\n                userMenuItems={userMenuItems}\n                profileHref={profileHref}\n                LinkComponent={LinkComponent}\n                theme={headerTheme}\n              />\n            )}\n            <main\n              className={cn(\n                \"flex-1 bg-muted/40 px-4 py-4 sm:px-8 sm:py-6\",\n                contentClassName\n              )}\n            >\n              {children}\n            </main>\n          </div>\n        </div>\n      </AdminLayoutProvider>\n    </TooltipProvider>\n  );\n}\n","\"use client\";\n\n/**\n * MobileContainer — 모바일 웹뷰용 뷰포트 컨테이너\n *\n * 루트 layout.tsx 에서 감싸면 로그인 페이지를 포함한 모든 페이지가\n * 모바일 너비로 제한된다. AdminLayout 과 별개로 동작하므로 함께 사용할 수 있다.\n *\n * @example\n * // app/layout.tsx\n * import { MobileContainer } from \"@sunkim4638/admin-modules\";\n *\n * export default function RootLayout({ children }) {\n *   return (\n *     <html>\n *       <body>\n *         <MobileContainer>{children}</MobileContainer>\n *       </body>\n *     </html>\n *   );\n * }\n *\n * // app/(admin)/layout.tsx\n * import { AdminLayout } from \"@sunkim4638/admin-modules\";\n *\n * export default function AdminLayoutWrapper({ children }) {\n *   return (\n *     <AdminLayout type=\"mobile\" nav={nav} ...>\n *       {children}\n *     </AdminLayout>\n *   );\n * }\n */\nimport type { CSSProperties, ReactNode } from \"react\";\n\nimport { cn } from \"../../lib/utils\";\n\nexport interface MobileContainerProps {\n  children: ReactNode;\n  /** 최대 너비 (px 또는 CSS 값). 기본 430px */\n  maxWidth?: number | string;\n  className?: string;\n}\n\nexport function MobileContainer({\n  children,\n  maxWidth = 430,\n  className,\n}: MobileContainerProps) {\n  const style: CSSProperties =\n    typeof maxWidth === \"number\"\n      ? { maxWidth: `${maxWidth}px` }\n      : { maxWidth };\n\n  return (\n    <div\n      className={cn(\"relative mx-auto min-h-screen w-full\", className)}\n      style={style}\n    >\n      {children}\n    </div>\n  );\n}\n","/**\n * AdminThemeProvider — 프로젝트 테마(주조색 등)를 한 곳에서 주입 (우선순위: 프로젝트별 컬러)\n *\n * primary 한 값만 바꾸면 이 라이브러리의 모든 컴포넌트(버튼·체크박스·툴팁·배지·\n * 페이지네이션 활성·텍스트 선택색 등)의 포인트 색이 함께 바뀐다.\n * 내부적으로 CSS 변수(--primary 등)를 :root 에 주입하므로, portal 로 뜨는\n * 모달/드로어/툴팁까지 동일하게 적용된다.\n *\n * 상호작용이 없어 서버 컴포넌트로 동작하며 SSR 시에도 깜빡임이 없다.\n * 보통 루트 레이아웃(app/layout.tsx)이나 (admin) 레이아웃 최상단에서 감싼다.\n *\n * @example\n * // app/layout.tsx 또는 app/(admin)/layout.tsx\n * <AdminThemeProvider primary=\"#4f46e5\">\n *   {children}\n * </AdminThemeProvider>\n *\n * @example\n * // 색·대비·포커스링까지 지정\n * <AdminThemeProvider primary=\"oklch(0.55 0.2 264)\" primaryForeground=\"#fff\" ring=\"#4f46e5\">\n *   {children}\n * </AdminThemeProvider>\n */\nimport type { ReactNode } from \"react\";\n\nexport interface AdminThemeProviderProps {\n  /** 주조색. 버튼/체크박스/배지/툴팁 등 포인트 색 (CSS 색상 문자열) */\n  primary?: string;\n  /** 주조색 위 글자색 (기본은 흰색 계열 유지) */\n  primaryForeground?: string;\n  /** 포커스 링 색. 주조색과 맞추고 싶을 때 지정 */\n  ring?: string;\n  /** 추가로 덮어쓸 임의의 CSS 변수 (예: { \"--radius\": \"0.5rem\" }) */\n  vars?: Record<string, string>;\n  children: ReactNode;\n}\n\nexport function AdminThemeProvider({\n  primary,\n  primaryForeground,\n  ring,\n  vars,\n  children,\n}: AdminThemeProviderProps) {\n  const decls = [\n    primary && `--primary:${primary};`,\n    primaryForeground && `--primary-foreground:${primaryForeground};`,\n    ring && `--ring:${ring};`,\n    ...Object.entries(vars ?? {}).map(([k, v]) => `${k}:${v};`),\n  ]\n    .filter(Boolean)\n    .join(\"\");\n\n  return (\n    <>\n      {decls && <style>{`:root{${decls}}`}</style>}\n      {children}\n    </>\n  );\n}\n","/**\n * AdminPage / AdminPageHeader — 본문 공통 컴포넌트 (우선순위 4: 페이지 타이틀 영역)\n *\n * 페이지명(타이틀), 설명, 우측 액션 버튼, 그리고 본문 간격을 자동으로 잡아준다.\n * 상위 layout 의 <main> 이 바깥 padding 을 담당하고, 이 컴포넌트는 그 안의\n * 세로 간격(space-y)과 헤더 레이아웃을 책임진다.\n *\n * 상호작용이 없으므로 서버 컴포넌트로 동작한다. (각 page.tsx 에서 바로 사용 가능)\n *\n * @example\n * // 올인원 사용\n * <AdminPage title=\"회원 관리\" description=\"가입 회원을 관리합니다\" actions={<Button>회원 등록</Button>}>\n *   ...본문...\n * </AdminPage>\n *\n * @example\n * // 헤더만 따로 쓰기\n * <AdminPageHeader title=\"대시보드\" />\n */\nimport { type ReactNode } from \"react\";\n\nimport { cn } from \"../../lib/utils\";\n\nexport interface AdminPageHeaderProps {\n  /** 페이지명 */\n  title: ReactNode;\n  /** 타이틀 아래 보조 설명 */\n  description?: ReactNode;\n  /** 우측 정렬 액션 영역 (등록/수정 버튼 등) */\n  actions?: ReactNode;\n  /** 타이틀 위 브레드크럼/뒤로가기 등 */\n  breadcrumb?: ReactNode;\n  className?: string;\n}\n\nexport function AdminPageHeader({\n  title,\n  description,\n  actions,\n  breadcrumb,\n  className,\n}: AdminPageHeaderProps) {\n    return (\n        <div className={cn(\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\", className)}>\n            <div className=\"space-y-1\">\n                {breadcrumb}\n                <h1 className=\"text-2xl font-semibold tracking-tight\">{title}</h1>\n                {description && (\n                <p className=\"text-sm text-muted-foreground\">{description}</p>\n                )}\n            </div>\n            {actions && (\n                <div className=\"flex shrink-0 items-center gap-2\">{actions}</div>\n            )}\n        </div>\n    );\n}\n\nexport interface AdminPageProps extends AdminPageHeaderProps {\n  children: ReactNode;\n  /** 헤더와 본문을 감싸는 바깥 컨테이너 클래스 */\n  className?: string;\n  /** 본문 영역 클래스 */\n  contentClassName?: string;\n}\n\nexport function AdminPage({\n  title,\n  description,\n  actions,\n  breadcrumb,\n  className,\n  contentClassName,\n  children,\n}: AdminPageProps) {\n  return (\n    <div className={cn(\"space-y-6\", className)}>\n      <AdminPageHeader\n        title={title}\n        description={description}\n        actions={actions}\n        breadcrumb={breadcrumb}\n      />\n      <div className={contentClassName}>{children}</div>\n    </div>\n  );\n}\n","/**\n * 공통 포맷 유틸리티\n *\n * 표 컬럼의 type 으로도 쓰이지만, 독립 함수라 어디서든 import 해서 재사용할 수 있다.\n *\n * @example\n * import { comma, tel, bizNum } from \"@linkup/admin-ui\";\n * comma(1234567)        // \"1,234,567\"\n * tel(\"01012345678\")    // \"010-1234-5678\"\n * bizNum(\"1234567890\")  // \"123-45-67890\"\n */\n\ntype Numeric = number | string | null | undefined;\n\n/** 숫자에 천 단위 콤마를 넣는다. (소수점은 유지) */\nexport function comma(value: Numeric): string {\n  if (value === null || value === undefined || value === \"\") return \"\";\n  const num =\n    typeof value === \"number\"\n      ? value\n      : Number(String(value).replace(/,/g, \"\"));\n  if (!Number.isFinite(num)) return String(value);\n  return num.toLocaleString(\"en-US\", { maximumFractionDigits: 20 });\n}\n\n/** 전화번호에 하이픈을 넣는다. (휴대폰 · 서울(02) · 지역번호 · 대표번호 대응) */\nexport function tel(value: Numeric): string {\n  if (value === null || value === undefined || value === \"\") return \"\";\n  const d = String(value).replace(/\\D/g, \"\");\n\n  // 서울 지역번호 02\n  if (d.startsWith(\"02\")) {\n    if (d.length === 9) return d.replace(/(\\d{2})(\\d{3})(\\d{4})/, \"$1-$2-$3\");\n    if (d.length === 10) return d.replace(/(\\d{2})(\\d{4})(\\d{4})/, \"$1-$2-$3\");\n  }\n  // 대표번호 등 8자리 (1588-1234)\n  if (d.length === 8) return d.replace(/(\\d{4})(\\d{4})/, \"$1-$2\");\n  // 10자리: 0XX-XXX-XXXX\n  if (d.length === 10) return d.replace(/(\\d{3})(\\d{3})(\\d{4})/, \"$1-$2-$3\");\n  // 11자리: 0XX-XXXX-XXXX (휴대폰 등)\n  if (d.length === 11) return d.replace(/(\\d{3})(\\d{4})(\\d{4})/, \"$1-$2-$3\");\n\n  // 형식을 모르면 원본 그대로 반환\n  return String(value);\n}\n\n/** 사업자등록번호에 하이픈을 넣는다. (10자리 → XXX-XX-XXXXX) */\nexport function bizNum(value: Numeric): string {\n  if (value === null || value === undefined || value === \"\") return \"\";\n  const d = String(value).replace(/\\D/g, \"\");\n  if (d.length === 10) return d.replace(/(\\d{3})(\\d{2})(\\d{5})/, \"$1-$2-$3\");\n  return String(value);\n}\n\n/** DB에서 온 값(Date 객체 · \"YYYY-MM-DD HH:mm:ss\" 문자열 등)을 Date로 정규화한다. 파싱 실패 시 null. */\nfunction toDate(value: unknown): Date | null {\n  if (value == null || value === \"\") return null;\n  const d = value instanceof Date ? value : new Date(String(value));\n  return Number.isNaN(d.getTime()) ? null : d;\n}\n\nfunction pad(n: number): string {\n  return String(n).padStart(2, \"0\");\n}\n\n/** 날짜만 \"YYYY-MM-DD\" 로 포맷한다. (시간은 버림) */\nexport function formatDate(value: unknown): string {\n  const d = toDate(value);\n  if (!d) return \"\";\n  return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;\n}\n\n/** 날짜+시간을 \"YYYY-MM-DD HH:mm:ss\" 로 포맷한다. */\nexport function formatDateTime(value: unknown): string {\n  const d = toDate(value);\n  if (!d) return \"\";\n  return `${formatDate(d)} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;\n}\n\n/** 표 컬럼 type 에서 사용할 수 있는 포맷 종류 */\nexport type ColumnFormatType = \"comma\" | \"tel\" | \"bizNum\" | \"date\" | \"datetime\";\n\n/** type 값에 맞는 포맷 함수를 적용한다. (AdminTable 내부에서 사용) */\nexport function formatByType(type: ColumnFormatType, value: unknown): string {\n  switch (type) {\n    case \"comma\":\n      return comma(value as Numeric);\n    case \"tel\":\n      return tel(value as Numeric);\n    case \"bizNum\":\n      return bizNum(value as Numeric);\n    case \"date\":\n      return formatDate(value);\n    case \"datetime\":\n      return formatDateTime(value);\n    default:\n      return value == null ? \"\" : String(value);\n  }\n}\n","\"use client\";\n\n/**\n * Input — shadcn/ui 기반 기본 입력창\n *\n * 검색 필터, 폼 등에서 사용하는 텍스트 입력 프리미티브.\n *\n * @example\n * <Input placeholder=\"이름 검색\" value={value} onChange={(e) => setValue(e.target.value)} />\n */\nimport { type ComponentProps } from \"react\";\n\nimport { cn } from \"../../lib/utils\";\n\nfunction Input({ className, type, ...props }: ComponentProps<\"input\">) {\n  return (\n    <input\n      type={type}\n      data-slot=\"input\"\n      className={cn(\n        \"flex h-9 w-full min-w-0 appearance-none rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-xs transition-colors outline-none\",\n        \"placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground\",\n        \"file:inline-flex file:border-0 file:bg-transparent file:text-sm file:font-medium\",\n        \"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]\",\n        \"disabled:cursor-not-allowed disabled:opacity-50\",\n        \"aria-invalid:border-destructive aria-invalid:ring-destructive/20\",\n        className\n      )}\n      {...props}\n    />\n  );\n}\n\nexport { Input };\n","\"use client\";\n\n/**\n * Label — 폼 입력 라벨\n *\n * htmlFor 로 입력 요소와 연결한다. (접근성)\n *\n * @example\n * <Label htmlFor=\"name\">이름</Label>\n * <Input id=\"name\" />\n */\nimport { type ComponentProps } from \"react\";\n\nimport { cn } from \"../../lib/utils\";\n\nfunction Label({ className, ...props }: ComponentProps<\"label\">) {\n  return (\n    <label\n      data-slot=\"label\"\n      className={cn(\n        \"flex items-center gap-2 text-sm font-medium leading-none select-none\",\n        \"peer-disabled:cursor-not-allowed peer-disabled:opacity-50\",\n        className\n      )}\n      {...props}\n    />\n  );\n}\n\nexport { Label };\n","\"use client\";\n\n/**\n * Switch — 켜짐/꺼짐 토글 스위치 (Radix Switch 기반)\n *\n * 두 개의 값 중 하나를 고르는 상태(예: 활성/비활성)를 select 대신 한눈에 보여줄 때 쓴다.\n * AdminFormField type=\"switch\" 의 기반 프리미티브. 직접 조합해서 쓸 수도 있다.\n * size 로 크기를 조절할 수 있다 (기본 md) — 옆에 놓이는 input/select 와 톤을 맞추고 싶을 때 lg 이상 사용.\n * 테두리 없이 트랙 좌우로 2px 여유를 두고 썸이 움직인다 (antd Switch 스타일).\n *\n * @example\n * <Switch checked={enabled} onCheckedChange={setEnabled} />\n * <Switch size=\"xl\" checked={enabled} onCheckedChange={setEnabled} />\n */\nimport { type ComponentProps } from \"react\";\nimport * as SwitchPrimitive from \"@radix-ui/react-switch\";\n\nimport { cn } from \"../../lib/utils\";\n\nexport type SwitchSize = \"sm\" | \"md\" | \"lg\" | \"xl\" | \"xxl\";\n\nconst TRACK_SIZE: Record<SwitchSize, string> = {\n  sm: \"h-4 w-7\",\n  md: \"h-[1.15rem] w-8\",\n  lg: \"h-6 w-11\",\n  xl: \"h-7 w-14\",\n  xxl: \"h-8 w-16\",\n};\n\nconst THUMB_SIZE: Record<SwitchSize, string> = {\n  sm: \"size-3\",\n  md: \"size-4\",\n  lg: \"size-5\",\n  xl: \"size-6\",\n  xxl: \"size-7\",\n};\n\n// 이동 거리(트랙 너비 - 좌우 여유 2px씩 - 썸 너비)를 트랙/썸 조합마다 정확히 맞춘 값.\n// 트랙에 px-[2px] 여유를 둬서 antd Switch 처럼 썸이 양 끝에 완전히 붙지 않고 살짝 여백을 남긴다.\n// sm: 28-4-12=12 / md: 32-4-16=12 / lg: 44-4-20=20 / xl: 56-4-24=28 / xxl: 64-4-28=32 (모두 4px 배수)\nconst THUMB_TRANSLATE: Record<SwitchSize, string> = {\n  sm: \"data-[state=checked]:translate-x-3\",\n  md: \"data-[state=checked]:translate-x-3\",\n  lg: \"data-[state=checked]:translate-x-5\",\n  xl: \"data-[state=checked]:translate-x-7\",\n  xxl: \"data-[state=checked]:translate-x-8\",\n};\n\nexport interface SwitchProps extends ComponentProps<typeof SwitchPrimitive.Root> {\n  /** 크기 (기본 md) */\n  size?: SwitchSize;\n}\n\nfunction Switch({ className, size = \"md\", ...props }: SwitchProps) {\n  return (\n    <SwitchPrimitive.Root\n      data-slot=\"switch\"\n      className={cn(\n        \"peer inline-flex shrink-0 items-center rounded-full px-[2px] shadow-xs outline-none transition-all focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input\",\n        TRACK_SIZE[size],\n        className\n      )}\n      {...props}\n    >\n      <SwitchPrimitive.Thumb\n        data-slot=\"switch-thumb\"\n        className={cn(\n          \"pointer-events-none block rounded-full bg-background shadow-md ring-0 transition-transform data-[state=unchecked]:translate-x-0\",\n          THUMB_SIZE[size],\n          THUMB_TRANSLATE[size]\n        )}\n      />\n    </SwitchPrimitive.Root>\n  );\n}\n\nexport { Switch };\n","\"use client\";\n\n/**\n * Popover — 트리거 기준으로 떠오르는 패널 (Radix Popover 기반)\n *\n * AdminSelect 등의 드롭다운 기반 프리미티브.\n */\nimport { type ComponentProps } from \"react\";\nimport * as PopoverPrimitive from \"@radix-ui/react-popover\";\n\nimport { cn } from \"../../lib/utils\";\n\nfunction Popover(props: ComponentProps<typeof PopoverPrimitive.Root>) {\n  return <PopoverPrimitive.Root data-slot=\"popover\" {...props} />;\n}\n\nfunction PopoverTrigger(\n  props: ComponentProps<typeof PopoverPrimitive.Trigger>\n) {\n  return <PopoverPrimitive.Trigger data-slot=\"popover-trigger\" {...props} />;\n}\n\nfunction PopoverAnchor(\n  props: ComponentProps<typeof PopoverPrimitive.Anchor>\n) {\n  return <PopoverPrimitive.Anchor data-slot=\"popover-anchor\" {...props} />;\n}\n\nfunction PopoverContent({\n  className,\n  align = \"start\",\n  sideOffset = 4,\n  ...props\n}: ComponentProps<typeof PopoverPrimitive.Content>) {\n  return (\n    <PopoverPrimitive.Portal>\n      <PopoverPrimitive.Content\n        data-slot=\"popover-content\"\n        align={align}\n        sideOffset={sideOffset}\n        className={cn(\n          \"bg-popover text-popover-foreground z-50 rounded-md border p-1 shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95\",\n          className\n        )}\n        {...props}\n      />\n    </PopoverPrimitive.Portal>\n  );\n}\n\nexport { Popover, PopoverTrigger, PopoverAnchor, PopoverContent };\n","\"use client\";\n\n/**\n * AdminSelect — 검색 가능 + 선택 취소 + 가상 스크롤 셀렉트 (단일 선택)\n *\n * - searchable=true(기본): 콤보박스 — 트리거 입력창에서 바로 타이핑해 검색한다.\n * - searchable=false: 일반 셀렉트 버튼.\n * - clearable: 선택값을 X 로 초기화 (기본 true)\n * - 가상 스크롤(TanStack Virtual)로 옵션이 수천 개여도 빠르게 렌더링\n * - 옵션 image/description 지원 (상품 선택 등)\n * - 키보드: ↑/↓ 이동, Enter 선택, Esc 닫기\n *\n * 제어 컴포넌트. AdminFormField/AdminFilterField 안에 넣어 쓸 수 있다.\n *\n * @example\n * <AdminSelect options={products} value={id} onChange={setId} placeholder=\"상품 검색·선택\" />\n */\nimport {\n  forwardRef,\n  useCallback,\n  useEffect,\n  useImperativeHandle,\n  useMemo,\n  useRef,\n  useState,\n} from \"react\";\nimport { useVirtualizer } from \"@tanstack/react-virtual\";\nimport { Check, ChevronDown, X } from \"lucide-react\";\n\nimport { cn } from \"../../lib/utils\";\nimport {\n  Popover,\n  PopoverAnchor,\n  PopoverContent,\n  PopoverTrigger,\n} from \"../ui/popover\";\n\nexport interface AdminSelectOption {\n  value: string;\n  label: string;\n  /** 옵션 앞에 표시할 이미지 URL (상품 선택 등) */\n  image?: string;\n  /** 라벨 아래 보조 설명 (가격/코드 등) */\n  description?: string;\n  disabled?: boolean;\n}\n\nexport interface AdminSelectProps {\n  options: AdminSelectOption[];\n  value?: string;\n  onChange?: (value: string) => void;\n  placeholder?: string;\n  /** 검색(콤보박스) 사용 (기본 true) */\n  searchable?: boolean;\n  /** 선택 취소(X) 버튼 (기본 true) */\n  clearable?: boolean;\n  disabled?: boolean;\n  /** 검색 결과 없을 때 문구 */\n  emptyText?: string;\n  /** 콤보박스 열렸을 때 입력 placeholder */\n  searchPlaceholder?: string;\n  id?: string;\n  /** 트리거 클래스 (너비 등) */\n  className?: string;\n  /** 드롭다운 패널 클래스 */\n  contentClassName?: string;\n  /** 트리거에서 포커스가 빠질 때 (AdminFormField 의 touched 검증 트리거용) */\n  onBlur?: () => void;\n}\n\n/** ref 로 노출되는 명령형 핸들 — 외부에서 강제로 포커스(+ 메뉴 열기)를 트리거할 때 사용 */\nexport interface AdminSelectHandle {\n  focus: () => void;\n}\n\nconst ROW_HEIGHT = 34;\nconst ROW_HEIGHT_RICH = 48; // 이미지/설명이 있을 때\n\nconst triggerBase =\n  \"flex h-9 w-full items-center gap-2 rounded-md border border-input bg-transparent px-3 text-sm shadow-xs outline-none transition-colors disabled:cursor-not-allowed disabled:opacity-50\";\nconst triggerFocus =\n  \"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]\";\n\nexport const AdminSelect = forwardRef<AdminSelectHandle, AdminSelectProps>(\n  function AdminSelect(\n    {\n      options,\n      value,\n      onChange,\n      placeholder = \"선택하세요\",\n      searchable = true,\n      clearable = true,\n      disabled,\n      emptyText = \"결과가 없습니다.\",\n      searchPlaceholder = \"검색...\",\n      id,\n      className,\n      contentClassName,\n      onBlur,\n    },\n    ref\n  ) {\n  const [open, setOpen] = useState(false);\n  const [query, setQuery] = useState(\"\");\n  // 열었을 때 아직 아무것도 타이핑 안 한 상태(false)인지, 한 번이라도 편집한 상태(true)인지.\n  // false 일 때만 입력창에 현재 선택된 라벨을 보여준다 — 한 번 편집하면(빈 문자열로 지운\n  // 경우 포함) 그 뒤로는 query 를 그대로 보여줘서, 검색어를 다 지웠을 때 선택값으로\n  // \"되돌아가는\" 것처럼 보이지 않게 한다.\n  const [searchTouched, setSearchTouched] = useState(false);\n  const [active, setActive] = useState(0);\n  const listRef = useRef<HTMLDivElement>(null);\n  const triggerRef = useRef<HTMLDivElement>(null);\n  // AdminModal(Radix Dialog) 안에서 쓰일 때, Dialog 가 배경 스크롤을 잠그면서\n  // (react-remove-scroll) 이 리스트는 Popover Portal 로 document.body 에 렌더되어\n  // \"모달 밖\" 콘텐츠로 오인되어 wheel 스크롤 자체가 막힌다. 네이티브 스크롤에 기대지\n  // 않고 wheel 이벤트를 직접 받아 scrollTop 을 옮겨서 우회한다 — React 의 onWheel 은\n  // 기본적으로 passive 라 preventDefault 가 안 먹히므로 네이티브 리스너를 직접 붙인다.\n  const handleListWheel = useCallback((e: WheelEvent) => {\n    e.preventDefault();\n    (e.currentTarget as HTMLDivElement).scrollTop += e.deltaY;\n  }, []);\n  const setListRef = useCallback(\n    (node: HTMLDivElement | null) => {\n      if (listRef.current) {\n        listRef.current.removeEventListener(\"wheel\", handleListWheel);\n      }\n      listRef.current = node;\n      if (node) {\n        node.addEventListener(\"wheel\", handleListWheel, { passive: false });\n      }\n    },\n    [handleListWheel]\n  );\n  const searchInputRef = useRef<HTMLInputElement>(null);\n  const buttonRef = useRef<HTMLButtonElement>(null);\n  const listId = `${id ?? \"admin-select\"}-listbox`;\n\n  useImperativeHandle(ref, () => ({\n    focus: () => {\n      if (searchable) {\n        searchInputRef.current?.focus();\n      } else {\n        buttonRef.current?.focus();\n        openMenu();\n      }\n    },\n  }));\n\n  const selected = options.find((o) => o.value === value);\n  const rowHeight = options.some((o) => o.image || o.description)\n    ? ROW_HEIGHT_RICH\n    : ROW_HEIGHT;\n\n  // 콤보박스가 열려 있고 검색어가 있을 때만 필터\n  const filtered = useMemo(() => {\n    if (!searchable || !open || !query.trim()) return options;\n    const q = query.trim().toLowerCase();\n    return options.filter((o) => o.label.toLowerCase().includes(q));\n  }, [options, query, searchable, open]);\n\n  // eslint-disable-next-line react-hooks/incompatible-library\n  const virtualizer = useVirtualizer({\n    count: filtered.length,\n    getScrollElement: () => listRef.current,\n    estimateSize: () => rowHeight,\n    overscan: 8,\n  });\n\n  // Radix Popover 는 내용을 Presence 로 한 프레임 늦게 마운트하는 경우가 있어서,\n  // 열리는 그 순간 useVirtualizer 가 listRef.current 를 아직 null 로 보고\n  // 리스트 엘리먼트를 못 찾은 채 굳어버릴 수 있다(항목이 하나도 안 보임 — 이후 아무 상태\n  // 변경 없이는 다시 측정되지 않는다). 열릴 때 한 프레임 뒤에 재렌더를 강제해서\n  // 그 시점엔 이미 마운트된 리스트 엘리먼트를 virtualizer 가 다시 찾게 한다.\n  const [remeasureTick, forceRemeasure] = useState(0);\n  useEffect(() => {\n    if (!open) return;\n    const raf = requestAnimationFrame(() => forceRemeasure((n) => n + 1));\n    return () => cancelAnimationFrame(raf);\n  }, [open]);\n\n  // 열려있고 검색 중이 아닐 때, 현재 선택된 항목으로 active 를 맞추고 그 위치로 스크롤한다.\n  // options 가 나중에(비동기) 채워지는 경우, 그리고 위 remeasureTick(리스트 엘리먼트가 늦게\n  // 마운트되는 경우)에도 이 effect 가 다시 돌아서 그때 선택 항목을 찾아 스크롤해준다 —\n  // \"옵션 로딩 끝났는데 선택한 부분에 포커스가 안 된다\"를 해결.\n  // eslint-disable-next-line react-hooks/incompatible-library\n  useEffect(() => {\n    if (!open || query.trim()) return;\n    const idx = options.findIndex((o) => o.value === value);\n    if (idx >= 0) {\n      setActive(idx);\n      virtualizer.scrollToIndex(idx, { align: \"center\" });\n    }\n  }, [open, options, value, remeasureTick]);\n\n  const openMenu = () => {\n    if (disabled) return;\n    setQuery(\"\");\n    setSearchTouched(false);\n    const idx = options.findIndex((o) => o.value === value);\n    setActive(idx >= 0 ? idx : 0);\n    setOpen(true);\n  };\n\n  const choose = (opt: AdminSelectOption) => {\n    if (opt.disabled) return;\n    onChange?.(opt.value);\n    setQuery(\"\");\n    setOpen(false);\n  };\n\n  const clear = () => {\n    onChange?.(\"\");\n    setQuery(\"\");\n  };\n\n  const moveActive = (delta: number) => {\n    if (filtered.length === 0) return;\n    const next = Math.min(Math.max(active + delta, 0), filtered.length - 1);\n    setActive(next);\n    virtualizer.scrollToIndex(next);\n  };\n\n  const handleKeyDown = (e: React.KeyboardEvent) => {\n    if (e.key === \"ArrowDown\") {\n      e.preventDefault();\n      if (!open) openMenu();\n      else moveActive(1);\n    } else if (e.key === \"ArrowUp\") {\n      e.preventDefault();\n      moveActive(-1);\n    } else if (e.key === \"Enter\") {\n      if (open) {\n        e.preventDefault();\n        const opt = filtered[active];\n        if (opt) choose(opt);\n      }\n    } else if (e.key === \"Escape\") {\n      setOpen(false);\n    }\n  };\n\n  // 옵션 목록 (검색형/버튼형 공용)\n  const list =\n    filtered.length === 0 ? (\n      <div className=\"px-3 py-6 text-center text-sm text-muted-foreground\">\n        {emptyText}\n      </div>\n    ) : (\n      <div\n        ref={setListRef}\n        id={listId}\n        role=\"listbox\"\n        className=\"max-h-60 overflow-y-auto p-1\"\n      >\n        <div style={{ height: virtualizer.getTotalSize(), position: \"relative\" }}>\n          {virtualizer.getVirtualItems().map((row) => {\n            const opt = filtered[row.index];\n            const isSelected = opt.value === value;\n            const isActive = row.index === active;\n            return (\n              <button\n                key={opt.value}\n                type=\"button\"\n                disabled={opt.disabled}\n                // 마우스다운 시 입력창 포커스가 풀리지 않도록(콤보박스) 막는다.\n                onMouseDown={(e) => e.preventDefault()}\n                onClick={() => choose(opt)}\n                onMouseEnter={() => setActive(row.index)}\n                className={cn(\n                  \"absolute left-0 flex w-full items-center gap-2 rounded-sm px-2 text-sm outline-none\",\n                  \"disabled:pointer-events-none disabled:opacity-50\",\n                  isActive && \"bg-accent text-accent-foreground\"\n                )}\n                style={{ top: row.start, height: row.size }}\n              >\n                <Check\n                  className={cn(\n                    \"size-4 shrink-0\",\n                    isSelected ? \"opacity-100\" : \"opacity-0\"\n                  )}\n                />\n                {opt.image && (\n                  // eslint-disable-next-line @next/next/no-img-element\n                  <img\n                    src={opt.image}\n                    alt=\"\"\n                    className=\"size-8 shrink-0 rounded object-cover\"\n                  />\n                )}\n                <span className=\"min-w-0 flex-1 text-left\">\n                  <span className={cn(\"block truncate\", isSelected && \"font-medium\")}>\n                    {opt.label}\n                  </span>\n                  {opt.description && (\n                    <span className=\"block truncate text-xs text-muted-foreground\">\n                      {opt.description}\n                    </span>\n                  )}\n                </span>\n              </button>\n            );\n          })}\n        </div>\n      </div>\n    );\n\n  const popoverContent = (\n    <PopoverContent\n      align=\"start\"\n      className={cn(\"p-0\", contentClassName)}\n      style={{ width: \"var(--radix-popover-trigger-width)\" }}\n      onKeyDown={handleKeyDown}\n      // 콤보박스: 포커스를 입력창에 유지하고, 트리거 클릭은 외부닫힘에서 제외\n      onOpenAutoFocus={searchable ? (e) => e.preventDefault() : undefined}\n      onInteractOutside={(e) => {\n        if (triggerRef.current?.contains(e.target as Node)) e.preventDefault();\n      }}\n    >\n      {list}\n    </PopoverContent>\n  );\n\n  // 검색형(콤보박스): 트리거 자리가 곧 검색 입력\n  if (searchable) {\n    return (\n      <Popover open={open} onOpenChange={setOpen}>\n        <PopoverAnchor asChild>\n          <div\n            ref={triggerRef}\n            className={cn(\n              triggerBase,\n              \"focus-within:border-ring focus-within:ring-ring/50 focus-within:ring-[3px]\",\n              disabled && \"opacity-50\",\n              className\n            )}\n          >\n            {selected?.image && !open && (\n              // eslint-disable-next-line @next/next/no-img-element\n              <img\n                src={selected.image}\n                alt=\"\"\n                className=\"size-5 shrink-0 rounded object-cover\"\n              />\n            )}\n            <input\n              ref={searchInputRef}\n              id={id}\n              disabled={disabled}\n              role=\"combobox\"\n              aria-expanded={open}\n              aria-controls={listId}\n              aria-autocomplete=\"list\"\n              // 열렸을 때 아직 편집 전(searchTouched=false)이면 현재 선택된 라벨을 그대로\n              // 보여준다 — 열자마자 값이 사라지고 \"검색...\" placeholder만 보여서 뭘 골랐는지\n              // 못 보는 문제 방지. 한 번 편집하면(빈 문자열로 지운 경우 포함) 그 뒤로는 query\n              // 를 그대로 보여줘서, 검색어를 다 지웠을 때 선택값으로 되돌아간 것처럼 보이지 않게 한다.\n              value={\n                open\n                  ? searchTouched\n                    ? query\n                    : selected?.label ?? \"\"\n                  : selected?.label ?? \"\"\n              }\n              placeholder={open ? searchPlaceholder : placeholder}\n              onChange={(e) => {\n                setQuery(e.target.value);\n                setSearchTouched(true);\n                setActive(0);\n                if (!open) setOpen(true);\n              }}\n              onFocus={(e) => {\n                openMenu();\n                e.target.select(); // 전체 선택 — 바로 타이핑하면 기존 값이 자연스럽게 교체됨\n              }}\n              onBlur={onBlur}\n              onKeyDown={handleKeyDown}\n              className=\"w-full min-w-0 bg-transparent outline-none placeholder:text-muted-foreground\"\n            />\n            {clearable && selected && !disabled && (\n              <button\n                type=\"button\"\n                tabIndex={-1}\n                aria-label=\"선택 해제\"\n                onMouseDown={(e) => e.preventDefault()}\n                onClick={clear}\n                className=\"flex shrink-0 items-center justify-center rounded-sm text-muted-foreground hover:text-foreground\"\n              >\n                <X className=\"size-3.5\" />\n              </button>\n            )}\n            <ChevronDown\n              className=\"size-4 shrink-0 text-muted-foreground\"\n              onMouseDown={(e) => e.preventDefault()}\n              onClick={() => (open ? setOpen(false) : openMenu())}\n            />\n          </div>\n        </PopoverAnchor>\n        {popoverContent}\n      </Popover>\n    );\n  }\n\n  // 비검색형: 일반 셀렉트 버튼\n  return (\n    <Popover\n      open={open}\n      onOpenChange={(o) => {\n        setOpen(o);\n        if (o) {\n          const idx = options.findIndex((opt) => opt.value === value);\n          setActive(idx >= 0 ? idx : 0);\n        }\n      }}\n    >\n      <PopoverTrigger asChild>\n        <button\n          ref={buttonRef}\n          type=\"button\"\n          id={id}\n          disabled={disabled}\n          aria-haspopup=\"listbox\"\n          aria-expanded={open}\n          onBlur={onBlur}\n          className={cn(triggerBase, triggerFocus, \"justify-between\", className)}\n        >\n          {selected ? (\n            <span className=\"flex min-w-0 items-center gap-2\">\n              {selected.image && (\n                // eslint-disable-next-line @next/next/no-img-element\n                <img\n                  src={selected.image}\n                  alt=\"\"\n                  className=\"size-5 shrink-0 rounded object-cover\"\n                />\n              )}\n              <span className=\"truncate\">{selected.label}</span>\n            </span>\n          ) : (\n            <span className=\"truncate text-muted-foreground\">{placeholder}</span>\n          )}\n          <span className=\"flex shrink-0 items-center gap-1\">\n            {clearable && selected && !disabled && (\n              <span\n                role=\"button\"\n                tabIndex={-1}\n                aria-label=\"선택 해제\"\n                className=\"flex items-center justify-center rounded-sm text-muted-foreground hover:text-foreground\"\n                onClick={(e) => {\n                  e.stopPropagation();\n                  clear();\n                }}\n              >\n                <X className=\"size-3.5\" />\n              </span>\n            )}\n            <ChevronDown className=\"size-4 shrink-0 text-muted-foreground\" />\n          </span>\n        </button>\n      </PopoverTrigger>\n      {popoverContent}\n    </Popover>\n  );\n  }\n);\n","\"use client\";\n\n/**\n * AdminImageUpload — 이미지 업로드 (클릭/드래그&드롭 + 미리보기 + 확대 + 삭제)\n *\n * 제어 컴포넌트: value(이미지 URL 배열) + onChange 로 관리한다.\n * - 기본은 파일을 data URL 로 읽어 value 에 넣는다(미리보기 = 값).\n * - onUpload 를 주면 그 결과 URL(서버 업로드 등)을 value 에 넣는다.\n * - 썸네일을 클릭하면 원본 크기로 확대해서 볼 수 있다 (preview=false 로 끌 수 있음).\n *\n * @example\n * const [images, setImages] = useState<string[]>([]);\n * <AdminImageUpload value={images} onChange={setImages} maxCount={3} />\n *\n * @example // 서버 업로드\n * <AdminImageUpload\n *   value={images}\n *   onChange={setImages}\n *   onUpload={async (file) => (await api.upload(file)).url}\n * />\n *\n * @example // 저장 시점에 업로드 (onUpload 를 안 주면 미리보기만 하고 서버로는 안 보낸다)\n * const pendingFile = useRef<File | null>(null);\n * <AdminImageUpload\n *   value={images}\n *   onChange={setImages}\n *   onFilesAdded={(files) => { pendingFile.current = files[0] ?? null; }}\n * />\n * // 저장 버튼에서: pendingFile.current 가 있으면 그때 업로드해서 실제 URL 로 바꿔치기\n */\nimport {\n  forwardRef,\n  useImperativeHandle,\n  useRef,\n  useState,\n} from \"react\";\nimport * as DialogPrimitive from \"@radix-ui/react-dialog\";\nimport { ImagePlus, Loader2, X, ZoomIn } from \"lucide-react\";\n\nimport { cn } from \"../../lib/utils\";\n\nexport interface AdminImageUploadProps {\n  /** 이미지 URL 배열 */\n  value?: string[];\n  onChange?: (urls: string[]) => void;\n  /** 최대 개수 (기본 1) */\n  maxCount?: number;\n  /** accept 속성 (기본 \"image/*\") */\n  accept?: string;\n  disabled?: boolean;\n  /** 업로드 처리(예: 서버 업로드). 주면 반환 URL 을 value 에 넣는다. 없으면 data URL */\n  onUpload?: (file: File) => Promise<string>;\n  /**\n   * 파일이 선택/드롭된 직후(업로드 전) 원본 File 목록을 받는다.\n   * onUpload 없이 미리보기만 해두고, 저장 시점에 이 File 을 직접 업로드하는 흐름에 사용한다.\n   */\n  onFilesAdded?: (files: File[]) => void;\n  /** 썸네일 한 변 크기 px (기본 96) */\n  size?: number;\n  /** 썸네일 클릭 시 확대(라이트박스)로 보기 (기본 true) */\n  preview?: boolean;\n  className?: string;\n}\n\n/** ref 로 노출되는 명령형 핸들 — 외부에서 강제로 포커스를 트리거할 때 사용 */\nexport interface AdminImageUploadHandle {\n  focus: () => void;\n}\n\nfunction readAsDataURL(file: File): Promise<string> {\n  return new Promise((resolve, reject) => {\n    const reader = new FileReader();\n    reader.onload = () => resolve(reader.result as string);\n    reader.onerror = reject;\n    reader.readAsDataURL(file);\n  });\n}\n\n/** file 이 accept 패턴(예: \"image/*,.pdf\") 중 하나라도 맞는지 검사 */\nfunction matchesAccept(file: File, accept: string): boolean {\n  const patterns = accept\n    .split(\",\")\n    .map((s) => s.trim())\n    .filter(Boolean);\n  if (patterns.length === 0) return true;\n  return patterns.some((p) => {\n    if (p.endsWith(\"/*\")) return file.type.startsWith(p.slice(0, -1));\n    if (p.startsWith(\".\")) return file.name.toLowerCase().endsWith(p.toLowerCase());\n    return file.type === p;\n  });\n}\n\nexport const AdminImageUpload = forwardRef<\n  AdminImageUploadHandle,\n  AdminImageUploadProps\n>(function AdminImageUpload(\n  {\n    value = [],\n    onChange,\n    maxCount = 1,\n    accept = \"image/*\",\n    disabled,\n    onUpload,\n    onFilesAdded,\n    size = 96,\n    preview = true,\n    className,\n  },\n  ref\n) {\n  const inputRef = useRef<HTMLInputElement>(null);\n  const addButtonRef = useRef<HTMLButtonElement>(null);\n  const [dragOver, setDragOver] = useState(false);\n  const [uploading, setUploading] = useState(0);\n  const [zoomIndex, setZoomIndex] = useState<number | null>(null);\n\n  useImperativeHandle(ref, () => ({\n    focus: () => addButtonRef.current?.focus(),\n  }));\n\n  const canAdd = !disabled && value.length + uploading < maxCount;\n\n  const addFiles = async (fileList: FileList | null) => {\n    if (!fileList || disabled) return;\n    const remaining = maxCount - value.length;\n    const files = Array.from(fileList)\n      .filter((f) => matchesAccept(f, accept))\n      .slice(0, Math.max(0, remaining));\n    if (files.length === 0) return;\n\n    onFilesAdded?.(files);\n\n    setUploading((n) => n + files.length);\n    try {\n      const urls = await Promise.all(\n        files.map((f) => (onUpload ? onUpload(f) : readAsDataURL(f)))\n      );\n      onChange?.([...value, ...urls]);\n    } finally {\n      setUploading((n) => Math.max(0, n - files.length));\n    }\n  };\n\n  const removeAt = (index: number) =>\n    onChange?.(value.filter((_, i) => i !== index));\n\n  const tileStyle = { width: size, height: size };\n\n  return (\n    <div className={cn(\"flex flex-wrap gap-3\", className)}>\n      {/* 미리보기 타일 */}\n      {value.map((url, i) => (\n        <div\n          key={i}\n          style={tileStyle}\n          className=\"group relative overflow-hidden rounded-lg border bg-muted\"\n        >\n          {/* eslint-disable-next-line @next/next/no-img-element */}\n          <img\n            src={url}\n            alt=\"\"\n            onClick={() => preview && setZoomIndex(i)}\n            className={cn(\"size-full object-cover\", preview && \"cursor-zoom-in\")}\n          />\n          {preview && (\n            <span className=\"pointer-events-none absolute inset-0 hidden items-center justify-center bg-black/30 text-white group-hover:flex\">\n              <ZoomIn className=\"size-5\" />\n            </span>\n          )}\n          {!disabled && (\n            <button\n              type=\"button\"\n              aria-label=\"삭제\"\n              onClick={() => removeAt(i)}\n              className=\"absolute top-1 right-1 rounded-full bg-black/55 p-1 text-white opacity-0 transition-opacity hover:bg-black/75 group-hover:opacity-100\"\n            >\n              <X className=\"size-3.5\" />\n            </button>\n          )}\n        </div>\n      ))}\n\n      {/* 업로드 중 타일 */}\n      {Array.from({ length: uploading }).map((_, i) => (\n        <div\n          key={`u-${i}`}\n          style={tileStyle}\n          className=\"flex items-center justify-center rounded-lg border bg-muted text-muted-foreground\"\n        >\n          <Loader2 className=\"size-5 animate-spin\" />\n        </div>\n      ))}\n\n      {/* 추가(업로드) 타일 */}\n      {canAdd && (\n        <button\n          ref={addButtonRef}\n          type=\"button\"\n          onClick={() => inputRef.current?.click()}\n          onDragOver={(e) => {\n            e.preventDefault();\n            setDragOver(true);\n          }}\n          onDragLeave={() => setDragOver(false)}\n          onDrop={(e) => {\n            e.preventDefault();\n            setDragOver(false);\n            void addFiles(e.dataTransfer.files);\n          }}\n          data-drag={dragOver}\n          style={tileStyle}\n          className={cn(\n            \"flex flex-col items-center justify-center gap-1 rounded-lg border-2 border-dashed border-input text-muted-foreground transition-colors\",\n            \"hover:border-ring hover:text-foreground\",\n            \"data-[drag=true]:border-ring data-[drag=true]:bg-accent data-[drag=true]:text-foreground\"\n          )}\n        >\n          <ImagePlus className=\"size-5\" />\n          <span className=\"text-xs\">업로드</span>\n        </button>\n      )}\n\n      <input\n        ref={inputRef}\n        type=\"file\"\n        accept={accept}\n        multiple={maxCount > 1}\n        className=\"hidden\"\n        onChange={(e) => {\n          void addFiles(e.target.files);\n          e.target.value = \"\"; // 같은 파일 재선택 가능하도록 초기화\n        }}\n      />\n\n      {/* 확대(라이트박스) */}\n      <DialogPrimitive.Root\n        open={zoomIndex !== null}\n        onOpenChange={(o) => !o && setZoomIndex(null)}\n      >\n        <DialogPrimitive.Portal>\n          <DialogPrimitive.Overlay className=\"fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\" />\n          <DialogPrimitive.Content\n            onClick={() => setZoomIndex(null)}\n            className=\"fixed inset-0 z-50 flex items-center justify-center p-6 outline-none\"\n          >\n            <DialogPrimitive.Title className=\"sr-only\">\n              이미지 확대 보기\n            </DialogPrimitive.Title>\n            {zoomIndex !== null && (\n              // eslint-disable-next-line @next/next/no-img-element\n              <img\n                src={value[zoomIndex]}\n                alt=\"\"\n                onClick={(e) => e.stopPropagation()}\n                className=\"max-h-[90vh] max-w-[90vw] object-contain data-[state=open]:animate-in data-[state=open]:zoom-in-95\"\n              />\n            )}\n            <DialogPrimitive.Close className=\"absolute top-4 right-4 rounded-full bg-black/50 p-2 text-white outline-none transition-colors hover:bg-black/70 focus-visible:ring-2 focus-visible:ring-white\">\n              <X className=\"size-5\" />\n              <span className=\"sr-only\">닫기</span>\n            </DialogPrimitive.Close>\n          </DialogPrimitive.Content>\n        </DialogPrimitive.Portal>\n      </DialogPrimitive.Root>\n    </div>\n  );\n});\n","\"use client\";\n\n/**\n * AdminFormField — 폼 입력 필드 (라벨 + 입력 컨트롤 묶음)\n *\n * 모달/폼에서 \"라벨 + input\"을 반복 작성하지 않도록 공통화한 것.\n * - required: 라벨 옆에 빨간 * 표시\n * - description / error: 입력 아래 도움말 / 에러 메시지(빨간색, description 대체)\n * - orientation: 라벨 위치 (vertical=위, horizontal=왼쪽)\n *\n * 입력 컨트롤은 두 가지 방식으로 줄 수 있다:\n * 1) children 으로 직접 주입 (Input, AdminSelect, 커스텀 등 무엇이든)\n * 2) type 으로 자동 생성 — \"text\" | \"email\" | \"password\" | \"number\" | \"comma\" | \"tel\" | \"bizNum\"\n *    | \"textarea\" | \"select\" | \"switch\" | \"upload\"\n *    (value/onChange 와 함께 사용. comma 는 천 단위 콤마 포맷을 자동 처리)\n *    switch 는 options 의 두 항목([0]=꺼짐, [1]=켜짐)을 토글로 보여준다 (select 대체용, 상태값이 2개일 때).\n *\n * @example\n * // 자동 input (type)\n * <AdminFormField label=\"이메일\" type=\"email\" required value={email} onChange={setEmail} />\n * <AdminFormField label=\"금액\" type=\"comma\" value={amount} onChange={setAmount} />\n * <AdminFormField label=\"메모\" type=\"textarea\" value={memo} onChange={setMemo} />\n * <AdminFormField\n *   label=\"상태\"\n *   type=\"select\"\n *   required\n *   options={[{ value: \"A\", label: \"진행중\" }]}\n *   value={status}\n *   onChange={setStatus}\n * />\n * // type=\"switch\": options[0]=꺼짐, options[1]=켜짐 — 상태값이 2개뿐일 때 select 대신 사용\n * // switchProps 로 크기 조절 가능 (기본 md, 옆 input/select 와 톤을 맞추고 싶으면 lg)\n * <AdminFormField\n *   label=\"상태\"\n *   type=\"switch\"\n *   options={[{ value: \"00\", label: \"비활성\" }, { value: \"01\", label: \"활성\" }]}\n *   value={status}\n *   onChange={setStatus}\n *   switchProps={{ size: \"lg\" }}\n * />\n * // type=\"upload\": 이미지 1장을 value(문자열 URL) 로 다룬다 (여러 장은 AdminImageUpload 직접 사용)\n * <AdminFormField\n *   label=\"사업자등록증\"\n *   type=\"upload\"\n *   value={form.values.biz_img}\n *   onChange={(url) => form.setValues((v) => ({ ...v, biz_img: url }))}\n *   uploadProps={{ accept: \"image/*,.pdf\", onFilesAdded: (files) => setBizImg(files[0] ?? null) }}\n * />\n *\n * @example\n * // 커스텀 컨트롤 (children)\n * <AdminFormField label=\"상태\">\n *   <select ...>...</select>\n * </AdminFormField>\n */\nimport {\n  type ComponentProps,\n  type ReactNode,\n  useEffect,\n  useRef,\n  useState,\n} from \"react\";\n\nimport { cn } from \"../../lib/utils\";\nimport { type ColumnFormatType, formatByType } from \"../../lib/format\";\nimport { Input } from \"../ui/input\";\nimport { Label } from \"../ui/label\";\nimport { Switch, type SwitchProps } from \"../ui/switch\";\nimport {\n  AdminSelect,\n  type AdminSelectHandle,\n  type AdminSelectOption,\n  type AdminSelectProps,\n} from \"../select/admin-select\";\nimport {\n  AdminImageUpload,\n  type AdminImageUploadHandle,\n  type AdminImageUploadProps,\n} from \"../upload/admin-image-upload\";\n\nexport type AdminFormFieldType =\n  | \"text\"\n  | \"email\"\n  | \"password\"\n  | \"number\"\n  | \"textarea\"\n  | \"select\"\n  | \"switch\"\n  | \"upload\"\n  | ColumnFormatType; // \"comma\" | \"tel\" | \"bizNum\" — 표시는 포맷, 저장은 숫자만\n\n/** 입력값을 포맷해서 보여주는 타입들 (저장 시 숫자만 추출) */\nconst FORMATTED_TYPES: ColumnFormatType[] = [\"comma\", \"tel\", \"bizNum\"];\n\n/** 포맷 타입별 최대 입력 자릿수 (없으면 무제한) */\nconst MAX_DIGITS: Partial<Record<ColumnFormatType, number>> = {\n  tel: 11, // 휴대폰 010xxxxxxxx\n  bizNum: 10, // 사업자등록번호\n};\n\nconst EMAIL_RE = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n\n/**\n * 타입별 기본 형식 검증. 통과하면 undefined, 아니면 오류 메시지를 반환한다.\n * (빈 값은 required 가 아니면 통과 — 비필수 선택 입력 허용)\n */\nfunction validateValue(\n  type: AdminFormFieldType | undefined,\n  value: string | number | undefined,\n  required?: boolean\n): string | undefined {\n  const v = String(value ?? \"\").trim();\n  if (!v) return required ? \"필수 입력 항목입니다.\" : undefined;\n\n  switch (type) {\n    case \"email\":\n      return EMAIL_RE.test(v) ? undefined : \"이메일 형식이 올바르지 않습니다.\";\n    case \"tel\": {\n      const len = v.replace(/\\D/g, \"\").length;\n      return len === 10 || len === 11\n        ? undefined\n        : \"전화번호 형식이 올바르지 않습니다.\";\n    }\n    case \"bizNum\":\n      return v.replace(/\\D/g, \"\").length === 10\n        ? undefined\n        : \"사업자등록번호는 10자리 숫자여야 합니다.\";\n    default:\n      return undefined;\n  }\n}\n\n/** 한 필드의 검증 규칙 (useAdminForm 등에서 사용) */\nexport interface FieldRule {\n  type?: AdminFormFieldType;\n  required?: boolean;\n  validate?: (value: string) => string | undefined;\n}\n\n/**\n * 규칙과 값으로 오류 메시지를 계산한다. (타이밍과 무관한 순수 검증 — 제출 검증용)\n * 순서: 필수 빈 값 → 커스텀 validate → 내장 type 검증\n */\nexport function getFieldError(\n  rule: FieldRule,\n  value: string | number | undefined\n): string | undefined {\n  const raw = String(value ?? \"\");\n  const v = raw.trim();\n  if (!v) return rule.required ? \"필수 입력 항목입니다.\" : undefined;\n  if (rule.validate) return rule.validate(raw);\n  if (rule.type) return validateValue(rule.type, raw);\n  return undefined;\n}\n\nexport interface AdminFormFieldProps {\n  /** 필드 라벨 */\n  label?: ReactNode;\n  /** 라벨과 연결할 컨트롤 id */\n  htmlFor?: string;\n  /** 필수 표시(*) */\n  required?: boolean;\n  /** 입력 아래 도움말 */\n  description?: ReactNode;\n  /** 에러 메시지 (있으면 빨간색으로 표시되고 description 을 대체) */\n  error?: ReactNode;\n  /** 라벨 위치 (기본 vertical=위) */\n  orientation?: \"vertical\" | \"horizontal\";\n  /** horizontal 일 때 라벨 너비 클래스 (기본 sm:w-28) */\n  labelClassName?: string;\n  className?: string;\n\n  /** 자동 생성할 입력 종류 (children 미지정 시) */\n  type?: AdminFormFieldType;\n  /** 자동 입력의 값 */\n  value?: string | number;\n  /** 자동 입력의 변경 콜백 (comma 는 숫자만 추출한 문자열을 돌려준다) */\n  onChange?: (value: string) => void;\n  /** 자동 입력의 placeholder */\n  placeholder?: string;\n  /**\n   * 커스텀 검증. 값을 받아 오류 메시지(문자열)를 반환하면 그 메시지가 표시되고,\n   * 통과하면 undefined 를 반환한다. (예: 비밀번호 규칙처럼 서비스마다 다른 조건)\n   * required 빈 값 검사 이후, 내장 type 검증보다 우선 적용된다.\n   * @example validate={(v) => v.length < 8 ? \"8자 이상 입력하세요.\" : undefined}\n   */\n  validate?: (value: string) => string | undefined;\n  /**\n   * 제출(저장) 시점에 부모가 true 로 켜면 필수 누락 등 모든 오류를 즉시 표시한다.\n   * 평소(false)에는 blur 이후 형식 오류만 표시하고, 필수 빈 값 오류는 띄우지 않는다.\n   */\n  forceValidate?: boolean;\n  /** 자동 입력에 추가로 전달할 input 속성 (type 이 \"textarea\" | \"select\" 가 아닐 때) */\n  inputProps?: Omit<\n    ComponentProps<\"input\">,\n    \"value\" | \"onChange\" | \"type\" | \"id\" | \"placeholder\"\n  >;\n  /** type=\"textarea\" 일 때 표시할 줄 수 (기본 3) */\n  rows?: number;\n  /** type=\"select\" 일 때 사용할 옵션 목록 */\n  options?: AdminSelectOption[];\n  /** type=\"select\" 일 때 AdminSelect 에 추가로 전달할 속성 (searchable, clearable 등) */\n  selectProps?: Omit<\n    AdminSelectProps,\n    \"options\" | \"value\" | \"onChange\" | \"id\" | \"placeholder\" | \"onBlur\"\n  >;\n  /** type=\"switch\" 일 때 Switch 에 추가로 전달할 속성 (size 등) */\n  switchProps?: Omit<SwitchProps, \"checked\" | \"onCheckedChange\" | \"id\">;\n  /**\n   * type=\"upload\" 일 때 AdminImageUpload 에 추가로 전달할 속성 (accept, onUpload, onFilesAdded 등).\n   * value/onChange 는 이미지 1장(문자열 URL)만 다룬다 — 여러 장이 필요하면 AdminImageUpload 를 직접 사용한다.\n   */\n  uploadProps?: Omit<AdminImageUploadProps, \"value\" | \"onChange\" | \"maxCount\">;\n\n  /**\n   * 에러가 뜰 때 이 필드로 포커스를 옮길지 여부 (기본 true).\n   * 단독 사용 시엔 항상 자기 자신의 에러에 반응해 포커싱한다.\n   * `useAdminForm.field()` 로 여러 필드를 한 폼에서 쓸 때는, 제출 시 여러 필드가\n   * 동시에 invalid 가 될 수 있어 폼이 \"가장 먼저 있는 오류 필드\"만 true 로 지정해준다\n   * (그 외 필드는 false 로 지정되어 포커스를 가져가지 않는다) — 별도 설정 없이 자동 적용됨.\n   */\n  autoFocusOnError?: boolean;\n  /**\n   * (내부용) `useAdminForm` 이 validate() 를 호출할 때마다 증가시키는 값.\n   * 같은 필드가 여전히 invalid 인 상태에서 제출을 다시 눌러도 재포커싱되도록 트리거한다.\n   */\n  focusToken?: number;\n\n  /** 커스텀 컨트롤 (주면 type 자동 생성 대신 이걸 쓴다) */\n  children?: ReactNode;\n}\n\nexport function AdminFormField({\n  label,\n  htmlFor,\n  required,\n  description,\n  error,\n  orientation = \"vertical\",\n  labelClassName,\n  className,\n  type,\n  value,\n  onChange,\n  placeholder,\n  validate,\n  forceValidate,\n  inputProps,\n  rows,\n  options,\n  selectProps,\n  switchProps,\n  uploadProps,\n  autoFocusOnError = true,\n  focusToken,\n  children,\n}: AdminFormFieldProps) {\n  const horizontal = orientation === \"horizontal\";\n\n  // blur 이후(touched) 또는 제출(forceValidate) 시점부터 검증 결과를 보여준다.\n  const [touched, setTouched] = useState(false);\n\n  // 표시할 오류: 부모가 준 error 가 우선, 없으면 아래 규칙으로 자동 검증.\n  // - 빈 값 + required: \"제출(forceValidate)\" 때만 표시 (blur 만으로는 안 띄움)\n  // - 값이 있을 때 형식 오류(이메일 등): blur 후 또는 제출 시 표시\n  let builtinError: string | undefined;\n  if (!children && type) {\n    const raw = String(value ?? \"\");\n    const v = raw.trim();\n    if (!v) {\n      builtinError = required && forceValidate ? \"필수 입력 항목입니다.\" : undefined;\n    } else if (touched || forceValidate) {\n      builtinError = validate ? validate(raw) : validateValue(type, value);\n    }\n  }\n  const shownError = error ?? builtinError;\n  const invalid = shownError != null;\n\n  // 포커스 규칙: autoFocusOnError=false 인 필드는 절대 포커스를 가져가지 않는다\n  // (useAdminForm 이 \"가장 먼저 있는 오류 필드\"에만 true 를 준다 — 나머지는 항상 false).\n  // 그 외에는 에러가 \"새로 나타난\" 순간(false -> true 전이) 또는 focusToken 이\n  // 바뀐(=다시 제출을 누른) 순간에 포커싱한다. ref 는 컴포넌트 내부에서만 사용 —\n  // 쓰는 쪽(form.field(...))은 아무것도 추가하지 않아도 된다.\n  const inputRef = useRef<HTMLInputElement>(null);\n  const textareaRef = useRef<HTMLTextAreaElement>(null);\n  const selectRef = useRef<AdminSelectHandle>(null);\n  const uploadRef = useRef<AdminImageUploadHandle>(null);\n  const switchRef = useRef<HTMLButtonElement>(null);\n  const wasInvalid = useRef(false);\n  const prevFocusToken = useRef(focusToken);\n  useEffect(() => {\n    const tokenChanged =\n      focusToken !== undefined && focusToken !== prevFocusToken.current;\n    const newlyInvalid = invalid && !wasInvalid.current;\n    if (autoFocusOnError && invalid && (newlyInvalid || tokenChanged)) {\n      if (type === \"select\") selectRef.current?.focus();\n      else if (type === \"textarea\") textareaRef.current?.focus();\n      else if (type === \"upload\") uploadRef.current?.focus();\n      else if (type === \"switch\") switchRef.current?.focus();\n      else inputRef.current?.focus();\n    }\n    wasInvalid.current = invalid;\n    prevFocusToken.current = focusToken;\n  }, [invalid, focusToken, autoFocusOnError, type]);\n\n  // type 기반 자동 입력 (children 이 없을 때)\n  let autoControl: ReactNode = null;\n  if (!children && type) {\n    if (type === \"select\") {\n      autoControl = (\n        <AdminSelect\n          ref={selectRef}\n          id={htmlFor}\n          options={options ?? []}\n          value={value != null ? String(value) : \"\"}\n          onChange={(v) => onChange?.(v)}\n          placeholder={placeholder}\n          onBlur={() => setTouched(true)}\n          {...selectProps}\n        />\n      );\n    } else if (type === \"textarea\") {\n      autoControl = (\n        <textarea\n          ref={textareaRef}\n          id={htmlFor}\n          rows={rows ?? 3}\n          placeholder={placeholder}\n          aria-invalid={invalid ? true : undefined}\n          onBlur={() => setTouched(true)}\n          value={value ?? \"\"}\n          onChange={(e) => onChange?.(e.target.value)}\n          className=\"flex w-full min-w-0 appearance-none resize-y rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-xs transition-colors outline-none placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20\"\n        />\n      );\n    } else if (type === \"switch\") {\n      const offOption = options?.[0];\n      const onOption = options?.[1];\n      const checked = onOption != null && String(value) === String(onOption.value);\n      const activeLabel = checked ? onOption?.label : offOption?.label;\n      autoControl = (\n        <div className=\"flex items-center gap-2 pt-0.5\">\n          <Switch\n            ref={switchRef}\n            id={htmlFor}\n            checked={checked}\n            onCheckedChange={(next: boolean) => {\n              setTouched(true);\n              onChange?.(String(next ? onOption?.value : offOption?.value));\n            }}\n            {...switchProps}\n          />\n          {activeLabel != null && (\n            <span className=\"text-sm text-muted-foreground\">{activeLabel}</span>\n          )}\n        </div>\n      );\n    } else if (type === \"upload\") {\n      autoControl = (\n        <AdminImageUpload\n          ref={uploadRef}\n          value={value ? [String(value)] : []}\n          onChange={(urls) => onChange?.(urls[0] ?? \"\")}\n          maxCount={1}\n          {...uploadProps}\n        />\n      );\n    } else if (FORMATTED_TYPES.includes(type as ColumnFormatType)) {\n      autoControl = (\n        <Input\n          ref={inputRef}\n          id={htmlFor}\n          inputMode=\"numeric\"\n          placeholder={placeholder}\n          aria-invalid={invalid ? true : undefined}\n          onBlur={() => setTouched(true)}\n          value={\n            value === \"\" || value == null\n              ? \"\"\n              : formatByType(type as ColumnFormatType, value)\n          }\n          onChange={(e) => {\n            const max = MAX_DIGITS[type as ColumnFormatType];\n            let digits = e.target.value.replace(/[^\\d]/g, \"\");\n            if (max) digits = digits.slice(0, max);\n            onChange?.(digits);\n          }}\n          {...inputProps}\n        />\n      );\n    } else {\n      autoControl = (\n        <Input\n          ref={inputRef}\n          id={htmlFor}\n          type={type}\n          placeholder={placeholder}\n          aria-invalid={invalid ? true : undefined}\n          onBlur={() => setTouched(true)}\n          value={value ?? \"\"}\n          onChange={(e) => onChange?.(e.target.value)}\n          {...inputProps}\n        />\n      );\n    }\n  }\n\n  const control = children ?? autoControl;\n\n  const labelEl = label ? (\n    <Label\n      htmlFor={htmlFor}\n      className={cn(\n        horizontal && \"shrink-0 pt-2 sm:w-28\",\n        !horizontal && \"mb-1.5\",\n        labelClassName\n      )}\n    >\n      {label}\n      {required && <span className=\"ml-0.5 text-destructive\">*</span>}\n    </Label>\n  ) : null;\n\n  const messageEl =\n    shownError != null ? (\n      <p className=\"mt-1.5 text-xs text-destructive\">{shownError}</p>\n    ) : description != null ? (\n      <p className=\"mt-1.5 text-xs text-muted-foreground\">{description}</p>\n    ) : null;\n\n  if (horizontal) {\n    return (\n      <div\n        className={cn(\"flex flex-col gap-1.5 sm:flex-row sm:gap-4\", className)}\n      >\n        {labelEl}\n        <div className=\"min-w-0 flex-1\">\n          {control}\n          {messageEl}\n        </div>\n      </div>\n    );\n  }\n\n  return (\n    <div className={cn(\"flex flex-col\", className)}>\n      {labelEl}\n      {control}\n      {messageEl}\n    </div>\n  );\n}\n","\"use client\";\n\n/**\n * useAdminForm — 폼 값 + 검증 + 제출 표시를 한 번에 관리하는 훅\n *\n * 필드마다 value/onChange/forceValidate 를 직접 만들 필요 없이 field() 가 묶어준다.\n * 저장 버튼 onClick 에서 form.validate() 한 줄로 전체 검증 + 오류 표시가 된다.\n *\n * @example\n * const form = useAdminForm({ name: \"\", email: \"\", password: \"\" });\n *\n * <AdminFormField label=\"이름\" {...form.field(\"name\", { required: true, type: \"text\" })} />\n * <AdminFormField label=\"이메일\" {...form.field(\"email\", { required: true, type: \"email\" })} />\n *\n * <Button\n *   onClick={() => {\n *     if (form.validate()) {     // 전체 검증 + 오류 표시\n *       save(form.values);       // 통과 시에만 저장\n *       form.reset();\n *     }\n *   }}\n * >\n *   저장\n * </Button>\n *\n * // 상세 조회 결과로 채우기: 없는/null 필드는 initial 값으로 자동 채워지므로\n * // 필드마다 `detail.x ?? \"\"` 를 나열할 필요가 없다.\n * useEffect(() => {\n *   if (open) form.reset(mode === \"add\" ? undefined : detail);\n * }, [open, detail]);\n */\nimport { useRef, useState } from \"react\";\n\nimport {\n  type FieldRule,\n  getFieldError,\n} from \"./admin-form-field\";\n\nexport function useAdminForm<T extends Record<string, unknown>>(\n  initial: { [K in keyof T]: string }\n) {\n  // 폼이 실제로 다루는 값의 타입 — T 는 필드 이름(keyof)만 빌려오고,\n  // 값 자체는 항상 string 으로 고정한다. T 의 필드가 `string | null` 이어도\n  // (API 원본 타입을 그대로 Pick 해서 쓰는 경우가 많다) initial 을 문자열로만\n  // 채우면 그대로 통과한다 — 컨트롤드 input 은 어차피 항상 문자열이기 때문.\n  type Values = { [K in keyof T]: string };\n\n  const [values, setValues] = useState<Values>(initial);\n  const [submitted, setSubmitted] = useState(false);\n  // 각 필드의 검증 규칙 (field() 호출 시 등록)\n  const rules = useRef<Partial<Record<keyof T, FieldRule>>>({});\n  // field() 가 호출된 순서 (등록된 순서 = 화면에 나열된 순서로 간주)\n  const fieldOrder = useRef<(keyof T)[]>([]);\n  // validate() 시점에 \"가장 먼저 있는 오류 필드\"만 포커싱하도록 지정\n  const [focusTarget, setFocusTarget] = useState<keyof T | null>(null);\n  // 같은 필드가 여전히 invalid 여도 재제출 시 다시 포커싱되도록 매 validate() 마다 증가\n  const [focusToken, setFocusToken] = useState(0);\n\n  /** AdminFormField 에 스프레드할 props 를 만든다. */\n  const field = (name: keyof T, rule: FieldRule = {}) => {\n    rules.current[name] = rule;\n    if (!fieldOrder.current.includes(name)) fieldOrder.current.push(name);\n    return {\n      value: values[name],\n      onChange: (v: string) =>\n        setValues((s) => ({ ...s, [name]: v }) as Values),\n      type: rule.type,\n      required: rule.required,\n      validate: rule.validate,\n      forceValidate: submitted,\n      autoFocusOnError: focusTarget === name,\n      focusToken,\n    };\n  };\n\n  /** 특정 필드의 현재 오류 (없으면 undefined) */\n  const errorOf = (name: keyof T) =>\n    getFieldError(rules.current[name] ?? {}, values[name]);\n\n  /** 전체 검증 + 오류 표시. 모두 통과하면 true. 가장 먼저 있는 오류 필드로 포커스를 옮긴다. */\n  const validate = () => {\n    setSubmitted(true);\n    const firstInvalid = fieldOrder.current.find((name) => !!errorOf(name));\n    setFocusTarget(firstInvalid ?? null);\n    setFocusToken((t) => t + 1);\n    return firstInvalid === undefined;\n  };\n\n  /**\n   * 값/제출 상태 초기화.\n   * source 를 넘기면 initial 의 각 필드를 기준으로, source 에 값이 있는 필드만 덮어써서 리셋한다\n   * (undefined/null 인 필드는 initial 값 그대로 유지 — 필드별 `?? \"\"` 나열이 필요 없다).\n   */\n  const reset = (source?: Partial<Record<keyof T, unknown>> | null) => {\n    if (!source) {\n      setValues(initial);\n    } else {\n      const next = { ...initial };\n      (Object.keys(initial) as (keyof T)[]).forEach((key) => {\n        const v = source[key];\n        if (v !== undefined && v !== null) {\n          // object/array 필드(예: address_json)는 String(v) 하면 \"[object Object]\"가\n          // 되어버리므로 JSON.stringify 로 직렬화한다 — select 의 number 필드처럼\n          // 원시값은 그대로 String() 으로 문자열화한다.\n          next[key] = (\n            typeof v === \"object\" ? JSON.stringify(v) : String(v)\n          ) as Values[keyof T];\n        }\n      });\n      setValues(next);\n    }\n    setSubmitted(false);\n    setFocusTarget(null);\n  };\n\n  return { values, setValues, submitted, setSubmitted, field, errorOf, validate, reset };\n}\n\n/** useAdminForm() 반환 타입. 단계별로 나뉜 폼 하위 컴포넌트에 form 을 props 로 넘길 때 사용한다. */\nexport type UseAdminFormReturn<T extends Record<string, unknown>> = ReturnType<\n  typeof useAdminForm<T>\n>;\n","\"use client\";\n\n/**\n * AdminInput — 라벨 + 입력 컨트롤 (경량 버전)\n *\n * AdminDescriptions layout=\"stacked\" 안에서 편집 가능한 필드로 쓰거나,\n * 단독으로 간단한 입력이 필요할 때 사용한다.\n *\n * 복잡한 유효성 검사나 포맷 처리가 필요하면 AdminFormField 를 사용한다.\n *\n * layout 옵션:\n * - \"stacked\"(기본): 라벨이 input 위에 작게(xs, muted) 표시\n * - \"inline\":        라벨이 input 왼쪽에 한 줄로 표시\n *\n * size 옵션: \"sm\" | \"default\" | \"lg\"\n *\n * 추가 기능:\n * - type=\"password\" 일 때 비밀번호 표시/숨김 토글 자동 제공\n * - clearable: 값이 있을 때 X 버튼으로 초기화\n *\n * @example\n * <AdminInput layout=\"stacked\" label=\"아이디\" value={id} onChange={setId} />\n * <AdminInput layout=\"stacked\" label=\"비밀번호\" type=\"password\" value={pw} onChange={setPw} />\n * <AdminInput layout=\"stacked\" label=\"검색\" clearable value={q} onChange={setQ} />\n */\nimport { type ComponentProps, type ReactNode, useId, useState } from \"react\";\nimport { Eye, EyeOff, X } from \"lucide-react\";\nimport { cn } from \"../../lib/utils\";\nimport { Label } from \"../ui/label\";\n\nexport type AdminInputSize = \"sm\" | \"default\" | \"lg\";\n\nconst SIZE_CLASS: Record<AdminInputSize, string> = {\n  sm:      \"h-8 text-xs\",\n  default: \"h-10 text-sm\",\n  lg:      \"h-12 text-base\",\n};\n\nconst ICON_SIZE: Record<AdminInputSize, number> = {\n  sm:      13,\n  default: 15,\n  lg:      20,\n};\n\n// 버튼 자체 padding\nconst BTN_PAD: Record<AdminInputSize, string> = {\n  sm:      \"p-0.5\",\n  default: \"p-1\",\n  lg:      \"p-1.5\",\n};\n\n// input 오른쪽 여백 (버튼 수 × 크기)\nconst RIGHT_PAD: Record<AdminInputSize, { none: string; one: string; two: string }> = {\n  sm:      { none: \"pr-3\", one: \"pr-8\",  two: \"pr-14\" },\n  default: { none: \"pr-3\", one: \"pr-9\",  two: \"pr-16\" },\n  lg:      { none: \"pr-4\", one: \"pr-12\", two: \"pr-20\" },\n};\n\nexport interface AdminInputProps\n  extends Omit<ComponentProps<\"input\">, \"onChange\" | \"size\"> {\n  /**\n   * 레이아웃 방식\n   * - \"stacked\"(기본): 라벨 위, input 아래\n   * - \"inline\": 라벨 왼쪽, input 오른쪽\n   */\n  layout?: \"stacked\" | \"inline\";\n  /** 입력 크기: \"sm\" | \"default\"(기본) | \"lg\" */\n  size?: AdminInputSize;\n  /** 필드 라벨 */\n  label?: ReactNode;\n  /** inline 일 때 라벨 너비 클래스 (기본 w-24) */\n  labelClassName?: string;\n  /** 입력값 변경 콜백 */\n  onChange?: (value: string) => void;\n  /** 값이 있을 때 X 버튼으로 초기화 */\n  clearable?: boolean;\n  /** 입력 아래 도움말 / 에러 메시지 */\n  hint?: ReactNode;\n  /** hint 를 에러(빨간색)로 표시 */\n  error?: boolean;\n  className?: string;\n  /**\n   * useAdminForm().field() 의 반환값을 그대로 스프레드해서 쓸 수 있도록 받아두는 값.\n   * AdminInput 은 검증 UI를 그리지 않으므로 실제로는 사용하지 않는다 (필요하면 AdminFormField 사용).\n   */\n  validate?: (value: string) => string | undefined;\n  forceValidate?: boolean;\n  /** useAdminForm().field() 반환값 스프레드용 — AdminInput 은 자동 포커싱을 지원하지 않으므로 사용하지 않는다. */\n  autoFocusOnError?: boolean;\n  /** useAdminForm().field() 반환값 스프레드용 — 위와 동일한 이유로 사용하지 않는다. */\n  focusToken?: number;\n}\n\nexport function AdminInput({\n  layout = \"stacked\",\n  size = \"default\",\n  label,\n  labelClassName,\n  onChange,\n  clearable,\n  hint,\n  error,\n  className,\n  id: idProp,\n  type,\n  value,\n  validate: _validate,\n  forceValidate: _forceValidate,\n  autoFocusOnError: _autoFocusOnError,\n  focusToken: _focusToken,\n  ...inputProps\n}: AdminInputProps) {\n  const autoId = useId();\n  const id = idProp ?? autoId;\n  const isPassword = type === \"password\";\n  const [showPw, setShowPw] = useState(false);\n  const iconSize = ICON_SIZE[size];\n\n  const hasRight = clearable || isPassword;\n  const clearActive = clearable && value !== \"\" && value != null;\n  const btnCount = (clearable ? 1 : 0) + (isPassword ? 1 : 0);\n  const rightPadding = RIGHT_PAD[size][btnCount === 2 ? \"two\" : hasRight ? \"one\" : \"none\"];\n\n  const inputEl = (\n    <div className=\"relative\">\n      <input\n        id={id}\n        type={isPassword ? (showPw ? \"text\" : \"password\") : type}\n        value={value}\n        aria-invalid={error ? true : undefined}\n        onChange={(e) => onChange?.(e.target.value)}\n        className={cn(\n          \"flex w-full min-w-0 appearance-none rounded-md border border-input bg-transparent pl-3 shadow-xs transition-colors outline-none\",\n          \"placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground\",\n          \"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]\",\n          \"disabled:cursor-not-allowed disabled:opacity-50\",\n          \"aria-invalid:border-destructive aria-invalid:ring-destructive/20\",\n          SIZE_CLASS[size],\n          rightPadding\n        )}\n        {...inputProps}\n      />\n\n      {/* 오른쪽 버튼 영역 */}\n      {hasRight && (\n        <div className=\"absolute inset-y-0 right-0 flex items-center pr-1\">\n          {/* Clear 버튼 */}\n          {clearable && (\n            <button\n              type=\"button\"\n              tabIndex={-1}\n              onClick={() => onChange?.(\"\")}\n              className={cn(\n                \"flex items-center justify-center rounded text-muted-foreground transition-opacity hover:text-foreground\",\n                BTN_PAD[size],\n                clearActive ? \"opacity-100\" : \"pointer-events-none opacity-0\"\n              )}\n              aria-label=\"입력 초기화\"\n            >\n              <X size={iconSize} />\n            </button>\n          )}\n\n          {/* Password 토글 버튼 */}\n          {isPassword && (\n            <button\n              type=\"button\"\n              tabIndex={-1}\n              onClick={() => setShowPw((v) => !v)}\n              className={cn(\"flex items-center justify-center rounded text-muted-foreground transition-colors hover:text-foreground\", BTN_PAD[size])}\n              aria-label={showPw ? \"비밀번호 숨기기\" : \"비밀번호 보기\"}\n            >\n              {showPw ? <EyeOff size={iconSize} /> : <Eye size={iconSize} />}\n            </button>\n          )}\n        </div>\n      )}\n    </div>\n  );\n\n  const hintEl = hint ? (\n    <p className={cn(\"mt-1 text-xs\", error ? \"text-destructive\" : \"text-muted-foreground\")}>\n      {hint}\n    </p>\n  ) : null;\n\n  if (!label) {\n    return (\n      <div className={className}>\n        {inputEl}\n        {hintEl}\n      </div>\n    );\n  }\n\n  if (layout === \"inline\") {\n    return (\n      <div className={cn(\"flex items-center gap-3\", className)}>\n        <Label\n          htmlFor={id}\n          className={cn(\"shrink-0 text-sm text-muted-foreground\", labelClassName ?? \"w-24\")}\n        >\n          {label}\n        </Label>\n        <div className=\"min-w-0 flex-1\">\n          {inputEl}\n          {hintEl}\n        </div>\n      </div>\n    );\n  }\n\n  // stacked\n  return (\n    <div className={cn(\"flex flex-col gap-1\", className)}>\n      <Label htmlFor={id} className=\"text-xs text-muted-foreground\">\n        {label}\n      </Label>\n      {inputEl}\n      {hintEl}\n    </div>\n  );\n}\n","\"use client\";\n\n/**\n * AdminTextarea — 라벨 + 여러 줄 입력 컨트롤\n *\n * AdminInput 의 textarea 버전. 메모/설명처럼 여러 줄이 필요한 필드에 사용한다.\n * 한 줄 입력이면 AdminInput 을 사용한다.\n *\n * layout 옵션:\n * - \"stacked\"(기본): 라벨이 textarea 위에 작게(xs, muted) 표시\n * - \"inline\":        라벨이 textarea 왼쪽에 한 줄로 표시\n *\n * @example\n * <AdminTextarea layout=\"stacked\" label=\"메모\" value={memo} onChange={setMemo} rows={4} />\n */\nimport { type ComponentProps, type ReactNode, useId } from \"react\";\nimport { cn } from \"../../lib/utils\";\nimport { Label } from \"../ui/label\";\n\nexport interface AdminTextareaProps\n  extends Omit<ComponentProps<\"textarea\">, \"onChange\"> {\n  /**\n   * 레이아웃 방식\n   * - \"stacked\"(기본): 라벨 위, textarea 아래\n   * - \"inline\": 라벨 왼쪽, textarea 오른쪽\n   */\n  layout?: \"stacked\" | \"inline\";\n  /** 필드 라벨 */\n  label?: ReactNode;\n  /** inline 일 때 라벨 너비 클래스 (기본 w-24) */\n  labelClassName?: string;\n  /** 입력값 변경 콜백 */\n  onChange?: (value: string) => void;\n  /** 입력 아래 도움말 / 에러 메시지 */\n  hint?: ReactNode;\n  /** hint 를 에러(빨간색)로 표시 */\n  error?: boolean;\n  className?: string;\n  /**\n   * useAdminForm().field() 의 반환값을 그대로 스프레드해서 쓸 수 있도록 받아두는 값.\n   * AdminTextarea 는 검증 UI를 그리지 않으므로 실제로는 사용하지 않는다 (필요하면 AdminFormField 사용).\n   */\n  validate?: (value: string) => string | undefined;\n  forceValidate?: boolean;\n  /** useAdminForm().field() 반환값 스프레드용 — AdminTextarea 는 자동 포커싱을 지원하지 않으므로 사용하지 않는다. */\n  autoFocusOnError?: boolean;\n  /** useAdminForm().field() 반환값 스프레드용 — 위와 동일한 이유로 사용하지 않는다. */\n  focusToken?: number;\n}\n\nexport function AdminTextarea({\n  layout = \"stacked\",\n  label,\n  labelClassName,\n  onChange,\n  hint,\n  error,\n  className,\n  id: idProp,\n  rows = 3,\n  value,\n  validate: _validate,\n  forceValidate: _forceValidate,\n  autoFocusOnError: _autoFocusOnError,\n  focusToken: _focusToken,\n  ...textareaProps\n}: AdminTextareaProps) {\n  const autoId = useId();\n  const id = idProp ?? autoId;\n\n  const textareaEl = (\n    <textarea\n      id={id}\n      rows={rows}\n      value={value}\n      aria-invalid={error ? true : undefined}\n      onChange={(e) => onChange?.(e.target.value)}\n      className={cn(\n        \"flex w-full min-w-0 appearance-none resize-y rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-xs transition-colors outline-none\",\n        \"placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground\",\n        \"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]\",\n        \"disabled:cursor-not-allowed disabled:opacity-50\",\n        \"aria-invalid:border-destructive aria-invalid:ring-destructive/20\"\n      )}\n      {...textareaProps}\n    />\n  );\n\n  const hintEl = hint ? (\n    <p className={cn(\"mt-1 text-xs\", error ? \"text-destructive\" : \"text-muted-foreground\")}>\n      {hint}\n    </p>\n  ) : null;\n\n  if (!label) {\n    return (\n      <div className={className}>\n        {textareaEl}\n        {hintEl}\n      </div>\n    );\n  }\n\n  if (layout === \"inline\") {\n    return (\n      <div className={cn(\"flex items-start gap-3\", className)}>\n        <Label\n          htmlFor={id}\n          className={cn(\"shrink-0 pt-2 text-sm text-muted-foreground\", labelClassName ?? \"w-24\")}\n        >\n          {label}\n        </Label>\n        <div className=\"min-w-0 flex-1\">\n          {textareaEl}\n          {hintEl}\n        </div>\n      </div>\n    );\n  }\n\n  // stacked\n  return (\n    <div className={cn(\"flex flex-col gap-1\", className)}>\n      <Label htmlFor={id} className=\"text-xs text-muted-foreground\">\n        {label}\n      </Label>\n      {textareaEl}\n      {hintEl}\n    </div>\n  );\n}\n","\"use client\";\n\n/**\n * AdminDateInput — 날짜 입력 공통 컴포넌트 (type=\"date\")\n *\n * 브라우저 기본 날짜 표시(로케일 의존 점 형식)를 숨기고,\n * 직접 \"YYYY-MM-DD\" 형식 또는 placeholder 를 그린다.\n * 클릭 시 네이티브 달력 picker 를 연다.\n *\n * 값은 \"YYYY-MM-DD\" 문자열로 주고받는다.\n *\n * @example\n * const [date, setDate] = useState(\"\");\n * <AdminDateInput\n *   value={date}\n *   onChange={setDate}\n *   placeholder=\"날짜를 선택하세요\"\n * />\n *\n * @example // 범위 제한\n * <AdminDateInput value={start} onChange={setStart} max={end} />\n * <AdminDateInput value={end}   onChange={setEnd}   min={start} />\n */\nimport { forwardRef } from \"react\";\n\nimport { cn } from \"../../lib/utils\";\n\nexport interface AdminDateInputProps {\n    /** \"YYYY-MM-DD\" 형식 날짜 문자열 */\n    value?: string;\n    onChange?: (value: string) => void;\n    /** 값이 없을 때 표시할 안내 문구 (기본 \"날짜를 선택하세요\") */\n    placeholder?: string;\n    /** 선택 가능한 최솟값 (\"YYYY-MM-DD\") */\n    min?: string;\n    /** 선택 가능한 최댓값 (\"YYYY-MM-DD\") */\n    max?: string;\n    disabled?: boolean;\n    /** 추가 CSS 클래스 */\n    className?: string;\n    \"aria-label\"?: string;\n    id?: string;\n}\n\n/** 클릭 시 네이티브 달력을 연다. */\nfunction openPicker(e: React.MouseEvent<HTMLInputElement>) {\n    try {\n        (e.currentTarget as HTMLInputElement).showPicker?.();\n    } catch {\n        /* showPicker 미지원 시 기본 동작 유지 */\n    }\n}\n\nexport const AdminDateInput = forwardRef<HTMLInputElement, AdminDateInputProps>(\n    function AdminDateInput(\n        {\n            value = \"\",\n            onChange,\n            placeholder = \"날짜를 선택하세요\",\n            min,\n            max,\n            disabled,\n            className,\n            \"aria-label\": ariaLabel,\n            id,\n        },\n        ref\n    ) {\n        return (\n            <input\n                ref={ref}\n                id={id}\n                type=\"date\"\n                aria-label={ariaLabel}\n                value={value}\n                min={min}\n                max={max}\n                disabled={disabled}\n                onChange={(e) => onChange?.(e.target.value)}\n                onClick={openPicker}\n                // data-display: ::before 가상 요소가 이 값을 직접 렌더링한다 (globals.css .admin-date-input)\n                data-display={value || placeholder}\n                // data-empty: placeholder 일 때 회색으로 표시한다\n                data-empty={value ? \"false\" : \"true\"}\n                className={cn(\n                    \"admin-date-input\",\n                    // shadcn Input 기본 스타일에 맞춤\n                    \"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-xs outline-none\",\n                    \"focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50\",\n                    \"disabled:pointer-events-none disabled:opacity-50\",\n                    className\n                )}\n            />\n        );\n    }\n);\n","\"use client\";\n\n/**\n * Calendar — react-day-picker v10 래퍼 (shadcn/ui 스타일, 한국어)\n *\n * 헤더: [이전] [연도 드롭다운] [월 드롭다운] [다음] — 겹침 없이 한 줄로 배치.\n * AdminDatePicker 내부에서 사용하며, 직접 사용도 가능하다.\n *\n * @example\n * <Calendar mode=\"single\" selected={date} onSelect={setDate} />\n *\n * @example // 선택 가능 연도 범위 지정\n * <Calendar mode=\"single\" selected={date} onSelect={setDate}\n *   startMonth={new Date(1950, 0)} endMonth={new Date(2010, 11)} />\n */\nimport { createContext, useContext } from \"react\";\nimport type { MonthCaptionProps } from \"react-day-picker\";\nimport { ChevronLeft, ChevronRight } from \"lucide-react\";\nimport { DayPicker, useDayPicker } from \"react-day-picker\";\nimport { ko } from \"react-day-picker/locale\";\n\nimport { cn } from \"../../lib/utils\";\n\nexport type CalendarProps = React.ComponentProps<typeof DayPicker>;\n\nconst TODAY = new Date();\n\nconst MONTHS_KO = [\n    \"1월\", \"2월\", \"3월\", \"4월\", \"5월\", \"6월\",\n    \"7월\", \"8월\", \"9월\", \"10월\", \"11월\", \"12월\",\n];\n\nconst selectCls =\n    \"h-8 cursor-pointer rounded-md border border-input bg-transparent px-2 text-sm font-medium \" +\n    \"outline-none hover:bg-accent focus:border-ring focus:ring-[3px] focus:ring-ring/50\";\n\nconst navBtnCls =\n    \"inline-flex size-7 shrink-0 items-center justify-center rounded-md border border-input bg-transparent \" +\n    \"text-muted-foreground shadow-xs transition-colors hover:bg-accent hover:text-accent-foreground \" +\n    \"disabled:pointer-events-none disabled:opacity-40\";\n\n/** 연도 범위를 DropdownCaption 으로 전달하기 위한 내부 context */\nconst YearRangeCtx = createContext({\n    startYear: TODAY.getFullYear() - 100,\n    endYear: TODAY.getFullYear() + 10,\n});\n\n/**\n * 헤더를 통째로 교체한 커스텀 MonthCaption.\n * prev 버튼 · 연도 select · 월 select · next 버튼을 한 flex 행에 배치해\n * absolute 포지션 없이도 겹침이 생기지 않는다.\n */\nfunction DropdownCaption({ calendarMonth }: MonthCaptionProps) {\n    const { startYear, endYear } = useContext(YearRangeCtx);\n    const { goToMonth, previousMonth, nextMonth } = useDayPicker();\n\n    const date = calendarMonth.date;\n    const year = date.getFullYear();\n    const month = date.getMonth(); // 0-indexed\n\n    const years = Array.from(\n        { length: endYear - startYear + 1 },\n        (_, i) => startYear + i,\n    );\n\n    return (\n        <div className=\"flex w-full items-center justify-between gap-1\">\n            {/* 이전 달 */}\n            <button\n                type=\"button\"\n                aria-label=\"이전 달\"\n                disabled={!previousMonth}\n                onClick={() => previousMonth && goToMonth(previousMonth)}\n                className={navBtnCls}\n            >\n                <ChevronLeft className=\"size-4\" />\n            </button>\n\n            {/* 연도 · 월 드롭다운 */}\n            <div className=\"flex items-center gap-1.5\">\n                <select\n                    value={year}\n                    onChange={(e) =>\n                        goToMonth(new Date(Number(e.target.value), month))\n                    }\n                    className={selectCls}\n                >\n                    {years.map((y) => (\n                        <option key={y} value={y}>{y}년</option>\n                    ))}\n                </select>\n                <select\n                    value={month}\n                    onChange={(e) =>\n                        goToMonth(new Date(year, Number(e.target.value)))\n                    }\n                    className={selectCls}\n                >\n                    {MONTHS_KO.map((label, i) => (\n                        <option key={i} value={i}>{label}</option>\n                    ))}\n                </select>\n            </div>\n\n            {/* 다음 달 */}\n            <button\n                type=\"button\"\n                aria-label=\"다음 달\"\n                disabled={!nextMonth}\n                onClick={() => nextMonth && goToMonth(nextMonth)}\n                className={navBtnCls}\n            >\n                <ChevronRight className=\"size-4\" />\n            </button>\n        </div>\n    );\n}\n\nexport function Calendar({\n    className,\n    classNames,\n    showOutsideDays = true,\n    startMonth,\n    endMonth,\n    ...props\n}: CalendarProps) {\n    const startYear = (startMonth ?? new Date(TODAY.getFullYear() - 100, 0)).getFullYear();\n    const endYear = (endMonth ?? new Date(TODAY.getFullYear() + 10, 11)).getFullYear();\n\n    return (\n        <YearRangeCtx.Provider value={{ startYear, endYear }}>\n            <DayPicker\n                locale={ko}\n                showOutsideDays={showOutsideDays}\n                {...(startMonth ? { startMonth } : {})}\n                {...(endMonth ? { endMonth } : {})}\n                className={cn(\"p-3\", className)}\n                classNames={{\n                    months: \"flex flex-col gap-4\",\n                    month: \"flex flex-col gap-4\",\n                    /* 캡션 행: DropdownCaption 이 full-width flex 행을 담당 */\n                    month_caption: \"flex h-9 items-center\",\n                    caption_label: \"hidden\",\n                    /* 원본 nav 는 DropdownCaption 안에서 처리하므로 숨김 */\n                    nav: \"hidden\",\n                    /* 날짜 그리드 */\n                    month_grid: \"w-full border-collapse\",\n                    weekdays: \"flex\",\n                    weekday:\n                        \"w-8 text-center text-[0.75rem] font-normal text-muted-foreground\",\n                    week: \"mt-2 flex\",\n                    /* 날짜 셀·버튼 */\n                    day: \"h-8 w-8 p-0 text-center text-sm\",\n                    day_button: cn(\n                        \"flex size-8 items-center justify-center rounded-md font-normal transition-colors\",\n                        \"hover:bg-accent hover:text-accent-foreground\",\n                        \"focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\",\n                        \"disabled:pointer-events-none disabled:opacity-30\",\n                    ),\n                    /* 상태 수식 클래스 */\n                    selected:\n                        \"bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground\",\n                    today: \"bg-accent text-accent-foreground\",\n                    outside: \"text-muted-foreground opacity-40\",\n                    disabled: \"pointer-events-none opacity-30\",\n                    range_start: \"rounded-l-md\",\n                    range_end: \"rounded-r-md\",\n                    range_middle:\n                        \"rounded-none bg-accent text-accent-foreground\",\n                    hidden: \"invisible\",\n                    ...classNames,\n                }}\n                components={{\n                    /* 원본 Chevron 은 DropdownCaption 에서 직접 쓰므로 빈 컴포넌트 */\n                    MonthCaption: DropdownCaption,\n                }}\n                {...props}\n            />\n        </YearRangeCtx.Provider>\n    );\n}\n","\"use client\";\n\n/**\n * AdminDatePicker — 달력 팝오버 date picker 공통 컴포넌트\n *\n * 입력창을 클릭하면 달력 팝오버가 열리고 날짜를 선택하면 닫힌다.\n * 값은 \"YYYY-MM-DD\" 문자열로 주고받는다.\n *\n * @example\n * const [date, setDate] = useState(\"\");\n * <AdminDatePicker value={date} onChange={setDate} placeholder=\"생년월일\" />\n *\n * @example // 범위 제한\n * <AdminDatePicker value={date} onChange={setDate} min=\"2020-01-01\" max=\"2026-12-31\" />\n *\n * @example // 지우기 버튼\n * <AdminDatePicker value={date} onChange={setDate} clearable />\n */\nimport { useState } from \"react\";\nimport { CalendarIcon, X } from \"lucide-react\";\n\nimport { cn } from \"../../lib/utils\";\nimport { Calendar } from \"../ui/calendar\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"../ui/popover\";\n\nexport interface AdminDatePickerProps {\n    /** \"YYYY-MM-DD\" 날짜 문자열 */\n    value?: string;\n    onChange?: (value: string) => void;\n    /** 빈 값일 때 표시 문구 (기본 \"날짜를 선택하세요\") */\n    placeholder?: string;\n    /** 선택 가능 최솟값 (\"YYYY-MM-DD\") */\n    min?: string;\n    /** 선택 가능 최댓값 (\"YYYY-MM-DD\") */\n    max?: string;\n    /** X 버튼으로 값 지우기 허용 (기본 false) */\n    clearable?: boolean;\n    disabled?: boolean;\n    className?: string;\n    /** 입력창 너비 클래스 (기본 w-full) */\n    widthClassName?: string;\n    id?: string;\n    \"aria-label\"?: string;\n}\n\n/** \"YYYY-MM-DD\" → Date (로컬 타임존) */\nfunction parseDate(ymd: string | undefined): Date | undefined {\n    if (!ymd) return undefined;\n    const [y, m, d] = ymd.split(\"-\").map(Number);\n    if (!y || !m || !d) return undefined;\n    return new Date(y, m - 1, d);\n}\n\n/** Date → \"YYYY-MM-DD\" */\nfunction formatDate(date: Date): string {\n    const y = date.getFullYear();\n    const m = String(date.getMonth() + 1).padStart(2, \"0\");\n    const d = String(date.getDate()).padStart(2, \"0\");\n    return `${y}-${m}-${d}`;\n}\n\nexport function AdminDatePicker({\n    value = \"\",\n    onChange,\n    placeholder = \"날짜를 선택하세요\",\n    min,\n    max,\n    clearable = false,\n    disabled,\n    className,\n    widthClassName = \"w-full\",\n    id,\n    \"aria-label\": ariaLabel,\n}: AdminDatePickerProps) {\n    const [open, setOpen] = useState(false);\n\n    const selected = parseDate(value);\n    const minDate = parseDate(min);\n    const maxDate = parseDate(max);\n\n    // 선택값이 없을 때 달력이 열릴 기본 월.\n    // max 가 있으면 max 월, 없으면 min 월, 둘 다 없으면 현재 월.\n    const defaultMonth = selected ?? maxDate ?? minDate;\n\n    const handleSelect = (date: Date | undefined) => {\n        onChange?.(date ? formatDate(date) : \"\");\n        if (date) setOpen(false); // 날짜 선택 시 팝오버 자동 닫기\n    };\n\n    const handleClear = (e: React.MouseEvent) => {\n        e.stopPropagation();\n        onChange?.(\"\");\n    };\n\n    return (\n        <Popover open={open} onOpenChange={disabled ? undefined : setOpen}>\n            <PopoverTrigger asChild>\n                <button\n                    id={id}\n                    type=\"button\"\n                    aria-label={ariaLabel ?? placeholder}\n                    aria-expanded={open}\n                    disabled={disabled}\n                    className={cn(\n                        \"flex h-9 items-center gap-2 rounded-md border border-input bg-transparent px-3 text-sm shadow-xs\",\n                        \"focus-visible:outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50\",\n                        \"disabled:pointer-events-none disabled:opacity-50\",\n                        \"text-left\",\n                        widthClassName,\n                        className\n                    )}\n                >\n                    <CalendarIcon className=\"size-4 shrink-0 text-muted-foreground\" />\n                    <span\n                        className={cn(\n                            \"flex-1 truncate\",\n                            !value && \"text-muted-foreground\"\n                        )}\n                    >\n                        {value || placeholder}\n                    </span>\n                    {/* 지우기 버튼 */}\n                    {clearable && value && !disabled && (\n                        <span\n                            role=\"button\"\n                            aria-label=\"날짜 초기화\"\n                            onClick={handleClear}\n                            className=\"shrink-0 rounded-sm text-muted-foreground hover:text-foreground\"\n                        >\n                            <X className=\"size-3.5\" />\n                        </span>\n                    )}\n                </button>\n            </PopoverTrigger>\n\n            <PopoverContent className=\"w-auto p-0\" align=\"start\">\n                <Calendar\n                    mode=\"single\"\n                    selected={selected}\n                    onSelect={handleSelect}\n                    defaultMonth={defaultMonth}\n                    // 드롭다운 연도·월 범위를 min/max 에 맞게 제한\n                    {...(minDate ? { startMonth: minDate } : {})}\n                    {...(maxDate ? { endMonth: maxDate } : {})}\n                    // min/max 날짜 바깥은 선택 비활성 (react-day-picker v10 matcher)\n                    {...(minDate || maxDate\n                        ? {\n                              disabled: [\n                                  ...(minDate ? [{ before: minDate }] : []),\n                                  ...(maxDate ? [{ after: maxDate }] : []),\n                              ],\n                          }\n                        : {})}\n                />\n            </PopoverContent>\n        </Popover>\n    );\n}\n","\"use client\";\n\n/**\n * AdminFilter / AdminFilterField — 검색 필터 공통 컴포넌트 (우선순위 5)\n *\n * 데스크탑 상단 고정 필터 영역.\n * - 필터 필드를 \"한 줄에 하나씩\" 세로로 배치한다.\n * - 헤더 바를 클릭하면 필터 영역을 접었다/폈다 할 수 있다. (collapsible)\n * - 각 필드는 왼쪽 라벨 + 오른쪽 컨트롤(children) 구조다. (모바일에선 위/아래 스택)\n *\n * 도메인 비종속: 어떤 필터 필드를 둘지는 children 으로 주입하고,\n * 검색/초기화 동작은 콜백(onSearch/onReset)으로 외부에서 처리한다.\n * (form submit 으로 동작하므로 입력창에서 Enter 시에도 onSearch 가 호출된다.)\n *\n * @example\n * <AdminFilter title=\"검색 필터\" onSearch={handleSearch} onReset={handleReset}>\n *   <AdminFilterField label=\"이름\" htmlFor=\"name\">\n *     <Input id=\"name\" value={name} onChange={(e) => setName(e.target.value)} />\n *   </AdminFilterField>\n *   <AdminFilterField label=\"상태\" htmlFor=\"status\">\n *     <select id=\"status\" ...>...</select>\n *   </AdminFilterField>\n * </AdminFilter>\n */\nimport { type ReactNode, useState } from \"react\";\nimport { ChevronDown, RotateCcw, Search } from \"lucide-react\";\n\nimport { cn } from \"../../lib/utils\";\nimport { Button } from \"../ui/button\";\nimport { Label } from \"../ui/label\";\n\nexport interface AdminFilterProps {\n  /** 필터 입력 필드들 (AdminFilterField 들을 넣는다) */\n  children: ReactNode;\n  /** 검색(submit) 콜백 */\n  onSearch?: () => void;\n  /** 초기화 콜백. 주어지면 초기화 버튼이 표시된다 */\n  onReset?: () => void;\n  /** 필터 헤더 라벨 (기본 \"검색 필터\") */\n  title?: ReactNode;\n  /** 접기/펴기 사용 여부 (기본 true) */\n  collapsible?: boolean;\n  /** 초기 펼침 상태 (기본 true) */\n  defaultOpen?: boolean;\n  /** 검색 버튼 라벨 (기본 \"검색\") */\n  searchLabel?: string;\n  /** 초기화 버튼 라벨 (기본 \"초기화\") */\n  resetLabel?: string;\n  /** 검색 중 비활성화/로딩 표시 */\n  loading?: boolean;\n  /** 버튼 영역에 추가로 둘 액션 */\n  actions?: ReactNode;\n  className?: string;\n}\n\nexport function AdminFilter({\n  children,\n  onSearch,\n  onReset,\n  title = \"검색 필터\",\n  collapsible = true,\n  defaultOpen = true,\n  searchLabel = \"검색\",\n  resetLabel = \"초기화\",\n  loading = false,\n  actions,\n  className,\n}: AdminFilterProps) {\n  const [open, setOpen] = useState(defaultOpen);\n  const expanded = collapsible ? open : true;\n\n  return (\n    <div\n      className={cn(\n        \"rounded-lg border bg-card text-card-foreground shadow-xs\",\n        className\n      )}\n    >\n      {/* 헤더 (접기/펴기 토글) */}\n      {collapsible ? (\n        <button\n          type=\"button\"\n          onClick={() => setOpen((v) => !v)}\n          aria-expanded={expanded}\n          className=\"flex w-full items-center justify-between rounded-t-lg px-4 py-3 text-left text-sm font-medium transition-colors hover:bg-accent/50\"\n        >\n          {title}\n          <ChevronDown\n            className={cn(\n              \"size-4 shrink-0 text-muted-foreground transition-transform\",\n              !expanded && \"-rotate-90\"\n            )}\n          />\n        </button>\n      ) : (\n        title && (\n          <div className=\"px-4 py-3 text-sm font-medium\">{title}</div>\n        )\n      )}\n\n      {expanded && (\n        <form\n          onSubmit={(e) => {\n            e.preventDefault();\n            onSearch?.();\n          }}\n        >\n          {/* 필드: 한 줄에 하나씩 (필드 간 구분선 없이 간격으로 구분) */}\n          <div className=\"space-y-3 border-t px-4 py-4\">{children}</div>\n\n          {/* 버튼 영역 */}\n          <div className=\"flex items-center justify-end gap-2 px-4 pb-4\">\n            {actions}\n            {onReset && (\n              <Button\n                type=\"button\"\n                variant=\"outline\"\n                onClick={onReset}\n                disabled={loading}\n              >\n                <RotateCcw className=\"size-4\" />\n                {resetLabel}\n              </Button>\n            )}\n            <Button type=\"submit\" disabled={loading}>\n              <Search className=\"size-4\" />\n              {searchLabel}\n            </Button>\n          </div>\n        </form>\n      )}\n    </div>\n  );\n}\n\nexport interface AdminFilterFieldProps {\n  /** 필드 라벨 (왼쪽) */\n  label?: ReactNode;\n  /** 라벨과 연결할 입력 요소 id */\n  htmlFor?: string;\n  /** 컨트롤(오른쪽) */\n  children: ReactNode;\n  /** 라벨 영역 너비 클래스 (기본 sm:w-32) */\n  labelClassName?: string;\n  className?: string;\n}\n\nexport function AdminFilterField({\n  label,\n  htmlFor,\n  children,\n  labelClassName,\n  className,\n}: AdminFilterFieldProps) {\n  return (\n    <div\n      className={cn(\n        \"flex flex-col gap-1.5 sm:flex-row sm:items-center sm:gap-4\",\n        className\n      )}\n    >\n      {label && (\n        <Label\n          htmlFor={htmlFor}\n          className={cn(\n            \"shrink-0 text-muted-foreground sm:w-32\",\n            labelClassName\n          )}\n        >\n          {label}\n        </Label>\n      )}\n      <div className=\"min-w-0 flex-1\">{children}</div>\n    </div>\n  );\n}\n","\"use client\";\n\n/**\n * KeywordFilter — 검색어 필터 (검색 유형 선택 + 키워드 입력)\n *\n * 거의 모든 관리자 필터에 들어가는 \"검색어\" 영역을 공통화한 것.\n * AdminFilterField(라벨 좌 / 컨트롤 우)를 품고 있어 AdminFilter 안에 바로 넣으면 된다.\n * 제어 컴포넌트이며, 비즈니스 로직 없이 값/콜백만 받는다.\n *\n * @example\n * <KeywordFilter\n *   typeOptions={[{ value: \"name\", label: \"이름\" }, { value: \"email\", label: \"이메일\" }]}\n *   type={filters.keywordType}\n *   onTypeChange={(v) => setField(\"keywordType\", v)}\n *   keyword={filters.keyword}\n *   onKeywordChange={(v) => setField(\"keyword\", v)}\n * />\n */\nimport type { ReactNode } from \"react\";\n\nimport { cn } from \"../../lib/utils\";\nimport { Input } from \"../ui/input\";\nimport { AdminFilterField } from \"./admin-filter\";\n\nexport interface KeywordTypeOption {\n  value: string;\n  label: string;\n}\n\nexport interface KeywordFilterProps {\n  /** 필드 라벨 (기본 \"검색어\") */\n  label?: ReactNode;\n  /**\n   * 검색 유형 선택 옵션. 주면 키워드 입력 왼쪽에 select 가 표시된다.\n   * (예: 이름/이메일/전화번호 중 무엇으로 검색할지)\n   */\n  typeOptions?: KeywordTypeOption[];\n  /** 선택된 검색 유형 값 */\n  type?: string;\n  onTypeChange?: (value: string) => void;\n  /** 키워드 값 */\n  keyword: string;\n  onKeywordChange: (value: string) => void;\n  /** 입력창 placeholder (기본 \"검색어 입력\") */\n  placeholder?: string;\n  /** 검색 유형 select 의 \"전체\" 옵션 라벨. null 이면 표시 안 함 (기본 \"전체\") */\n  allTypeLabel?: string | null;\n  htmlFor?: string;\n  className?: string;\n}\n\nconst selectClass =\n  \"h-9 shrink-0 rounded-md border border-input bg-transparent px-3 text-sm shadow-xs outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50\";\n\nexport function KeywordFilter({\n  label = \"검색어\",\n  typeOptions,\n  type,\n  onTypeChange,\n  keyword,\n  onKeywordChange,\n  placeholder = \"검색어 입력\",\n  allTypeLabel = \"전체\",\n  htmlFor = \"keyword\",\n  className,\n}: KeywordFilterProps) {\n  return (\n    <AdminFilterField label={label} htmlFor={htmlFor} className={className}>\n      <div className=\"flex gap-2\">\n        {typeOptions && typeOptions.length > 0 && (\n          <select\n            aria-label=\"검색 유형\"\n            value={type ?? \"\"}\n            onChange={(e) => onTypeChange?.(e.target.value)}\n            className={cn(selectClass, \"w-28\")}\n          >\n            {allTypeLabel !== null && <option value=\"\">{allTypeLabel}</option>}\n            {typeOptions.map((o) => (\n              <option key={o.value} value={o.value}>\n                {o.label}\n              </option>\n            ))}\n          </select>\n        )}\n        <Input\n          id={htmlFor}\n          placeholder={placeholder}\n          value={keyword}\n          onChange={(e) => onKeywordChange(e.target.value)}\n        />\n      </div>\n    </AdminFilterField>\n  );\n}\n","\"use client\";\n\n/**\n * DateRangeFilter — 기간 필터 (날짜 유형 + 시작일 ~ 종료일 + 빠른 선택 프리셋)\n *\n * 거의 모든 관리자 필터에 들어가는 \"기간\" 영역을 공통화한 것.\n * AdminFilterField 를 품고 있어 AdminFilter 안에 바로 넣으면 된다. 제어 컴포넌트.\n * 날짜 입력은 AdminDateInput 을 사용한다.\n *\n * 날짜는 \"YYYY-MM-DD\" 문자열로 주고받는다.\n *\n * @example\n * <DateRangeFilter\n *   typeOptions={[{ value: \"joinedAt\", label: \"가입일\" }]}\n *   type={filters.dateType}\n *   onTypeChange={(v) => setField(\"dateType\", v)}\n *   startDate={filters.startDate}\n *   endDate={filters.endDate}\n *   onStartDateChange={(v) => setField(\"startDate\", v)}\n *   onEndDateChange={(v) => setField(\"endDate\", v)}\n *   presets\n * />\n */\nimport type { ReactNode } from \"react\";\n\nimport { cn } from \"../../lib/utils\";\nimport { Button } from \"../ui/button\";\nimport { AdminDateInput } from \"../input/admin-date-input\";\nimport { AdminFilterField } from \"./admin-filter\";\n\nexport interface DateTypeOption {\n    value: string;\n    label: string;\n}\n\nexport interface DateRangePreset {\n    label: string;\n    /** 클릭 시 적용할 [시작일, 종료일] (\"YYYY-MM-DD\") 을 반환 */\n    getRange: () => [string, string];\n}\n\nexport interface DateRangeFilterProps {\n    /** 필드 라벨 (기본 \"기간\") */\n    label?: ReactNode;\n    /** 날짜 유형 선택 옵션 (예: 가입일/수정일). 주면 좌측에 select 표시 */\n    typeOptions?: DateTypeOption[];\n    type?: string;\n    onTypeChange?: (value: string) => void;\n    /** 날짜 유형 select 의 \"전체\" 옵션 라벨. null 이면 표시 안 함 (기본 \"전체\") */\n    allTypeLabel?: string | null;\n    startDate: string | null;\n    endDate: string | null;\n    onStartDateChange: (value: string) => void;\n    onEndDateChange: (value: string) => void;\n    /**\n     * 빠른 기간 선택 버튼.\n     * - true: 기본 프리셋(오늘/최근 7일/최근 30일/최근 3개월)\n     * - 배열: 커스텀 프리셋\n     */\n    presets?: boolean | DateRangePreset[];\n    /** 시작일이 비었을 때 안내 문구 (기본 \"날짜를 선택하세요\") */\n    startPlaceholder?: string;\n    /** 종료일이 비었을 때 안내 문구 (기본 \"날짜를 선택하세요\") */\n    endPlaceholder?: string;\n    className?: string;\n}\n\nconst selectClass =\n    \"h-9 shrink-0 rounded-md border border-input bg-transparent px-3 text-sm shadow-xs outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50\";\n\n/** Date → \"YYYY-MM-DD\" */\nfunction ymd(date: Date): string {\n    const y = date.getFullYear();\n    const m = String(date.getMonth() + 1).padStart(2, \"0\");\n    const d = String(date.getDate()).padStart(2, \"0\");\n    return `${y}-${m}-${d}`;\n}\n\n/** 오늘 기준 n일 전 날짜 */\nfunction daysAgo(n: number): Date {\n    const d = new Date();\n    d.setDate(d.getDate() - n);\n    return d;\n}\n\n/** 오늘 기준 n개월 전 날짜 */\nfunction monthsAgo(n: number): Date {\n    const d = new Date();\n    d.setMonth(d.getMonth() - n);\n    return d;\n}\n\nconst DEFAULT_PRESETS: DateRangePreset[] = [\n    { label: \"오늘\", getRange: () => [ymd(new Date()), ymd(new Date())] },\n    { label: \"최근 7일\", getRange: () => [ymd(daysAgo(6)), ymd(new Date())] },\n    { label: \"최근 30일\", getRange: () => [ymd(daysAgo(29)), ymd(new Date())] },\n    { label: \"최근 3개월\", getRange: () => [ymd(monthsAgo(3)), ymd(new Date())] },\n];\n\nexport function DateRangeFilter({\n    label = \"기간\",\n    typeOptions,\n    type,\n    onTypeChange,\n    allTypeLabel = \"전체\",\n    startDate,\n    endDate,\n    onStartDateChange,\n    onEndDateChange,\n    presets,\n    startPlaceholder = \"날짜를 선택하세요\",\n    endPlaceholder = \"날짜를 선택하세요\",\n    className,\n}: DateRangeFilterProps) {\n    const presetList =\n        presets === true ? DEFAULT_PRESETS : Array.isArray(presets) ? presets : [];\n\n    return (\n        <AdminFilterField label={label} className={className}>\n            <div className=\"flex flex-wrap items-center gap-2\">\n                {typeOptions && typeOptions.length > 0 && (\n                    <select\n                        aria-label=\"날짜 유형\"\n                        value={type ?? \"\"}\n                        onChange={(e) => onTypeChange?.(e.target.value)}\n                        className={cn(selectClass, \"w-28\")}\n                    >\n                        {allTypeLabel !== null && (\n                            <option value=\"\">{allTypeLabel}</option>\n                        )}\n                        {typeOptions.map((o) => (\n                            <option key={o.value} value={o.value}>\n                                {o.label}\n                            </option>\n                        ))}\n                    </select>\n                )}\n\n                <AdminDateInput\n                    aria-label=\"시작일\"\n                    value={startDate ?? \"\"}\n                    max={endDate || undefined}\n                    onChange={onStartDateChange}\n                    placeholder={startPlaceholder}\n                    className=\"w-56\"\n                />\n                <span className=\"text-muted-foreground\"> ~ </span>\n                <AdminDateInput\n                    aria-label=\"종료일\"\n                    value={endDate ?? \"\"}\n                    min={startDate || undefined}\n                    onChange={onEndDateChange}\n                    placeholder={endPlaceholder}\n                    className=\"w-56\"\n                />\n\n                {presetList.length > 0 && (\n                    <div className=\"flex flex-wrap gap-1.5\">\n                        {presetList.map((preset) => (\n                            <Button\n                                key={preset.label}\n                                type=\"button\"\n                                variant=\"outline\"\n                                size=\"sm\"\n                                onClick={() => {\n                                    const [start, end] = preset.getRange();\n                                    onStartDateChange(start);\n                                    onEndDateChange(end);\n                                }}\n                            >\n                                {preset.label}\n                            </Button>\n                        ))}\n                    </div>\n                )}\n            </div>\n        </AdminFilterField>\n    );\n}\n","\"use client\";\n\n/**\n * Checkbox — shadcn/ui 기반 체크박스 (Radix Checkbox)\n *\n * 표의 행 선택, 폼 등에서 사용한다. 부분 선택(indeterminate) 상태도 지원한다.\n *\n * @example\n * <Checkbox checked={checked} onCheckedChange={setChecked} />\n * <Checkbox checked=\"indeterminate\" />  // 전체 선택 일부만 체크된 상태\n */\nimport { type ComponentProps } from \"react\";\nimport * as CheckboxPrimitive from \"@radix-ui/react-checkbox\";\nimport { Check, Minus } from \"lucide-react\";\n\nimport { cn } from \"../../lib/utils\";\n\nfunction Checkbox({\n  className,\n  ...props\n}: ComponentProps<typeof CheckboxPrimitive.Root>) {\n  return (\n    <CheckboxPrimitive.Root\n      data-slot=\"checkbox\"\n      className={cn(\n        \"peer size-4 shrink-0 rounded-[4px] border border-input shadow-xs transition-shadow outline-none\",\n        \"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]\",\n        \"disabled:cursor-not-allowed disabled:opacity-50\",\n        \"data-[state=checked]:border-primary data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground\",\n        \"data-[state=indeterminate]:border-primary data-[state=indeterminate]:bg-primary data-[state=indeterminate]:text-primary-foreground\",\n        className\n      )}\n      {...props}\n    >\n      <CheckboxPrimitive.Indicator\n        data-slot=\"checkbox-indicator\"\n        className=\"flex items-center justify-center text-current\"\n      >\n        {props.checked === \"indeterminate\" ? (\n          <Minus className=\"size-3.5\" />\n        ) : (\n          <Check className=\"size-3.5\" />\n        )}\n      </CheckboxPrimitive.Indicator>\n    </CheckboxPrimitive.Root>\n  );\n}\n\nexport { Checkbox };\n","\"use client\";\n\n/**\n * AdminCheckboxFilter — 체크박스 다중 선택 필터\n *\n * 옵션 목록 중 여러 개를 체크박스로 선택하는 필터 필드.\n * AdminFilterField(라벨 좌 / 컨트롤 우)를 품고 있어 AdminFilter 안에 바로 넣으면 된다.\n * 제어 컴포넌트이며, 선택된 값 배열/콜백만 받는다. (전체 선택 기능 없음)\n *\n * options 를 서버에서 받아와 채우는 경우, 로딩 중엔 loading 을 켜서\n * 옵션이 없다가 갑자기 나타나는 깜빡임 대신 스켈레톤을 보여줄 수 있다.\n *\n * @example\n * <AdminCheckboxFilter\n *   label=\"권한\"\n *   options={[\n *     { value: \"admin\", label: \"관리자\" },\n *     { value: \"manager\", label: \"매니저\" },\n *   ]}\n *   value={filters.roles}\n *   onChange={(v) => setField(\"roles\", v)}\n *   loading={isOptionsLoading}\n * />\n */\nimport { useId, type ReactNode } from \"react\";\n\nimport { cn } from \"../../lib/utils\";\nimport { Checkbox } from \"../ui/checkbox\";\nimport { Label } from \"../ui/label\";\nimport { AdminFilterField } from \"./admin-filter\";\n\nexport interface AdminCheckboxFilterOption {\n  value: string;\n  label: ReactNode;\n  disabled?: boolean;\n}\n\nexport interface AdminCheckboxFilterProps {\n  /** 필드 라벨 */\n  label?: ReactNode;\n  options: AdminCheckboxFilterOption[];\n  /** 선택된 값 배열 (기본 []) */\n  value?: string[];\n  onChange: (value: string[]) => void;\n  /** 옵션 로딩 중 표시 (기본 false). 켜지면 옵션 대신 스켈레톤을 보여준다 */\n  loading?: boolean;\n  /** 로딩 스켈레톤 개수 (기본 3) */\n  skeletonCount?: number;\n  /** 옵션 id 접두사. 안 주면 인스턴스마다 useId()로 자동 생성되어 겹칠 일이 없다 */\n  htmlFor?: string;\n  className?: string;\n}\n\nexport function AdminCheckboxFilter({\n  label,\n  options,\n  value = [],\n  onChange,\n  loading = false,\n  skeletonCount = 3,\n  htmlFor,\n  className,\n}: AdminCheckboxFilterProps) {\n  const autoId = useId();\n  const baseId = htmlFor ?? autoId;\n\n  const toggle = (v: string, checked: boolean) =>\n    onChange(checked ? [...value, v] : value.filter((item) => item !== v));\n\n  if (loading) {\n    return (\n      <AdminFilterField label={label} htmlFor={baseId} className={className}>\n        <div className=\"flex flex-wrap gap-2\">\n          {Array.from({ length: skeletonCount }).map((_, i) => (\n            <div\n              key={i}\n              className=\"h-5 w-16 animate-pulse rounded bg-muted\"\n            />\n          ))}\n        </div>\n      </AdminFilterField>\n    );\n  }\n\n  return (\n    <AdminFilterField label={label} htmlFor={baseId} className={className}>\n      <div className=\"flex flex-wrap gap-x-4 gap-y-2\">\n        {options.map((opt) => {\n          const id = `${baseId}-${opt.value}`;\n          return (\n            <Label\n              key={opt.value}\n              htmlFor={id}\n              className={cn(\n                \"flex items-center gap-1.5 font-normal\",\n                opt.disabled && \"cursor-not-allowed opacity-50\"\n              )}\n            >\n              <Checkbox\n                id={id}\n                checked={value.includes(opt.value)}\n                disabled={opt.disabled}\n                onCheckedChange={(checked) => toggle(opt.value, checked === true)}\n              />\n              {opt.label}\n            </Label>\n          );\n        })}\n      </div>\n    </AdminFilterField>\n  );\n}\n","\"use client\";\n\n/**\n * AdminFilterFields — 필터 필드 목록을 배열 하나로 선언하는 컴포넌트\n *\n * AdminFilter 안에 AdminFilterField + AdminCheckboxFilter/AdminSelect 를 필드마다\n * 반복해서 작성하는 대신, items 배열 하나로 선언하면 type 에 따라 자동으로 렌더링한다.\n * (AdminFormField 가 type 으로 입력 종류를 자동 생성하는 것과 같은 방식)\n *\n * 현재는 \"checkbox\"(다중 체크박스)와 \"select\"(단일 선택) 두 타입을 지원한다.\n *\n * @example\n * <AdminFilterFields\n *   items={[\n *     {\n *       type: \"checkbox\",\n *       label: \"상태\",\n *       options: kioskOptions.kioskStatus,\n *       value: filters.options?.status,\n *       onChange: (v) => setFiltersField(\"options\", { ...filters.options, status: v }),\n *       loading: kioskOptionsLoading,\n *     },\n *     {\n *       type: \"select\",\n *       label: \"파트너\",\n *       options: partnerOptions,\n *       value: filters.options.partner_key,\n *       onChange: (v) => setFiltersField(\"options\", { ...filters.options, partner_key: v }),\n *       placeholder: \"전체\",\n *       searchable: false,\n *       clearable: true,\n *     },\n *   ]}\n * />\n */\nimport { useId, type ReactNode } from \"react\";\n\nimport { cn } from \"../../lib/utils\";\nimport {\n  AdminSelect,\n  type AdminSelectOption,\n  type AdminSelectProps,\n} from \"../select/admin-select\";\nimport { AdminFilterField } from \"./admin-filter\";\nimport {\n  AdminCheckboxFilter,\n  type AdminCheckboxFilterOption,\n} from \"./admin-checkbox-filter\";\n\nexport interface AdminFilterFieldsCheckboxItem {\n  type: \"checkbox\";\n  label?: ReactNode;\n  options: AdminCheckboxFilterOption[];\n  /** 선택된 값 배열 (기본 []) */\n  value?: string[];\n  onChange: (value: string[]) => void;\n  /** 옵션 로딩 중 표시 (기본 false) */\n  loading?: boolean;\n  /** 로딩 스켈레톤 개수 (기본 3) */\n  skeletonCount?: number;\n  htmlFor?: string;\n  className?: string;\n}\n\nexport interface AdminFilterFieldsSelectItem {\n  type: \"select\";\n  label?: ReactNode;\n  options: AdminSelectOption[];\n  value?: string;\n  onChange: (value: string) => void;\n  placeholder?: string;\n  /** 옵션 로딩 중 표시 (기본 false). 켜지면 select 대신 스켈레톤을 보여준다 */\n  loading?: boolean;\n  htmlFor?: string;\n  className?: string;\n  /** AdminSelect 에 추가로 전달할 속성 (searchable, clearable 등) */\n  selectProps?: Omit<\n    AdminSelectProps,\n    \"options\" | \"value\" | \"onChange\" | \"id\" | \"placeholder\"\n  >;\n}\n\nexport type AdminFilterFieldsItem =\n  | AdminFilterFieldsCheckboxItem\n  | AdminFilterFieldsSelectItem;\n\nexport interface AdminFilterFieldsProps {\n  items: AdminFilterFieldsItem[];\n  className?: string;\n}\n\nexport function AdminFilterFields({ items, className }: AdminFilterFieldsProps) {\n  const autoId = useId();\n\n  return (\n    <div className={cn(\"flex flex-col gap-6\", className)}>\n      {items.map((item, index) => {\n        const htmlFor = item.htmlFor ?? `${autoId}-${index}`;\n\n        if (item.type === \"checkbox\") {\n          return (\n            <AdminCheckboxFilter\n              key={index}\n              label={item.label}\n              options={item.options}\n              value={item.value}\n              onChange={item.onChange}\n              loading={item.loading}\n              skeletonCount={item.skeletonCount}\n              htmlFor={htmlFor}\n              className={item.className}\n            />\n          );\n        }\n\n        return (\n          <AdminFilterField\n            key={index}\n            label={item.label}\n            htmlFor={htmlFor}\n            className={item.className}\n          >\n            {item.loading ? (\n              <div className=\"h-9 w-full animate-pulse rounded-md bg-muted\" />\n            ) : (\n              <AdminSelect\n                id={htmlFor}\n                options={item.options}\n                value={item.value}\n                onChange={item.onChange}\n                placeholder={item.placeholder}\n                {...item.selectProps}\n              />\n            )}\n          </AdminFilterField>\n        );\n      })}\n    </div>\n  );\n}\n","/**\n * AdminTableToolbar — 표 위 한 줄 툴바 (합계/요약 + 액션 버튼)\n *\n * - 왼쪽(summary): 총 N건, 총금액 등 요약 정보를 넣는다. (선택)\n * - 오른쪽(actions): 등록/삭제/엑셀 다운로드 등 버튼 영역을 넣는다. (선택)\n *\n * 상호작용이 없으므로 서버 컴포넌트로도 사용 가능하다.\n *\n * @example\n * <AdminTableToolbar\n *   summary={<>총 <b>{total}</b>건 · 선택 {selected}건</>}\n *   actions={<><Button variant=\"outline\">삭제</Button><Button>등록</Button></>}\n * />\n */\nimport { type ReactNode } from \"react\";\n\nimport { cn } from \"../../lib/utils\";\n\nexport interface AdminTableToolbarProps {\n  /** 왼쪽 요약/합계 영역 */\n  summary?: ReactNode;\n  /** 오른쪽 버튼/액션 영역 */\n  actions?: ReactNode;\n  className?: string;\n}\n\nexport function AdminTableToolbar({\n  summary,\n  actions,\n  className,\n}: AdminTableToolbarProps) {\n  return (\n    <div\n      className={cn(\n        \"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\",\n        className\n      )}\n    >\n      <div className=\"text-sm text-muted-foreground\">{summary}</div>\n      {actions && (\n        <div className=\"flex flex-wrap items-center gap-2\">{actions}</div>\n      )}\n    </div>\n  );\n}\n","\"use client\";\n\n/**\n * AdminPagination — 표 페이지네이션 (우선순위 7)\n *\n * 완전 제어(controlled) 컴포넌트라 서버/클라이언트 페이징 모두에 쓸 수 있다.\n * - 왼쪽: \"몇 개씩 보기\" page size 선택\n * - 오른쪽: 이전/다음 + 페이지 번호 + \"바로 페이지 이동\" 입력\n *\n * @example\n * <AdminPagination\n *   page={page} pageSize={pageSize} total={total}\n *   onPageChange={setPage}\n *   onPageSizeChange={(s) => { setPageSize(s); setPage(1); }}\n * />\n */\nimport { useState } from \"react\";\nimport {\n  ChevronLeft,\n  ChevronRight,\n  ChevronsLeft,\n  ChevronsRight,\n} from \"lucide-react\";\n\nimport { cn } from \"../../lib/utils\";\nimport { Button } from \"../ui/button\";\nimport { Input } from \"../ui/input\";\n\nexport interface AdminPaginationProps {\n  /** 현재 페이지 (1부터 시작) */\n  page: number;\n  /** 페이지당 항목 수 */\n  pageSize: number;\n  /** 전체 항목 수 */\n  total: number;\n  /** 페이지 변경 콜백 */\n  onPageChange: (page: number) => void;\n  /** page size 변경 콜백. 주어지면 \"몇 개씩 보기\" 선택이 표시된다 */\n  onPageSizeChange?: (size: number) => void;\n  /** page size 후보 (기본 [10, 20, 50, 100]) */\n  pageSizeOptions?: number[];\n  /** \"바로 이동\" 입력 표시 (기본 true) */\n  showJump?: boolean;\n  className?: string;\n}\n\n/** 페이지 번호 목록을 생성한다. (양끝 + 현재 주변, 나머지는 생략표시) */\nfunction buildPages(\n  current: number,\n  totalPages: number\n): (number | \"ellipsis\")[] {\n  const pages: (number | \"ellipsis\")[] = [];\n  const window = 1;\n  for (let p = 1; p <= totalPages; p++) {\n    if (\n      p === 1 ||\n      p === totalPages ||\n      (p >= current - window && p <= current + window)\n    ) {\n      pages.push(p);\n    } else if (pages[pages.length - 1] !== \"ellipsis\") {\n      pages.push(\"ellipsis\");\n    }\n  }\n  return pages;\n}\n\nconst selectClass =\n  \"h-9 rounded-md border border-input bg-transparent px-2 text-sm shadow-xs outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50\";\n\nexport function AdminPagination({\n  page,\n  pageSize,\n  total,\n  onPageChange,\n  onPageSizeChange,\n  pageSizeOptions = [10, 20, 50, 100],\n  showJump = true,\n  className,\n}: AdminPaginationProps) {\n  const totalPages = Math.max(1, Math.ceil(total / pageSize));\n  const current = Math.min(Math.max(1, page), totalPages);\n  const [jump, setJump] = useState(\"\");\n\n  const goto = (p: number) => {\n    const next = Math.min(Math.max(1, p), totalPages);\n    if (next !== current) onPageChange(next);\n  };\n\n  const submitJump = () => {\n    const n = Number(jump);\n    if (Number.isFinite(n) && n >= 1) {\n      goto(Math.floor(n));\n      setJump(\"\");\n    }\n  };\n\n  const pages = buildPages(current, totalPages);\n\n  return (\n    <div\n      className={cn(\n        \"flex flex-wrap items-center justify-end gap-x-4 gap-y-3\",\n        className\n      )}\n    >\n      {/* 페이지당 몇 개 보기 (오른쪽 정렬) */}\n      {onPageSizeChange && (\n        <div className=\"flex items-center gap-2 bg-white text-sm text-muted-foreground\">\n          <select\n            value={pageSize}\n            onChange={(e) => onPageSizeChange(Number(e.target.value))}\n            className={selectClass}\n            aria-label=\"페이지당 항목 수\"\n          >\n            {pageSizeOptions.map((opt) => (\n              <option key={opt} value={opt}>\n                {opt}개씩 보기\n              </option>\n            ))}\n          </select>\n        </div>\n      )}\n\n      {/* 페이지 네비게이션 */}\n      <div className=\"flex flex-wrap items-center gap-1\">\n        <Button\n          variant=\"outline\"\n          size=\"icon\"\n          onClick={() => goto(1)}\n          disabled={current <= 1}\n          aria-label=\"첫 페이지\"\n        >\n          <ChevronsLeft className=\"size-4\" />\n        </Button>\n        <Button\n          variant=\"outline\"\n          size=\"icon\"\n          onClick={() => goto(current - 1)}\n          disabled={current <= 1}\n          aria-label=\"이전 페이지\"\n        >\n          <ChevronLeft className=\"size-4\" />\n        </Button>\n\n        {pages.map((p, i) =>\n          p === \"ellipsis\" ? (\n            <span\n              key={`e-${i}`}\n              className=\"px-1.5 text-sm text-muted-foreground\"\n            >\n              …\n            </span>\n          ) : (\n            <Button\n              key={p}\n              variant={p === current ? \"default\" : \"outline\"}\n              size=\"icon\"\n              onClick={() => goto(p)}\n              aria-current={p === current ? \"page\" : undefined}\n            >\n              {p}\n            </Button>\n          )\n        )}\n\n        <Button\n          variant=\"outline\"\n          size=\"icon\"\n          onClick={() => goto(current + 1)}\n          disabled={current >= totalPages}\n          aria-label=\"다음 페이지\"\n        >\n          <ChevronRight className=\"size-4\" />\n        </Button>\n        <Button\n          variant=\"outline\"\n          size=\"icon\"\n          onClick={() => goto(totalPages)}\n          disabled={current >= totalPages}\n          aria-label=\"마지막 페이지\"\n        >\n          <ChevronsRight className=\"size-4\" />\n        </Button>\n\n        {showJump && (\n          <div className=\"ml-2 flex items-center gap-1.5 text-sm text-muted-foreground\">\n            <Input\n              type=\"number\"\n              min={1}\n              max={totalPages}\n              value={jump}\n              onChange={(e) => setJump(e.target.value)}\n              onKeyDown={(e) => {\n                if (e.key === \"Enter\") {\n                  e.preventDefault();\n                  submitJump();\n                }\n              }}\n              placeholder={String(current)}\n              className=\"h-9 w-16 text-center\"\n              aria-label=\"이동할 페이지 번호\"\n            />\n            <Button type=\"button\" variant=\"outline\" onClick={submitJump}>\n              이동\n            </Button>\n          </div>\n        )}\n      </div>\n    </div>\n  );\n}\n","\"use client\";\n\n/**\n * AdminTable — 관리자 공통 표 (TanStack Table 엔진 + Ant Design 스타일 컬럼 API, 우선순위 6)\n *\n * 컬럼은 Ant Design 의 column 과 유사하게 정의한다.\n * - title: 헤더 라벨\n * - dataIndex: 표시할 데이터의 키\n * - render(value, record, index): 셀 커스텀 렌더링 (배지/버튼 등)\n * - width / align / ellipsis: 너비 · 정렬 · 넘침 시 \"…\" 말줄임\n *\n * 도메인 비종속: 컬럼/데이터는 props 로 주입하고, 정렬·필터·페이징 로직은 프로젝트에서 처리한다.\n * 행 선택 상태는 외부 제어(rowSelection/onRowSelectionChange)하거나 생략 시 내부 상태로 동작한다.\n *\n * @example\n * const columns: AdminColumn<Member>[] = [\n *   { title: \"이름\", dataIndex: \"name\" },\n *   { title: \"이메일\", dataIndex: \"email\", ellipsis: true },\n *   {\n *     title: \"상태\", dataIndex: \"status\", align: \"center\",\n *     render: (value) => <StatusBadge>{value}</StatusBadge>,\n *   },\n *   {\n *     title: \"관리\", align: \"right\",\n *     render: (_v, record) => <Button onClick={() => edit(record)}>수정</Button>,\n *   },\n * ];\n * <AdminTable columns={columns} data={rows} enableRowSelection getRowId={(r) => r.id} />\n *\n * @example // 맨 아래 합계 행(tfoot, 위쪽 구분선만 있음) — 컬럼의 key(또는 dataIndex)를 키로 원하는 컬럼에만 표시\n * <AdminTable\n *   columns={columns}\n *   data={rows}\n *   footer={{\n *     product_name_snapshot: \"합계\",\n *     total_price: <span className=\"font-bold\">{comma(total)}</span>,\n *   }}\n * />\n *\n * @example // 툴바(요약+액션) + 페이지네이션까지 한 번에 (summary/toolbarActions, total/page/pageSize/onPageChange 로 각각 켜짐)\n * <AdminTable\n *   columns={columns}\n *   data={rows}\n *   summary={<>총 <b>{total}</b>건</>}\n *   toolbarActions={<Button variant=\"outline\">선택 삭제</Button>}\n *   total={total}\n *   page={page}\n *   pageSize={pageSize}\n *   onPageChange={setPage}\n *   onPageSizeChange={(s) => { setPageSize(s); setPage(1); }}\n * />\n */\nimport { type ReactNode, useMemo, useState } from \"react\";\nimport {\n  type ColumnDef,\n  type OnChangeFn,\n  type RowSelectionState,\n  flexRender,\n  getCoreRowModel,\n  useReactTable,\n} from \"@tanstack/react-table\";\nimport {\n  ChevronDown,\n  ChevronUp,\n  ChevronsUpDown,\n  Loader2,\n} from \"lucide-react\";\n\nimport { cn } from \"../../lib/utils\";\nimport { type ColumnFormatType, formatByType } from \"../../lib/format\";\nimport type { SortType } from \"../../hooks/use-page-search-state\";\nimport { Checkbox } from \"../ui/checkbox\";\nimport { AdminTableToolbar } from \"./admin-table-toolbar\";\nimport { AdminPagination } from \"./admin-pagination\";\n\n/** Ant Design 스타일 컬럼 정의 */\nexport interface AdminColumn<TData> {\n  /** 헤더 라벨 */\n  title: ReactNode;\n  /** 표시할 데이터의 키 (없으면 render 로만 렌더링) */\n  dataIndex?: keyof TData;\n  /** 컬럼 고유 키 (없으면 dataIndex 또는 인덱스로 자동 생성) */\n  key?: string;\n  /**\n   * 값 자동 포맷 종류. (render 가 없을 때 적용)\n   * - \"comma\": 천 단위 콤마 (1234567 → 1,234,567)\n   * - \"tel\": 전화번호 하이픈 (01012345678 → 010-1234-5678)\n   * - \"bizNum\": 사업자등록번호 하이픈 (1234567890 → 123-45-67890)\n   */\n  type?: ColumnFormatType;\n  /** 컬럼 너비 (number=px) */\n  width?: number | string;\n  /** 셀 정렬 (기본 left) */\n  align?: \"left\" | \"center\" | \"right\";\n  /** true 이면 헤더 클릭으로 정렬할 수 있다 (서버 정렬: onSortChange 로 전달) */\n  sortable?: boolean;\n  /** 가로 스크롤 시 좌/우에 고정한다. (width 를 number 로 지정해야 정확히 동작) */\n  fixed?: \"left\" | \"right\";\n  /** true 이면 내용이 넘칠 때 \"…\" 로 말줄임한다 (width 지정 권장) */\n  ellipsis?: boolean;\n  /**\n   * 셀 커스텀 렌더링. value=해당 셀 값, record=행 데이터, index=행 번호\n   * value 타입은 any 다 — 컬럼마다 dataIndex 가 가리키는 필드 타입이 다른데, 이를\n   * `TData[keyof TData]` 유니온으로 만들면 TData 에 unknown 타입 필드가 하나만 있어도\n   * 유니온 전체가 unknown 으로 붕괴되어(예: address_json?: unknown) 모든 컬럼의 render 에서\n   * String(value) 같은 캐스팅을 강제하게 된다. antd 등 다른 테이블 라이브러리와 동일하게 any 로 둔다.\n   */\n  render?: (value: any, record: TData, index: number) => ReactNode;\n  /**\n   * 값이 null/undefined/\"\"일 때 대신 보여줄 내용. (render를 쓰면 적용되지 않는다)\n   * 컬럼별로 다르게 하고 싶을 때만 지정 — 없으면 AdminTable의 emptyText(기본 \"-\")를 따른다.\n   */\n  emptyText?: ReactNode;\n  /** 셀(td) 추가 클래스 */\n  className?: string;\n  /** 헤더(th) 추가 클래스 */\n  headerClassName?: string;\n}\n\n/** 컬럼 부가 정보를 TanStack meta 로 실어 th/td 에서 읽는다. */\ninterface ColMeta {\n  align?: \"left\" | \"center\" | \"right\";\n  sortable?: boolean;\n  fixed?: \"left\" | \"right\";\n  ellipsis?: boolean;\n  width?: number | string;\n  className?: string;\n  headerClassName?: string;\n}\n\n/** 너비 값을 px 숫자로 변환 (고정 컬럼 offset 계산용). 알 수 없으면 0 */\nfunction toPx(width: number | string | undefined): number {\n  if (typeof width === \"number\") return width;\n  if (typeof width === \"string\") {\n    const n = parseFloat(width);\n    return Number.isFinite(n) ? n : 0;\n  }\n  return 0;\n}\n\nexport interface AdminTableProps<TData> {\n  /** Ant Design 스타일 컬럼 정의 */\n  columns: AdminColumn<TData>[];\n  data: TData[];\n  /** 맨 앞에 체크박스(행 선택) 컬럼을 추가한다 */\n  enableRowSelection?: boolean;\n  /** 행 선택 상태 (제어 컴포넌트). 생략하면 내부 상태로 동작 */\n  rowSelection?: RowSelectionState;\n  onRowSelectionChange?: OnChangeFn<RowSelectionState>;\n  /** 행 고유 id 추출 (선택 상태 키로 사용). 권장. number를 반환해도 내부적으로 문자열로 변환된다 */\n  getRowId?: (row: TData, index: number) => string | number;\n  /** 로딩 상태 표시 */\n  loading?: boolean;\n  /** 데이터가 없을 때(행이 0개) 표시할 내용 */\n  emptyMessage?: ReactNode;\n  /**\n   * 셀 값이 null/undefined/\"\"일 때 대신 보여줄 내용. (기본 \"-\")\n   * render를 쓰는 컬럼에는 적용되지 않는다 — 그건 render가 전적으로 책임진다.\n   */\n  emptyText?: ReactNode;\n  /**\n   * 정렬 상태 (제어형 서버 정렬). usePageSearchState의 sort와 동일한 타입이라\n   * 변환 없이 바로 넘길 수 있다. sortKey가 없으면 정렬 없음.\n   */\n  sort?: SortType | null;\n  /**\n   * 정렬 변경 콜백. 오름차순 → 내림차순 → 해제 순으로 토글된다.\n   * usePageSearchState의 setSortAndSync에 그대로 연결 가능하다 (예: onSortChange={setSortAndSync}).\n   */\n  onSortChange?: (sort: SortType) => void;\n  /** 행 클릭 콜백 */\n  onRowClick?: (row: TData) => void;\n  /**\n   * 표 본문의 최소 높이를 \"행 개수\" 기준으로 확보한다.\n   * 행이 적거나 비어 있어도 높이가 유지되어 페이지 이동 시 레이아웃이 흔들리지 않는다.\n   * (예: minRows={20} → 20행 분량의 최소 높이)\n   */\n  minRows?: number;\n  className?: string;\n  /**\n   * 표 맨 아래 합계/요약 행(tfoot, 위쪽 구분선만 있음).\n   * 컬럼의 key(또는 dataIndex, 없으면 \"col_인덱스\")를 키로 사용해 원하는 컬럼 자리에만\n   * 내용을 넣을 수 있다. 지정하지 않은 컬럼은 빈 셀로 렌더링된다.\n   */\n  footer?: Record<string, ReactNode>;\n\n  // ── 툴바 (요약 + 액션) — summary 또는 toolbarActions 중 하나라도 있으면 표 위에 표시된다 ──\n  /** 툴바 좌측 요약 영역 (예: 총 N건, 선택 N건). 없으면 툴바 자체가 생략된다 */\n  summary?: ReactNode;\n  /** 툴바 우측 액션 버튼 영역 (등록/삭제/엑셀 다운로드 등) */\n  toolbarActions?: ReactNode;\n  toolbarClassName?: string;\n\n  // ── 페이지네이션 — total/page/pageSize/onPageChange 가 모두 있으면 표 아래에 표시된다 ──\n  total?: number;\n  page?: number;\n  pageSize?: number;\n  onPageChange?: (page: number) => void;\n  /** 주어지면 \"몇 개씩 보기\" 선택이 표시된다 */\n  onPageSizeChange?: (size: number) => void;\n  pageSizeOptions?: number[];\n  showJump?: boolean;\n  paginationClassName?: string;\n}\n\n/**\n * rowSelection 객체에서 선택된 행 id 배열을 뽑는다.\n * (TanStack 의 RowSelectionState 는 선택된 행만 키로 가지므로 키 목록이 곧 선택 id 다.)\n *\n * @example\n * const ids = getSelectedRowIds(rowSelection);        // [\"3\", \"7\"]\n * const rows = data.filter((d) => rowSelection[d.id]); // 선택된 행 객체\n */\nexport function getSelectedRowIds(rowSelection: RowSelectionState): string[] {\n  return Object.keys(rowSelection).filter((key) => rowSelection[key]);\n}\n\n/** 본문 최소 높이 계산용 행 높이 추정치(px) */\nconst ROW_HEIGHT = 20;\nconst HEADER_HEIGHT = 44;\n\nconst alignClass = {\n  left: \"text-left\",\n  center: \"text-center\",\n  right: \"text-right\",\n} as const;\n\n/** 정렬 상태 아이콘 (오름/내림/없음) */\nfunction SortIcon({ order }: { order?: \"ASC\" | \"DESC\" }) {\n  if (order === \"ASC\") return <ChevronUp className=\"size-3.5\" />;\n  if (order === \"DESC\") return <ChevronDown className=\"size-3.5\" />;\n  return <ChevronsUpDown className=\"size-3.5 opacity-40\" />;\n}\n\nexport function AdminTable<TData>({\n  columns,\n  data,\n  enableRowSelection = false,\n  rowSelection: controlledSelection,\n  onRowSelectionChange: controlledOnChange,\n  getRowId,\n  loading = false,\n  emptyMessage = \"데이터가 없습니다.\",\n  emptyText = \"-\",\n  sort,\n  onSortChange,\n  onRowClick,\n  minRows,\n  className,\n  footer,\n  summary,\n  toolbarActions,\n  toolbarClassName,\n  total,\n  page,\n  pageSize,\n  onPageChange,\n  onPageSizeChange,\n  pageSizeOptions,\n  showJump,\n  paginationClassName,\n}: AdminTableProps<TData>) {\n  const [internalSelection, setInternalSelection] =\n    useState<RowSelectionState>({});\n  const rowSelection = controlledSelection ?? internalSelection;\n  const onRowSelectionChange = controlledOnChange ?? setInternalSelection;\n\n  const hasToolbar = summary != null || toolbarActions != null;\n  const hasPagination =\n    total !== undefined &&\n    page !== undefined &&\n    pageSize !== undefined &&\n    !!onPageChange;\n\n  // 말줄임(ellipsis) 컬럼이 있거나 fixed(고정) 컬럼이 있으면 table-fixed 로 전환해서\n  // width 가 실제 렌더링에 정확히 반영되게 한다. table-layout: auto(기본값)에서는\n  // 브라우저가 내용 길이에 따라 컬럼 폭을 자체적으로 줄이기 때문에, fixed 컬럼의 sticky\n  // left/right 오프셋 계산(지정한 width 합산)과 실제 렌더링 폭이 어긋나서 고정 컬럼이\n  // 엉뚱한 위치에 붙어버린다.\n  const hasEllipsis = columns.some((c) => c.ellipsis);\n  const hasFixedCol = columns.some((c) => c.fixed);\n\n  // AntD 스타일 컬럼 → TanStack ColumnDef 로 변환한다.\n  const finalColumns = useMemo<ColumnDef<TData, unknown>[]>(() => {\n    const mapped: ColumnDef<TData, unknown>[] = columns.map((col, i) => ({\n      id:\n        col.key ??\n        (col.dataIndex != null ? String(col.dataIndex) : `col_${i}`),\n      header: () => col.title,\n      cell: ({ row }) => {\n        const value =\n          col.dataIndex != null ? row.original[col.dataIndex] : undefined;\n        if (col.render) return col.render(value, row.original, row.index);\n        const formatted = col.type\n          ? formatByType(col.type, value)\n          : (value as ReactNode);\n        if (formatted === \"\" || formatted == null) {\n          return col.emptyText ?? emptyText;\n        }\n        return formatted;\n      },\n      size: typeof col.width === \"number\" ? col.width : undefined,\n      enableSorting: false,\n      meta: {\n        align: col.align,\n        sortable: col.sortable,\n        fixed: col.fixed,\n        ellipsis: col.ellipsis,\n        width: col.width,\n        className: col.className,\n        headerClassName: col.headerClassName,\n      } satisfies ColMeta,\n    }));\n\n    if (!enableRowSelection) return mapped;\n\n    // 좌측 고정 컬럼이 있으면 선택 체크박스 컬럼도 함께 좌측 고정한다.\n    const hasLeftFixed = columns.some((c) => c.fixed === \"left\");\n\n    const selectionColumn: ColumnDef<TData, unknown> = {\n      id: \"__select__\",\n      size: 40,\n      header: ({ table }) => (\n        <Checkbox\n          checked={\n            table.getIsAllPageRowsSelected()\n              ? true\n              : table.getIsSomePageRowsSelected()\n                ? \"indeterminate\"\n                : false\n          }\n          onCheckedChange={(value) => table.toggleAllPageRowsSelected(!!value)}\n          aria-label=\"전체 선택\"\n        />\n      ),\n      cell: ({ row }) => (\n        <Checkbox\n          checked={row.getIsSelected()}\n          onCheckedChange={(value) => row.toggleSelected(!!value)}\n          aria-label=\"행 선택\"\n          onClick={(e) => e.stopPropagation()}\n        />\n      ),\n      enableSorting: false,\n      meta: {\n        align: \"center\",\n        width: 40,\n        fixed: hasLeftFixed ? \"left\" : undefined,\n      } satisfies ColMeta,\n    };\n    return [selectionColumn, ...mapped];\n  }, [columns, enableRowSelection, emptyText]);\n\n  // 고정 컬럼의 sticky left/right offset 을 컬럼 순서/너비로 계산한다.\n  const stickyMap = useMemo(() => {\n    const map: Record<string, { left?: number; right?: number }> = {};\n    let leftAcc = 0;\n    for (const col of finalColumns) {\n      const meta = col.meta as ColMeta | undefined;\n      if (meta?.fixed === \"left\") {\n        map[col.id as string] = { left: leftAcc };\n        leftAcc += toPx(meta.width);\n      }\n    }\n    let rightAcc = 0;\n    for (let i = finalColumns.length - 1; i >= 0; i--) {\n      const col = finalColumns[i];\n      const meta = col.meta as ColMeta | undefined;\n      if (meta?.fixed === \"right\") {\n        map[col.id as string] = { right: rightAcc };\n        rightAcc += toPx(meta.width);\n      }\n    }\n    return map;\n  }, [finalColumns]);\n\n  // TanStack Table 의 useReactTable 은 외부 라이브러리 훅이라 react-hooks 규칙 대상에서 제외한다.\n  // eslint-disable-next-line react-hooks/incompatible-library\n  // TanStack Table의 getRowId는 string만 반환해야 하므로(RowSelectionState가 Record<string, boolean>),\n  // number를 반환해도 되도록 여기서 문자열로 변환해준다.\n  const table = useReactTable({\n    data,\n    columns: finalColumns,\n    state: { rowSelection },\n    enableRowSelection,\n    onRowSelectionChange,\n    getRowId: getRowId\n      ? (row: TData, index: number) => String(getRowId(row, index))\n      : undefined,\n    getCoreRowModel: getCoreRowModel(),\n  });\n\n  const colSpan = finalColumns.length;\n\n  // 헤더 클릭 정렬: 오름차순 → 내림차순 → 해제 토글\n  const handleSort = (field: string) => {\n    const cur = sort?.sortKey === field ? sort.sortType : undefined;\n    const next = cur === \"ASC\" ? \"DESC\" : cur === \"DESC\" ? undefined : \"ASC\";\n    onSortChange?.({ sortKey: next ? field : undefined, sortType: next });\n  };\n\n  const tableEl = (\n    <div\n      className={cn(\n        \"relative overflow-hidden rounded-lg border bg-card text-card-foreground shadow-xs\",\n        !hasToolbar && !hasPagination && className\n      )}\n    >\n      <div\n        className=\"overflow-x-auto\"\n        style={\n          minRows\n            ? { minHeight: HEADER_HEIGHT + minRows * ROW_HEIGHT }\n            : undefined\n        }\n      >\n        <table className={cn(\"w-full text-sm\", (hasEllipsis || hasFixedCol) && \"table-fixed\")}>\n          <thead className=\"border-b bg-muted\">\n            {table.getHeaderGroups().map((headerGroup) => (\n              <tr key={headerGroup.id}>\n                {headerGroup.headers.map((header) => {\n                  const meta = header.column.columnDef.meta as\n                    | ColMeta\n                    | undefined;\n                  const sticky = stickyMap[header.column.id];\n                  return (\n                    <th\n                      key={header.id}\n                      className={cn(\n                        \"h-11 px-3 align-middle font-medium text-muted-foreground whitespace-nowrap\",\n                        alignClass[meta?.align ?? \"left\"],\n                        meta?.ellipsis && \"truncate\",\n                        sticky && \"sticky z-20 bg-muted\",\n                        sticky?.left !== undefined &&\n                          \"shadow-[2px_0_4px_-2px_rgba(0,0,0,0.12)]\",\n                        sticky?.right !== undefined &&\n                          \"shadow-[-2px_0_4px_-2px_rgba(0,0,0,0.12)]\",\n                        meta?.headerClassName\n                      )}\n                      style={{\n                        width: meta?.width,\n                        left: sticky?.left,\n                        right: sticky?.right,\n                      }}\n                      aria-sort={\n                        meta?.sortable\n                          ? sort?.sortKey === header.column.id\n                            ? sort.sortType === \"ASC\"\n                              ? \"ascending\"\n                              : \"descending\"\n                            : \"none\"\n                          : undefined\n                      }\n                    >\n                      {header.isPlaceholder ? null : meta?.sortable ? (\n                        <button\n                          type=\"button\"\n                          onClick={() => handleSort(header.column.id)}\n                          className=\"inline-flex items-center gap-1 select-none transition-colors hover:text-foreground\"\n                        >\n                          {flexRender(\n                            header.column.columnDef.header,\n                            header.getContext()\n                          )}\n                          <SortIcon\n                            order={\n                              sort?.sortKey === header.column.id\n                                ? sort.sortType\n                                : undefined\n                            }\n                          />\n                        </button>\n                      ) : (\n                        flexRender(\n                          header.column.columnDef.header,\n                          header.getContext()\n                        )\n                      )}\n                    </th>\n                  );\n                })}\n              </tr>\n            ))}\n          </thead>\n          <tbody>\n            {loading || table.getRowModel().rows.length === 0 ? (\n              // colSpan td 는 컬럼 폭 합만큼 넓어져서(가로 스크롤 생김) 그 안에서는\n              // \"현재 보이는 영역\" 기준으로 가운데 정렬을 할 수 없다(position:sticky 로도\n              // 안 됨 — 이 td 자체가 이미 스크롤 영역 전체 너비라서 뷰포트에 고정되지 않는다).\n              // 그래서 내용 없는 빈 placeholder 행으로 높이만 잡아두고, 실제 문구/스피너는\n              // 가로 스크롤 영역 밖(아래 relative 컨테이너에 겹쳐진 absolute 오버레이)에서\n              // 렌더링해 항상 보이는 영역 기준으로 정확히 가운데에 오게 한다.\n              <tr>\n                <td colSpan={colSpan} className=\"h-32\" />\n              </tr>\n            ) : (\n              table.getRowModel().rows.map((row) => (\n                <tr\n                  key={row.id}\n                  data-state={row.getIsSelected() ? \"selected\" : undefined}\n                  onClick={\n                    onRowClick ? () => onRowClick(row.original) : undefined\n                  }\n                  className={cn(\n                    \"group border-b bg-card transition-colors last:border-0 hover:bg-muted data-[state=selected]:bg-muted\",\n                    onRowClick && \"cursor-pointer\"\n                  )}\n                >\n                  {row.getVisibleCells().map((cell) => {\n                    const meta = cell.column.columnDef.meta as\n                      | ColMeta\n                      | undefined;\n                    const sticky = stickyMap[cell.column.id];\n                    return (\n                      <td\n                        key={cell.id}\n                        className={cn(\n                          \"px-3 py-2.5 align-middle\",\n                          alignClass[meta?.align ?? \"left\"],\n                          meta?.ellipsis ? \"truncate\" : \"whitespace-nowrap\",\n                          // 고정 셀은 스크롤 내용이 비쳐 보이면 안 되므로 항상 불투명한 배경을 직접 지정한다.\n                          // (bg-inherit로 행의 hover 배경을 상속하면 반투명 배경일 때 스크롤 중 호버 시\n                          //  뒤에 있는(스크롤된) 셀이 비쳐 보이는 문제가 생긴다. 그래서 group-hover로\n                          //  행과 동일한 불투명 색을 별도 지정 — 행의 hover 배경도 완전 불투명이어야\n                          //  고정/비고정 컬럼 색이 정확히 일치한다.)\n                          sticky &&\n                            \"sticky z-10 bg-card transition-colors group-hover:bg-muted group-data-[state=selected]:bg-muted\",\n                          sticky?.left !== undefined &&\n                            \"shadow-[2px_0_4px_-2px_rgba(0,0,0,0.12)]\",\n                          sticky?.right !== undefined &&\n                            \"shadow-[-2px_0_4px_-2px_rgba(0,0,0,0.12)]\",\n                          meta?.className\n                        )}\n                        style={{\n                          maxWidth: meta?.width,\n                          left: sticky?.left,\n                          right: sticky?.right,\n                        }}\n                      >\n                        {flexRender(\n                          cell.column.columnDef.cell,\n                          cell.getContext()\n                        )}\n                      </td>\n                    );\n                  })}\n                </tr>\n              ))\n            )}\n          </tbody>\n          {footer && (\n            <tfoot>\n              <tr className=\"border-t bg-card\">\n                {finalColumns.map((col) => {\n                  const meta = col.meta as ColMeta | undefined;\n                  const sticky = stickyMap[col.id as string];\n                  return (\n                    <td\n                      key={col.id}\n                      className={cn(\n                        \"px-3 py-2.5 align-middle\",\n                        alignClass[meta?.align ?? \"left\"],\n                        sticky && \"sticky z-10 bg-card\",\n                        sticky?.left !== undefined &&\n                          \"shadow-[2px_0_4px_-2px_rgba(0,0,0,0.12)]\",\n                        sticky?.right !== undefined &&\n                          \"shadow-[-2px_0_4px_-2px_rgba(0,0,0,0.12)]\",\n                        meta?.className\n                      )}\n                      style={{\n                        maxWidth: meta?.width,\n                        left: sticky?.left,\n                        right: sticky?.right,\n                      }}\n                    >\n                      {footer[col.id as string]}\n                    </td>\n                  );\n                })}\n              </tr>\n            </tfoot>\n          )}\n        </table>\n      </div>\n\n      {(loading || table.getRowModel().rows.length === 0) && (\n        <div\n          className=\"absolute inset-x-0 top-11 flex h-32 items-center justify-center text-muted-foreground\"\n        >\n          {loading ? (\n            <span className=\"inline-flex items-center gap-2\">\n              <Loader2 className=\"size-4 animate-spin\" />\n              불러오는 중...\n            </span>\n          ) : (\n            emptyMessage\n          )}\n        </div>\n      )}\n    </div>\n  );\n\n  if (!hasToolbar && !hasPagination) return tableEl;\n\n  return (\n    <div className={cn(\"space-y-3\", className)}>\n      {hasToolbar && (\n        <AdminTableToolbar\n          summary={summary}\n          actions={toolbarActions}\n          className={toolbarClassName}\n        />\n      )}\n      {tableEl}\n      {hasPagination && (\n        <AdminPagination\n          page={page!}\n          pageSize={pageSize!}\n          total={total!}\n          onPageChange={onPageChange!}\n          onPageSizeChange={onPageSizeChange}\n          pageSizeOptions={pageSizeOptions}\n          showJump={showJump}\n          className={paginationClassName}\n        />\n      )}\n    </div>\n  );\n}\n","\"use client\";\n\n/**\n * Dialog — 화면 중앙에 뜨는 모달 (Radix Dialog 기반)\n *\n * AdminModal 의 기반 프리미티브. 직접 조합해서 쓸 수도 있다.\n *\n * @example\n * <Dialog open={open} onOpenChange={setOpen}>\n *   <DialogContent>\n *     <DialogHeader><DialogTitle>제목</DialogTitle></DialogHeader>\n *     ...\n *   </DialogContent>\n * </Dialog>\n */\nimport { type ComponentProps } from \"react\";\nimport * as DialogPrimitive from \"@radix-ui/react-dialog\";\nimport { XIcon } from \"lucide-react\";\n\nimport { cn } from \"../../lib/utils\";\n\nfunction Dialog(props: ComponentProps<typeof DialogPrimitive.Root>) {\n  return <DialogPrimitive.Root data-slot=\"dialog\" {...props} />;\n}\n\nfunction DialogTrigger(\n  props: ComponentProps<typeof DialogPrimitive.Trigger>\n) {\n  return <DialogPrimitive.Trigger data-slot=\"dialog-trigger\" {...props} />;\n}\n\nfunction DialogClose(props: ComponentProps<typeof DialogPrimitive.Close>) {\n  return <DialogPrimitive.Close data-slot=\"dialog-close\" {...props} />;\n}\n\nfunction DialogOverlay({\n  className,\n  ...props\n}: ComponentProps<typeof DialogPrimitive.Overlay>) {\n  return (\n    <DialogPrimitive.Overlay\n      data-slot=\"dialog-overlay\"\n      className={cn(\n        \"fixed inset-0 z-50 bg-black/50 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\",\n        className\n      )}\n      {...props}\n    />\n  );\n}\n\nfunction DialogContent({\n  className,\n  children,\n  showClose = true,\n  ...props\n}: ComponentProps<typeof DialogPrimitive.Content> & { showClose?: boolean }) {\n  return (\n    <DialogPrimitive.Portal data-slot=\"dialog-portal\">\n      <DialogOverlay />\n      <DialogPrimitive.Content\n        data-slot=\"dialog-content\"\n        className={cn(\n          \"bg-background fixed top-1/2 left-1/2 z-50 grid w-[calc(100%-2rem)] max-w-lg -translate-x-1/2 -translate-y-1/2 gap-4 rounded-lg border p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95\",\n          className\n        )}\n        {...props}\n      >\n        {children}\n        {showClose && (\n          <DialogPrimitive.Close className=\"ring-offset-background focus:ring-ring absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none\">\n            <XIcon className=\"size-4\" />\n            <span className=\"sr-only\">닫기</span>\n          </DialogPrimitive.Close>\n        )}\n      </DialogPrimitive.Content>\n    </DialogPrimitive.Portal>\n  );\n}\n\nfunction DialogHeader({ className, ...props }: ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"dialog-header\"\n      className={cn(\"flex flex-col gap-1.5 text-left\", className)}\n      {...props}\n    />\n  );\n}\n\nfunction DialogFooter({ className, ...props }: ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"dialog-footer\"\n      className={cn(\n        \"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end\",\n        className\n      )}\n      {...props}\n    />\n  );\n}\n\nfunction DialogTitle({\n  className,\n  ...props\n}: ComponentProps<typeof DialogPrimitive.Title>) {\n  return (\n    <DialogPrimitive.Title\n      data-slot=\"dialog-title\"\n      className={cn(\"text-lg font-semibold\", className)}\n      {...props}\n    />\n  );\n}\n\nfunction DialogDescription({\n  className,\n  ...props\n}: ComponentProps<typeof DialogPrimitive.Description>) {\n  return (\n    <DialogPrimitive.Description\n      data-slot=\"dialog-description\"\n      className={cn(\"text-muted-foreground text-sm\", className)}\n      {...props}\n    />\n  );\n}\n\nexport {\n  Dialog,\n  DialogTrigger,\n  DialogClose,\n  DialogOverlay,\n  DialogContent,\n  DialogHeader,\n  DialogFooter,\n  DialogTitle,\n  DialogDescription,\n};\n","\"use client\";\n\n/**\n * AdminModal — 화면 중앙 모달 (우선순위 9)\n *\n * 제목/설명/본문/푸터를 props 로 받아 일관된 모달을 만든다. 제어 컴포넌트.\n * 등록/수정 폼, 안내 등에 사용한다. (확인 전용 다이얼로그는 ConfirmDialog 사용 예정)\n *\n * @example\n * <AdminModal\n *   open={open}\n *   onClose={() => setOpen(false)}\n *   title=\"회원 등록\"\n *   description=\"새 회원 정보를 입력하세요.\"\n *   footer={\n *     <>\n *       <Button variant=\"outline\" onClick={() => setOpen(false)}>취소</Button>\n *       <Button onClick={save}>저장</Button>\n *     </>\n *   }\n * >\n *   ...폼 본문...\n * </AdminModal>\n */\nimport type { ReactNode } from \"react\";\n\nimport { cn } from \"../../lib/utils\";\nimport {\n  Dialog,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n} from \"../ui/dialog\";\n\nexport type AdminModalSize = \"sm\" | \"md\" | \"lg\" | \"xl\" | \"xxl\" | \"xxxl\";\n\nexport interface AdminModalProps {\n  open: boolean;\n  /** 모달이 닫힐 때 호출되는 콜백 (X/오버레이/ESC/취소 등 모든 닫힘에 공통) */\n  onClose: () => void;\n  /** 모달 제목 */\n  title?: ReactNode;\n  /** 제목 아래 보조 설명 */\n  description?: ReactNode;\n  /** 본문 */\n  children?: ReactNode;\n  /** 하단 버튼 영역 (취소/저장 등) */\n  footer?: ReactNode;\n  /** 너비 (기본 md, xl=2xl, xxl=4xl, xxxl=6xl) */\n  size?: AdminModalSize;\n  /** 오버레이 클릭/ESC 로 닫기 막기 */\n  disableClose?: boolean;\n  /** 우상단 X 닫기 버튼 숨기기 */\n  hideCloseButton?: boolean;\n  /**\n   * 모달이 열릴 때 내부 첫 번째 포커스 가능한 요소(예: 폼의 첫 select)로 자동 포커스할지 여부.\n   * 기본 false — 첫 필드가 검색형 select(AdminSelect)인 경우 포커스만으로 드롭다운이\n   * 자동으로 열려버리는 것을 막기 위한 기본값이다. 키보드 진입 편의를 위해 자동 포커스가\n   * 필요하면 true로 켠다.\n   */\n  autoFocus?: boolean;\n  className?: string;\n}\n\nconst SIZE: Record<AdminModalSize, string> = {\n  sm: \"max-w-sm\",\n  md: \"max-w-md\",\n  lg: \"max-w-lg\",\n  xl: \"max-w-2xl\",\n  xxl: \"max-w-4xl\",\n  xxxl: \"max-w-6xl\",\n};\n\nexport function AdminModal({\n  open,\n  onClose,\n  title,\n  description,\n  children,\n  footer,\n  size = \"md\",\n  disableClose = false,\n  hideCloseButton = false,\n  autoFocus = false,\n  className,\n}: AdminModalProps) {\n  // className 으로 너비(w-*/max-w-*)를 직접 주면 size 기본 max-w 가 캡(cap)하지 않도록 끈다.\n  const hasCustomWidth = !!className && /(?:^|\\s)(?:max-)?w-/.test(className);\n\n  return (\n    <Dialog\n      open={open}\n      onOpenChange={(next) => {\n        if (!next) onClose();\n      }}\n    >\n      <DialogContent\n        showClose={!hideCloseButton && !disableClose}\n        // 콘텐츠가 길면 본문만 스크롤되도록 전체 높이를 제한한다. 헤더/본문/푸터 각자 여백을 관리하도록 기본 p-6·gap-4 는 없앤다.\n        className={cn(\n          \"flex max-h-[85vh] flex-col gap-0 overflow-hidden p-0\",\n          // 커스텀 너비가 있으면 size·기본 max-w 캡을 풀고(max-w-none), 없으면 size 적용\n          hasCustomWidth ? \"max-w-none\" : SIZE[size],\n          className\n        )}\n        onInteractOutside={\n          disableClose ? (e) => e.preventDefault() : undefined\n        }\n        onEscapeKeyDown={disableClose ? (e) => e.preventDefault() : undefined}\n        onOpenAutoFocus={autoFocus ? undefined : (e) => e.preventDefault()}\n      >\n        {(title || description) && (\n          <DialogHeader className=\"shrink-0 border-b px-6 py-4\">\n            {title && <DialogTitle>{title}</DialogTitle>}\n            {description && (\n              // asChild + div: description 에 div/span 등 블록 요소가 들어와도\n              // <p> 안에 블록 요소가 들어가는 HTML 오류(hydration mismatch)가 나지 않도록 한다.\n              <DialogDescription asChild>\n                <div>{description}</div>\n              </DialogDescription>\n            )}\n          </DialogHeader>\n        )}\n\n        {/* 본문: 길어지면 여기만 스크롤되고 헤더/푸터는 고정된다. 배경을 page 본문 영역과 같은 bg-muted/40 으로 둬서 카드형 폼과 구분되게 한다. */}\n        <div className=\"flex-1 overflow-y-auto bg-muted/40 px-6 py-4\">\n          {children}\n        </div>\n\n        {footer && (\n          <DialogFooter className=\"shrink-0 border-t px-6 py-4\">\n            {footer}\n          </DialogFooter>\n        )}\n      </DialogContent>\n    </Dialog>\n  );\n}\n","\"use client\";\n\n/**\n * AdminDrawer — 화면 가장자리에서 나오는 패널 (우선순위 9)\n *\n * Sheet 기반. 상세보기, 보조 폼, 모바일 필터 등에 사용한다. 제어 컴포넌트.\n * side 로 등장 방향을, size 로 너비를 조절한다. (좌/우일 때 적용)\n *\n * @example\n * <AdminDrawer\n *   open={open}\n *   onClose={() => setOpen(false)}\n *   side=\"right\"\n *   title=\"회원 상세\"\n *   footer={<Button onClick={() => setOpen(false)}>닫기</Button>}\n * >\n *   ...상세 내용...\n * </AdminDrawer>\n */\nimport type { ReactNode } from \"react\";\n\nimport { cn } from \"../../lib/utils\";\nimport {\n  Sheet,\n  SheetContent,\n  SheetDescription,\n  SheetFooter,\n  SheetHeader,\n  SheetTitle,\n} from \"../ui/sheet\";\n\nexport type AdminDrawerSide = \"left\" | \"right\" | \"top\" | \"bottom\";\nexport type AdminDrawerSize = \"sm\" | \"md\" | \"lg\" | \"xl\";\n\nexport interface AdminDrawerProps {\n  open: boolean;\n  onClose: () => void;\n  /** 등장 방향 (기본 right) */\n  side?: AdminDrawerSide;\n  /** 드로어 제목 */\n  title?: ReactNode;\n  /** 제목 아래 보조 설명 */\n  description?: ReactNode;\n  /** 본문 (길면 스크롤된다) */\n  children?: ReactNode;\n  /** 하단 고정 버튼 영역 */\n  footer?: ReactNode;\n  /** 너비 (좌/우 방향일 때 적용, 기본 md) */\n  size?: AdminDrawerSize;\n  className?: string;\n}\n\nconst WIDTH: Record<AdminDrawerSize, string> = {\n  sm: \"sm:max-w-sm\",\n  md: \"sm:max-w-md\",\n  lg: \"sm:max-w-lg\",\n  xl: \"sm:max-w-2xl\",\n};\n\nexport function AdminDrawer({\n  open,\n  onClose,\n  side = \"right\",\n  title,\n  description,\n  children,\n  footer,\n  size = \"md\",\n  className,\n}: AdminDrawerProps) {\n  const isHorizontal = side === \"left\" || side === \"right\";\n  // className 으로 너비(w-*/max-w-*)를 직접 주면 size·기본 max-w 캡을 풀어 그 값이 적용되게 한다.\n  const hasCustomWidth = !!className && /(?:^|\\s)(?:max-)?w-/.test(className);\n\n  return (\n    <Sheet\n      open={open}\n      onOpenChange={(next) => {\n        if (!next) onClose();\n      }}\n    >\n      <SheetContent\n        side={side}\n        className={cn(\n          isHorizontal &&\n            (hasCustomWidth ? \"sm:max-w-none\" : WIDTH[size]),\n          className\n        )}\n        // 헤더를 primary 로 칠했을 때 X 버튼도 그 위에서 보이도록 색을 맞춘다.\n        closeClassName={\n          title || description ? \"text-primary-foreground\" : undefined\n        }\n      >\n        {/* Radix Dialog 접근성을 위해 제목은 항상 둔다 (없으면 숨김) */}\n        {title || description ? (\n          <SheetHeader className=\"bg-primary\">\n            <SheetTitle className=\"text-primary-foreground font-bold\">{title}</SheetTitle>\n            {description && <SheetDescription className=\"text-ring\">{description}</SheetDescription>}\n          </SheetHeader>\n        ) : (\n          <SheetTitle className=\"sr-only\">패널</SheetTitle>\n        )}\n\n        <div className=\"flex-1 overflow-y-auto px-4\">{children}</div>\n\n        {footer && <SheetFooter>{footer}</SheetFooter>}\n      </SheetContent>\n    </Sheet>\n  );\n}\n","\"use client\";\n\n/**\n * ConfirmDialog — 화면 중앙 확인 다이얼로그 (삭제/이탈 등 위험한 액션 재확인용)\n *\n * 제어 컴포넌트. title/description 아래 취소·확인 버튼이 바로 붙어 나온다.\n * 확인 버튼은 기본으로 프라이머리 색(variant=\"default\")을 쓰고, 필요하면 destructive 로 바꿀 수 있다.\n *\n * 부모 모달이 닫힐 때 같이 닫으려면 open 을 부모의 open 상태와 함께 조합한다:\n * <ConfirmDialog open={confirmOpen && parentOpen} ... />\n *\n * @example\n * const [confirmOpen, setConfirmOpen] = useState(false);\n * <ConfirmDialog\n *   open={confirmOpen}\n *   onClose={() => setConfirmOpen(false)}\n *   title=\"제휴사를 삭제하시겠습니까?\"\n *   description=\"삭제하면 되돌릴 수 없습니다.\"\n *   confirmLabel=\"삭제\"\n *   loading={deleteMutation.isPending}\n *   onConfirm={() => deleteMutation.mutate(...)}\n * />\n */\nimport { type ReactNode } from \"react\";\n\nimport { Button } from \"../ui/button\";\nimport {\n  Dialog,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n} from \"../ui/dialog\";\n\nexport interface ConfirmDialogProps {\n  open: boolean;\n  onClose: () => void;\n  /** 다이얼로그 제목 */\n  title?: ReactNode;\n  /** 제목 아래 보조 설명 */\n  description?: ReactNode;\n  /** 확인 버튼 라벨 (기본 \"확인\") */\n  confirmLabel?: string;\n  /** 취소 버튼 라벨 (기본 \"취소\") */\n  cancelLabel?: string;\n  /** 확인 버튼 클릭 시 실행 */\n  onConfirm: () => void;\n  /** 확인 버튼 색상 (기본 \"default\" = 프라이머리 색) */\n  confirmVariant?: \"default\" | \"destructive\";\n  /** 확인 처리 중 여부 — 스피너 표시 + 처리 중엔 닫기(오버레이/ESC/취소) 막기 */\n  loading?: boolean;\n  className?: string;\n}\n\nexport function ConfirmDialog({\n  open,\n  onClose,\n  title,\n  description,\n  confirmLabel = \"확인\",\n  cancelLabel = \"취소\",\n  onConfirm,\n  confirmVariant = \"default\",\n  loading = false,\n  className,\n}: ConfirmDialogProps) {\n  return (\n    <Dialog\n      open={open}\n      onOpenChange={(next) => {\n        if (!next && !loading) onClose();\n      }}\n    >\n      <DialogContent\n        showClose={false}\n        className={className ?? \"max-w-sm\"}\n        onInteractOutside={loading ? (e) => e.preventDefault() : undefined}\n        onEscapeKeyDown={loading ? (e) => e.preventDefault() : undefined}\n      >\n        {(title || description) && (\n          <DialogHeader>\n            {title && <DialogTitle>{title}</DialogTitle>}\n            {description && (\n              <DialogDescription>{description}</DialogDescription>\n            )}\n          </DialogHeader>\n        )}\n        <DialogFooter>\n          <Button variant=\"outline\" onClick={onClose} disabled={loading}>\n            {cancelLabel}\n          </Button>\n          <Button variant={confirmVariant} loading={loading} onClick={onConfirm}>\n            {confirmLabel}\n          </Button>\n        </DialogFooter>\n      </DialogContent>\n    </Dialog>\n  );\n}\n","\"use client\";\n\n/**\n * confirmToast — sonner 토스트 기반 확인/취소 액션\n *\n * ConfirmDialog(모달)와 달리 open/onClose state 없이 함수 호출 한 번으로 띄운다 (toast.warning 과 동일한 감각).\n * sonner 의 <Toaster /> 가 이미 앱에 마운트돼 있어야 한다 (Toast 알림 기능과 동일한 전제).\n *\n * 반환값은 토스트 id — 부모 모달이 닫힐 때 같이 닫고 싶으면 toast.dismiss(id) 를 호출한다.\n *\n * @example\n * confirmToast({\n *   title: \"제휴사를 삭제하시겠습니까?\",\n *   description: \"삭제하면 되돌릴 수 없습니다.\",\n *   confirmLabel: \"삭제\",\n *   onConfirm: () => deleteMutation.mutate(...),\n * });\n *\n * @example // 부모 모달이 닫힐 때 같이 닫기\n * const toastId = useRef<string | number | null>(null);\n * toastId.current = confirmToast({ title: \"...\", onConfirm: handleDelete });\n * // 부모 close 핸들러에서:\n * if (toastId.current != null) toast.dismiss(toastId.current);\n */\nimport { type ReactNode } from \"react\";\nimport { toast } from \"sonner\";\n\nimport { Button } from \"../ui/button\";\n\nexport interface ConfirmToastOptions {\n  /** 토스트 제목 */\n  title: ReactNode;\n  /** 제목 아래 보조 설명 */\n  description?: ReactNode;\n  /** 확인 버튼 라벨 (기본 \"확인\") */\n  confirmLabel?: string;\n  /** 취소 버튼 라벨 (기본 \"취소\") */\n  cancelLabel?: string;\n  /** 확인 버튼 클릭 시 실행 */\n  onConfirm: () => void;\n  /** 취소 버튼 클릭 시 실행 (선택) */\n  onCancel?: () => void;\n  /** 확인 버튼 색상 (기본 \"default\" = 프라이머리 색) */\n  confirmVariant?: \"default\" | \"destructive\";\n  /** 자동으로 닫히지 않는 시간(ms). 기본 Infinity(사용자가 버튼을 눌러야 닫힘) */\n  duration?: number;\n  /** 화면 표시 위치 (기본 \"top-center\") */\n  position?:\n    | \"top-left\"\n    | \"top-center\"\n    | \"top-right\"\n    | \"bottom-left\"\n    | \"bottom-center\"\n    | \"bottom-right\";\n}\n\n/** 반환값: 토스트 id (toast.dismiss(id) 로 직접 닫을 때 사용) */\nexport function confirmToast(options: ConfirmToastOptions): string | number {\n  const {\n    title,\n    description,\n    confirmLabel = \"확인\",\n    cancelLabel = \"취소\",\n    onConfirm,\n    onCancel,\n    confirmVariant = \"default\",\n    duration = Infinity,\n    position = \"top-center\",\n  } = options;\n\n  return toast.custom(\n    (id) => (\n      <div className=\"w-[min(92vw,380px)] rounded-lg border bg-card p-4 shadow-lg\">\n        <div className=\"text-sm font-semibold text-foreground\">{title}</div>\n        {description && (\n          <div className=\"mt-1 text-sm text-muted-foreground\">\n            {description}\n          </div>\n        )}\n        <div className=\"mt-4 flex justify-end gap-2\">\n          <Button\n            variant=\"outline\"\n            size=\"sm\"\n            onClick={() => {\n              toast.dismiss(id);\n              onCancel?.();\n            }}\n          >\n            {cancelLabel}\n          </Button>\n          <Button\n            variant={confirmVariant}\n            size=\"sm\"\n            onClick={() => {\n              toast.dismiss(id);\n              onConfirm();\n            }}\n          >\n            {confirmLabel}\n          </Button>\n        </div>\n      </div>\n    ),\n    { position, duration }\n  );\n}\n","\"use client\";\n\n/**\n * confirmModal — antd Modal.confirm 스타일의 확인 다이얼로그\n *\n * ConfirmDialog(controlled 컴포넌트)와 달리 open/onClose state 관리 없이 함수 호출 한 번으로 띄운다.\n * 배경이 어두워지고(dim) 뒤 화면 클릭도 막히는 진짜 모달이다 — confirmToast(sonner 기반)와 달리\n * sonner 에 의존하지 않는다.\n *\n * 내부적으로 document.body 에 임시 컨테이너를 만들어 필요할 때만 렌더링하고, 닫히면(애니메이션 끝난 뒤)\n * 스스로 언마운트해서 정리한다 — 앱 루트에 별도 Provider 를 마운트해둘 필요가 없다.\n *\n * @example\n * confirmModal({\n *   title: \"제휴사를 삭제하시겠습니까?\",\n *   description: \"삭제하면 되돌릴 수 없습니다.\",\n *   confirmLabel: \"삭제\",\n *   onConfirm: () => deleteMutation.mutateAsync({ ... }),\n * });\n */\nimport { type ReactNode, useEffect, useState } from \"react\";\nimport { createRoot } from \"react-dom/client\";\n\nimport { ConfirmDialog } from \"./confirm-dialog\";\n\nexport interface ConfirmModalOptions {\n  /** 다이얼로그 제목 */\n  title?: ReactNode;\n  /** 제목 아래 보조 설명 */\n  description?: ReactNode;\n  /** 확인 버튼 라벨 (기본 \"확인\") */\n  confirmLabel?: string;\n  /** 취소 버튼 라벨 (기본 \"취소\") */\n  cancelLabel?: string;\n  /** 확인 클릭 시 실행. Promise 를 반환하면 완료될 때까지 확인 버튼이 로딩 상태가 되고, 성공해야 닫힌다. */\n  onConfirm: () => void | Promise<void>;\n  /** 취소 클릭 시 실행 (선택) */\n  onCancel?: () => void;\n  /** 확인 버튼 색상 (기본 \"default\" = 프라이머리 색) */\n  confirmVariant?: \"default\" | \"destructive\";\n}\n\n// DialogContent 의 닫힘 애니메이션(duration-200)이 끝난 뒤 언마운트하기 위한 대기 시간\nconst CLOSE_ANIMATION_MS = 200;\n\nfunction ConfirmModalRoot({\n  options,\n  onExitComplete,\n}: {\n  options: ConfirmModalOptions;\n  onExitComplete: () => void;\n}) {\n  const [open, setOpen] = useState(true);\n  const [loading, setLoading] = useState(false);\n\n  useEffect(() => {\n    if (open) return;\n    const timer = setTimeout(onExitComplete, CLOSE_ANIMATION_MS);\n    return () => clearTimeout(timer);\n  }, [open, onExitComplete]);\n\n  return (\n    <ConfirmDialog\n      open={open}\n      loading={loading}\n      title={options.title}\n      description={options.description}\n      confirmLabel={options.confirmLabel}\n      cancelLabel={options.cancelLabel}\n      confirmVariant={options.confirmVariant}\n      onClose={() => {\n        setOpen(false);\n        options.onCancel?.();\n      }}\n      onConfirm={async () => {\n        try {\n          setLoading(true);\n          await options.onConfirm();\n          setOpen(false);\n        } finally {\n          setLoading(false);\n        }\n      }}\n    />\n  );\n}\n\nexport function confirmModal(options: ConfirmModalOptions) {\n  if (typeof document === \"undefined\") return;\n\n  const container = document.createElement(\"div\");\n  document.body.appendChild(container);\n  const root = createRoot(container);\n\n  const dispose = () => {\n    root.unmount();\n    container.remove();\n  };\n\n  root.render(\n    <ConfirmModalRoot options={options} onExitComplete={dispose} />\n  );\n}\n","\"use client\";\n\n/**\n * Tabs — 콘텐츠 전환용 탭 (Radix Tabs 기반)\n *\n * AdminTabs 의 기반 프리미티브. 직접 조합해서 쓸 수도 있다.\n * variant 로 스타일을 고른다 (기본 \"line\").\n * - \"line\": 밑줄 탭 (antd 기본 스타일). 배경색이 아니라 밑줄/글자색으로 활성 상태를 표시해서\n *   무채색(그레이스케일) 테마처럼 배경 대비가 약한 경우에도 항상 잘 보인다.\n * - \"segment\": 알약형 배경 탭 (shadcn 기본 스타일). 배경색 대비가 뚜렷한 테마에서 사용.\n *\n * @example\n * <Tabs defaultValue=\"info\">\n *   <TabsList>\n *     <TabsTrigger value=\"info\">기본 정보</TabsTrigger>\n *     <TabsTrigger value=\"history\">변경 이력</TabsTrigger>\n *   </TabsList>\n *   <TabsContent value=\"info\">...</TabsContent>\n *   <TabsContent value=\"history\">...</TabsContent>\n * </Tabs>\n * <Tabs defaultValue=\"info\" variant=\"segment\">...</Tabs>\n */\nimport { type ComponentProps, createContext, useContext } from \"react\";\nimport * as TabsPrimitive from \"@radix-ui/react-tabs\";\n\nimport { cn } from \"../../lib/utils\";\n\nexport type TabsVariant = \"line\" | \"segment\";\n\nconst TabsVariantContext = createContext<TabsVariant>(\"line\");\n\nfunction Tabs({\n  className,\n  variant = \"line\",\n  ...props\n}: ComponentProps<typeof TabsPrimitive.Root> & { variant?: TabsVariant }) {\n  return (\n    <TabsVariantContext.Provider value={variant}>\n      <TabsPrimitive.Root\n        data-slot=\"tabs\"\n        className={cn(\"flex flex-col gap-2\", className)}\n        {...props}\n      />\n    </TabsVariantContext.Provider>\n  );\n}\n\nfunction TabsList({\n  className,\n  ...props\n}: ComponentProps<typeof TabsPrimitive.List>) {\n  const variant = useContext(TabsVariantContext);\n  return (\n    <TabsPrimitive.List\n      data-slot=\"tabs-list\"\n      className={cn(\n        \"inline-flex w-fit items-center\",\n        variant === \"segment\"\n          ? \"h-9 justify-center rounded-lg bg-muted p-[3px] text-muted-foreground\"\n          : \"gap-4\",\n        className\n      )}\n      {...props}\n    />\n  );\n}\n\nfunction TabsTrigger({\n  className,\n  ...props\n}: ComponentProps<typeof TabsPrimitive.Trigger>) {\n  const variant = useContext(TabsVariantContext);\n  return (\n    <TabsPrimitive.Trigger\n      data-slot=\"tabs-trigger\"\n      className={cn(\n        \"inline-flex items-center justify-center gap-1.5 text-sm font-medium whitespace-nowrap transition-[color,box-shadow,background-color] outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50\",\n        variant === \"segment\"\n          ? \"h-[calc(100%-1px)] flex-1 rounded-md border border-transparent px-2 py-1 text-muted-foreground focus-visible:border-ring data-[state=active]:bg-primary data-[state=active]:text-primary-foreground data-[state=active]:shadow-sm\"\n          : \"-mb-px rounded-t-md border-b-2 border-transparent px-2 pb-2 text-muted-foreground hover:bg-muted/50 hover:text-foreground data-[state=active]:border-primary data-[state=active]:text-primary\",\n        className\n      )}\n      {...props}\n    />\n  );\n}\n\nfunction TabsContent({\n  className,\n  ...props\n}: ComponentProps<typeof TabsPrimitive.Content>) {\n  return (\n    <TabsPrimitive.Content\n      data-slot=\"tabs-content\"\n      className={cn(\"flex-1 outline-none\", className)}\n      {...props}\n    />\n  );\n}\n\nexport { Tabs, TabsList, TabsTrigger, TabsContent };\n","\"use client\";\n\n/**\n * AdminTabs — 탭으로 콘텐츠를 전환하는 공통 컴포넌트\n *\n * 탭 목록과 각 탭의 콘텐츠를 items 로 한번에 받는다. 상세보기 모달/드로어 안에서\n * \"기본 정보 / 변경 이력\" 같이 영역을 나눌 때 AdminModal, AdminDrawer 등의 children 으로 바로 넣으면 된다.\n * value 를 주면 제어 컴포넌트, 안 주면 비제어(내부 상태)로 동작한다.\n *\n * type 으로 스타일을 고른다 (기본 \"line\" — 밑줄 탭, antd 기본 스타일).\n * \"segment\"를 주면 알약형 배경 탭(shadcn 기본 스타일)이 된다.\n *\n * @example\n * <AdminTabs\n *   items={[\n *     { value: \"info\", label: \"기본 정보\", content: <AdminDescriptions items={items} /> },\n *     { value: \"history\", label: \"변경 이력\", content: <HistoryTable /> },\n *   ]}\n * />\n * <AdminTabs type=\"segment\" items={[...]} />\n */\nimport type { ReactNode } from \"react\";\n\nimport { cn } from \"../../lib/utils\";\nimport { Tabs, TabsContent, TabsList, TabsTrigger, type TabsVariant } from \"../ui/tabs\";\n\nexport interface AdminTabItem {\n  value: string;\n  label: ReactNode;\n  content: ReactNode;\n  disabled?: boolean;\n}\n\nexport interface AdminTabsProps {\n  items: AdminTabItem[];\n  /** 탭 스타일 (기본 \"line\") */\n  type?: TabsVariant;\n  /** 선택된 탭 값 (제어 컴포넌트로 쓸 때) */\n  value?: string;\n  /** 초기 선택 탭 값 (비제어). 안 주면 첫 번째 탭 */\n  defaultValue?: string;\n  onValueChange?: (value: string) => void;\n  className?: string;\n  listClassName?: string;\n  contentClassName?: string;\n}\n\nexport function AdminTabs({\n  items,\n  type = \"line\",\n  value,\n  defaultValue,\n  onValueChange,\n  className,\n  listClassName,\n  contentClassName,\n}: AdminTabsProps) {\n  return (\n    <Tabs\n      variant={type}\n      value={value}\n      defaultValue={defaultValue ?? items[0]?.value}\n      onValueChange={onValueChange}\n      className={className}\n    >\n      <TabsList className={cn(\"w-full\", listClassName)}>\n        {items.map((item) => (\n          <TabsTrigger key={item.value} value={item.value} disabled={item.disabled}>\n            {item.label}\n          </TabsTrigger>\n        ))}\n      </TabsList>\n      {items.map((item) => (\n        <TabsContent\n          key={item.value}\n          value={item.value}\n          className={contentClassName}\n        >\n          {item.content}\n        </TabsContent>\n      ))}\n    </Tabs>\n  );\n}\n","\"use client\";\n\n/**\n * AdminSteps — 단계형 진행 표시기 (Step / Wizard)\n *\n * 여러 단계로 나뉜 등록/설정 폼(마법사)에서 현재 진행 단계를 보여준다.\n * current(0부터 시작하는 인덱스)보다 앞선 단계는 완료(체크) 표시로, 현재 단계는 primary 색으로\n * 강조되고, 뒤의 단계는 흐리게 표시된다. onChange 를 주면 이미 지난(완료된) 단계를 클릭해서\n * 되돌아갈 수 있다 — 아직 오지 않은 단계는 검증을 건너뛰지 못하도록 클릭이 막혀 있다.\n *\n * 모바일(좁은 화면)에서는 원형 스텝을 모두 나열하는 대신 \"현재 단계 제목 + N/전체 + 진행 바\"로\n * 축약해서 보여준다 (direction=\"horizontal\" 일 때만 — vertical 은 이미 좁은 화면에 적합하다).\n *\n * @example\n * <AdminSteps\n *   current={step}\n *   onChange={setStep}\n *   items={[\n *     { title: \"기본 정보\" },\n *     { title: \"도어 & 카메라\" },\n *     { title: \"결제 / 인증\" },\n *     { title: \"외부 시스템\" },\n *     { title: \"확인\" },\n *   ]}\n * />\n */\nimport { Check } from \"lucide-react\";\nimport type { ReactNode } from \"react\";\n\nimport { useIsMobile } from \"../../hooks/use-is-mobile\";\nimport { cn } from \"../../lib/utils\";\n\nexport type AdminStepStatus = \"process\" | \"error\";\nexport type AdminStepsDirection = \"horizontal\" | \"vertical\";\nexport type AdminStepsSize = \"sm\" | \"md\";\n\nexport interface AdminStepItem {\n  title: ReactNode;\n  /** 제목 아래 보조 설명 */\n  description?: ReactNode;\n  /** 완료된 단계라도 클릭 이동을 막는다 */\n  disabled?: boolean;\n}\n\nexport interface AdminStepsProps {\n  items: AdminStepItem[];\n  /** 현재 단계 인덱스 (0부터 시작) */\n  current: number;\n  /** 현재 단계의 상태. \"error\" 를 주면 현재 단계가 destructive 색으로 표시된다. (기본 \"process\") */\n  status?: AdminStepStatus;\n  /** 완료된 단계를 클릭해 되돌아갈 수 있게 한다. 안 주면 클릭 이동 없이 표시만 한다. */\n  onChange?: (index: number) => void;\n  /** 배치 방향 (기본 \"horizontal\") */\n  direction?: AdminStepsDirection;\n  /** 크기 (기본 \"md\") */\n  size?: AdminStepsSize;\n  className?: string;\n}\n\nconst CIRCLE_SIZE: Record<AdminStepsSize, string> = {\n  sm: \"size-6 text-xs\",\n  md: \"size-7 text-sm\",\n};\n\nconst ICON_SIZE: Record<AdminStepsSize, string> = {\n  sm: \"size-3\",\n  md: \"size-3.5\",\n};\n\nconst TITLE_SIZE: Record<AdminStepsSize, string> = {\n  sm: \"text-xs\",\n  md: \"text-sm\",\n};\n\nexport function AdminSteps({\n  items,\n  current,\n  status = \"process\",\n  onChange,\n  direction = \"horizontal\",\n  size = \"md\",\n  className,\n}: AdminStepsProps) {\n  const isMobile = useIsMobile();\n\n  if (isMobile && direction === \"horizontal\") {\n    return (\n      <MobileSteps\n        items={items}\n        current={current}\n        status={status}\n        className={className}\n      />\n    );\n  }\n\n  const isVertical = direction === \"vertical\";\n\n  return (\n    <ol\n      className={cn(\n        \"flex w-full\",\n        isVertical ? \"flex-col\" : \"items-center\",\n        className\n      )}\n    >\n      {items.map((item, index) => {\n        const isLast = index === items.length - 1;\n        const isDone = index < current;\n        const isCurrent = index === current;\n        const isError = isCurrent && status === \"error\";\n        const canClick = !!onChange && !item.disabled && isDone;\n        const connectorFilled = index < current;\n\n        const circle = (\n          <span\n            className={cn(\n              \"flex shrink-0 items-center justify-center rounded-full border font-medium\",\n              CIRCLE_SIZE[size],\n              isError\n                ? \"border-destructive bg-destructive text-destructive-foreground\"\n                : isDone\n                ? \"border-primary bg-primary text-primary-foreground\"\n                : isCurrent\n                ? \"border-primary bg-primary text-primary-foreground\"\n                : \"border-border bg-background text-muted-foreground\"\n            )}\n          >\n            {isDone ? <Check className={ICON_SIZE[size]} /> : index + 1}\n          </span>\n        );\n\n        const label = (\n          <span className=\"flex min-w-0 flex-col text-left\">\n            <span\n              className={cn(\n                TITLE_SIZE[size],\n                \"truncate\",\n                isError\n                  ? \"font-semibold text-destructive\"\n                  : isCurrent\n                  ? \"font-semibold text-foreground\"\n                  : isDone\n                  ? \"font-medium text-foreground\"\n                  : \"font-medium text-muted-foreground\"\n              )}\n            >\n              {item.title}\n            </span>\n            {item.description && (\n              <span className=\"truncate text-xs text-muted-foreground\">\n                {item.description}\n              </span>\n            )}\n          </span>\n        );\n\n        const content = (\n          <button\n            type=\"button\"\n            disabled={!canClick}\n            aria-current={isCurrent ? \"step\" : undefined}\n            onClick={canClick ? () => onChange?.(index) : undefined}\n            className={cn(\n              \"flex min-w-0 items-center gap-2 rounded-md bg-transparent p-0 text-left\",\n              canClick ? \"cursor-pointer hover:opacity-80\" : \"cursor-default\"\n            )}\n          >\n            {circle}\n            {label}\n          </button>\n        );\n\n        if (isVertical) {\n          return (\n            <li key={index} className={cn(\"flex gap-3\", !isLast && \"pb-6\")}>\n              <div className=\"flex flex-col items-center\">\n                {circle}\n                {!isLast && (\n                  <span\n                    className={cn(\n                      \"mt-1 w-px flex-1\",\n                      connectorFilled ? \"bg-primary\" : \"bg-border\"\n                    )}\n                  />\n                )}\n              </div>\n              <button\n                type=\"button\"\n                disabled={!canClick}\n                aria-current={isCurrent ? \"step\" : undefined}\n                onClick={canClick ? () => onChange?.(index) : undefined}\n                className={cn(\n                  \"flex-1 bg-transparent p-0 pt-0.5 text-left\",\n                  canClick ? \"cursor-pointer hover:opacity-80\" : \"cursor-default\"\n                )}\n              >\n                {label}\n              </button>\n            </li>\n          );\n        }\n\n        return (\n          <li key={index} className=\"flex min-w-0 flex-1 items-center\">\n            {content}\n            {!isLast && (\n              <span\n                className={cn(\n                  \"mx-3 h-px flex-1\",\n                  connectorFilled ? \"bg-primary\" : \"bg-border\"\n                )}\n              />\n            )}\n          </li>\n        );\n      })}\n    </ol>\n  );\n}\n\nfunction MobileSteps({\n  items,\n  current,\n  status,\n  className,\n}: {\n  items: AdminStepItem[];\n  current: number;\n  status: AdminStepStatus;\n  className?: string;\n}) {\n  const total = items.length;\n  const activeItem = items[current];\n  const isError = status === \"error\";\n  const percent = total > 0 ? ((current + 1) / total) * 100 : 0;\n\n  return (\n    <div className={cn(\"w-full\", className)}>\n      <div className=\"flex items-center justify-between gap-3\">\n        <span\n          className={cn(\n            \"text-sm font-semibold\",\n            isError ? \"text-destructive\" : \"text-foreground\"\n          )}\n        >\n          {current + 1}. {activeItem?.title}\n        </span>\n        <span className=\"shrink-0 text-xs text-muted-foreground\">\n          {current + 1} / {total}\n        </span>\n      </div>\n      {activeItem?.description && (\n        <p className=\"mt-0.5 text-xs text-muted-foreground\">\n          {activeItem.description}\n        </p>\n      )}\n      <div className=\"mt-2 h-1.5 w-full overflow-hidden rounded-full bg-muted\">\n        <div\n          className={cn(\n            \"h-full rounded-full transition-all\",\n            isError ? \"bg-destructive\" : \"bg-primary\"\n          )}\n          style={{ width: `${percent}%` }}\n        />\n      </div>\n    </div>\n  );\n}\n","\"use client\";\n\n/**\n * AdminWizard — 단계별 콘텐츠를 \"마법사(steps)\" 또는 \"탭(tabs)\"으로 보여주는 컴포넌트\n *\n * 등록(add)처럼 순서대로 입력해야 하는 흐름은 variant=\"steps\"로 — AdminSteps 진행 표시 +\n * 이전/다음 버튼과 함께 현재 단계의 content 만 보여준다. 수정(update)처럼 이미 값이 다 있어서\n * 아무 섹션이나 바로 이동해서 고치는 흐름은 variant=\"tabs\"로 — AdminTabs 로 자유롭게 전환한다.\n *\n * 섹션(제목+내용)을 items 배열 하나로만 정의하면 되고, variant 에 따라 AdminSteps/AdminTabs 로\n * 자동으로 갈라 렌더링해준다 — steps 용 배열과 tabs 용 배열을 따로 만들 필요가 없다.\n * AdminSteps 처럼 완전한 제어 컴포넌트다 (current/onChange 를 직접 관리).\n *\n * @example\n * const [step, setStep] = useState(0);\n * <AdminWizard\n *   variant={mode === \"add\" ? \"steps\" : \"tabs\"}\n *   current={step}\n *   onChange={setStep}\n *   items={[\n *     { key: \"basic\", title: \"기본 정보\", content: <KioskBasicInfo form={form} /> },\n *     { key: \"camera\", title: \"카메라\", content: <KioskCamera form={form} /> },\n *     { key: \"confirm\", title: \"확인\", content: <KioskConfirm form={form} /> },\n *   ]}\n * />\n */\nimport type { ReactNode } from \"react\";\n\nimport { Button } from \"../ui/button\";\nimport { AdminTabs } from \"../tabs/admin-tabs\";\nimport { AdminSteps, type AdminStepsSize } from \"./admin-steps\";\n\nexport type AdminWizardVariant = \"steps\" | \"tabs\";\n\nexport interface AdminWizardItem {\n  /** AdminTabs 로 렌더링될 때 사용하는 고유 key (tabs value 로도 쓰인다) */\n  key: string;\n  title: ReactNode;\n  /** variant=\"steps\" 일 때만 표시되는 단계 설명 */\n  description?: ReactNode;\n  /** 이 단계/탭에서 보여줄 콘텐츠 */\n  content: ReactNode;\n  disabled?: boolean;\n}\n\nexport interface AdminWizardProps {\n  items: AdminWizardItem[];\n  /** \"steps\"(기본): 이전/다음 버튼이 있는 순차 마법사. \"tabs\": 자유 이동 탭 */\n  variant?: AdminWizardVariant;\n  /** 현재 단계/탭 인덱스 */\n  current: number;\n  onChange: (index: number) => void;\n  /** variant=\"steps\" 일 때 이전 버튼 라벨 (기본 \"이전\") */\n  prevLabel?: ReactNode;\n  /** variant=\"steps\" 일 때 다음 버튼 라벨 (기본 \"다음\") */\n  nextLabel?: ReactNode;\n  /** AdminSteps 크기 (variant=\"steps\" 일 때만 적용, 기본 \"md\") */\n  size?: AdminStepsSize;\n  className?: string;\n  /** 콘텐츠 영역(각 단계/탭의 content)에 적용할 클래스 */\n  contentClassName?: string;\n  /**\n   * variant=\"steps\" 일 때 기본 제공되는 이전/다음 버튼(하단 네비게이션)을 숨긴다.\n   * 모달 footer 등 다른 위치에 직접 이전/다음 버튼을 두고 싶을 때 사용한다 (기본 false=보임).\n   * 이 경우 이전/다음 버튼은 그냥 onChange(current - 1) / onChange(current + 1) 을 호출하면 된다.\n   */\n  hideNav?: boolean;\n}\n\nexport function AdminWizard({\n  items,\n  variant = \"steps\",\n  current,\n  onChange,\n  prevLabel = \"이전\",\n  nextLabel = \"다음\",\n  size = \"md\",\n  className,\n  contentClassName,\n  hideNav = false,\n}: AdminWizardProps) {\n  if (variant === \"tabs\") {\n    return (\n      <AdminTabs\n        className={className}\n        contentClassName={contentClassName}\n        value={items[current]?.key}\n        onValueChange={(value) => {\n          const index = items.findIndex((item) => item.key === value);\n          if (index !== -1) onChange(index);\n        }}\n        items={items.map((item) => ({\n          value: item.key,\n          label: item.title,\n          content: item.content,\n          disabled: item.disabled,\n        }))}\n      />\n    );\n  }\n\n  const isFirst = current === 0;\n  const isLast = current === items.length - 1;\n\n  return (\n    <div className={className}>\n      <AdminSteps\n        className=\"mb-6\"\n        size={size}\n        current={current}\n        onChange={onChange}\n        items={items.map((item) => ({\n          title: item.title,\n          description: item.description,\n          disabled: item.disabled,\n        }))}\n      />\n      <div className={contentClassName}>{items[current]?.content}</div>\n      {!hideNav && (\n        <div className=\"mt-4 flex justify-between border-t pt-4\">\n          <Button\n            type=\"button\"\n            variant=\"outline\"\n            disabled={isFirst}\n            onClick={() => onChange(Math.max(current - 1, 0))}\n          >\n            {prevLabel}\n          </Button>\n          <Button\n            type=\"button\"\n            disabled={isLast}\n            onClick={() => onChange(Math.min(current + 1, items.length - 1))}\n          >\n            {nextLabel}\n          </Button>\n        </div>\n      )}\n    </div>\n  );\n}\n","\"use client\";\n\n/**\n * AdminTransfer — 두 목록 간 항목 이동 (Ant Design Transfer 스타일)\n *\n * 각 패널 구성: ① 상단 건수 → ② 검색창 → ③ 표(헤더 전체선택 + 행 목록).\n * 행에는 이미지/설명을 넣을 수 있고, 목록은 스크롤된다.\n * pageSize 를 주면 패널별 클라이언트 페이지네이션을 쓴다. (서버 페이징 아님)\n *\n * 제어 컴포넌트: targetKeys(우측에 있는 key 배열) 와 onChange 로 제어한다.\n *\n * @example\n * const [targetKeys, setTargetKeys] = useState<string[]>([]);\n * <AdminTransfer\n *   dataSource={items}\n *   targetKeys={targetKeys}\n *   onChange={setTargetKeys}\n *   titles={[\"미부여\", \"부여됨\"]}\n *   pageSize={10}\n * />\n */\nimport { type ReactNode, useState } from \"react\";\nimport { ChevronLeft, ChevronRight, Search } from \"lucide-react\";\n\nimport { cn } from \"../../lib/utils\";\nimport { Button } from \"../ui/button\";\nimport { Checkbox } from \"../ui/checkbox\";\nimport { AdminPagination } from \"../table/admin-pagination\";\n\nexport interface TransferItem {\n  key: string;\n  /** 기본(컬럼 미지정) 렌더용 제목 */\n  title?: string;\n  /** 행 앞 이미지 URL (기본 렌더) */\n  image?: string;\n  /** 제목 아래 보조 설명 (기본 렌더) */\n  description?: string;\n  disabled?: boolean;\n  /** 컬럼 모드에서 dataIndex 로 참조할 필드 */\n  [field: string]: unknown;\n}\n\n/** 표 형태 컬럼 정의 (columns 지정 시) */\nexport interface TransferColumn {\n  title: ReactNode;\n  /** 표시할 필드명 (render 없으면 item[dataIndex]) */\n  dataIndex?: string;\n  /** 너비 (number=px, 미지정 시 1fr) */\n  width?: number | string;\n  /** 셀 커스텀 렌더 */\n  render?: (item: TransferItem) => ReactNode;\n}\n\nexport interface AdminTransferProps {\n  dataSource: TransferItem[];\n  /** 우측(선택됨) 패널에 있는 항목 key 배열 */\n  targetKeys: string[];\n  onChange: (targetKeys: string[]) => void;\n  /** [좌측, 우측] 패널 제목 (기본 [\"목록\", \"선택됨\"]) */\n  titles?: [ReactNode, ReactNode];\n  /** 검색 입력 표시 (기본 true) */\n  searchable?: boolean;\n  searchPlaceholder?: string;\n  /** 리스트 높이(px, 기본 280) */\n  listHeight?: number;\n  /** 주면 패널별 클라이언트 페이지네이션 사용 */\n  pageSize?: number;\n  /** 표 컬럼 정의. 주면 헤더에 컬럼명 + 행에 표 형태로 렌더링 */\n  columns?: TransferColumn[];\n  /** 항목 표시 커스터마이징 (columns 미지정 시, 기본: 이미지 + 제목/설명) */\n  render?: (item: TransferItem) => ReactNode;\n  className?: string;\n}\n\nexport function AdminTransfer({\n  dataSource,\n  targetKeys,\n  onChange,\n  titles = [\"목록\", \"선택됨\"],\n  searchable = true,\n  searchPlaceholder = \"검색...\",\n  listHeight = 280,\n  pageSize,\n  columns,\n  render,\n  className,\n}: AdminTransferProps) {\n  const [checked, setChecked] = useState<string[]>([]);\n\n  const targetSet = new Set(targetKeys);\n  const leftItems = dataSource.filter((d) => !targetSet.has(d.key));\n  const rightItems = dataSource.filter((d) => targetSet.has(d.key));\n\n  const checkedSet = new Set(checked);\n  const leftChecked = leftItems.filter(\n    (i) => checkedSet.has(i.key) && !i.disabled\n  );\n  const rightChecked = rightItems.filter(\n    (i) => checkedSet.has(i.key) && !i.disabled\n  );\n\n  const moveRight = () => {\n    const moving = leftChecked.map((i) => i.key);\n    onChange([...targetKeys, ...moving]);\n    setChecked((c) => c.filter((k) => !moving.includes(k)));\n  };\n  const moveLeft = () => {\n    const moving = new Set(rightChecked.map((i) => i.key));\n    onChange(targetKeys.filter((k) => !moving.has(k)));\n    setChecked((c) => c.filter((k) => !moving.has(k)));\n  };\n\n  const toggle = (key: string) =>\n    setChecked((c) =>\n      c.includes(key) ? c.filter((k) => k !== key) : [...c, key]\n    );\n\n  const toggleAll = (keys: string[], next: boolean) =>\n    setChecked((c) => {\n      const set = new Set(c);\n      if (next) keys.forEach((k) => set.add(k));\n      else keys.forEach((k) => set.delete(k));\n      return [...set];\n    });\n\n  const panelProps = {\n    checkedKeys: checkedSet,\n    onToggle: toggle,\n    onToggleAll: toggleAll,\n    searchable,\n    searchPlaceholder,\n    listHeight,\n    pageSize,\n    columns,\n    render,\n  };\n\n  return (\n    <div className={cn(\"flex items-stretch gap-3\", className)}>\n      <TransferPanel title={titles[0]} items={leftItems} {...panelProps} />\n\n      <div className=\"flex flex-col justify-center gap-2\">\n        <Button\n          type=\"button\"\n          // 활성: solid(primary), 비활성: outline+흐림 → 상태가 또렷이 구분된다\n          variant={leftChecked.length > 0 ? \"default\" : \"outline\"}\n          size=\"icon\"\n          aria-label=\"오른쪽으로 이동\"\n          disabled={leftChecked.length === 0}\n          onClick={moveRight}\n          className=\"disabled:opacity-40\"\n        >\n          <ChevronRight className=\"size-4\" />\n        </Button>\n        <Button\n          type=\"button\"\n          variant={rightChecked.length > 0 ? \"default\" : \"outline\"}\n          size=\"icon\"\n          aria-label=\"왼쪽으로 이동\"\n          disabled={rightChecked.length === 0}\n          onClick={moveLeft}\n          className=\"disabled:opacity-40\"\n        >\n          <ChevronLeft className=\"size-4\" />\n        </Button>\n      </div>\n\n      <TransferPanel title={titles[1]} items={rightItems} {...panelProps} />\n    </div>\n  );\n}\n\ninterface TransferPanelProps {\n  title: ReactNode;\n  items: TransferItem[];\n  checkedKeys: Set<string>;\n  onToggle: (key: string) => void;\n  onToggleAll: (keys: string[], next: boolean) => void;\n  searchable: boolean;\n  searchPlaceholder: string;\n  listHeight: number;\n  pageSize?: number;\n  columns?: TransferColumn[];\n  render?: (item: TransferItem) => ReactNode;\n}\n\n/** 항목의 검색 대상 텍스트 (컬럼이 있으면 컬럼 값들, 없으면 제목/설명) */\nfunction itemText(item: TransferItem, columns?: TransferColumn[]): string {\n  if (columns?.length) {\n    return columns\n      .map((c) => (c.dataIndex ? String(item[c.dataIndex] ?? \"\") : \"\"))\n      .join(\" \");\n  }\n  return `${item.title ?? \"\"} ${item.description ?? \"\"}`;\n}\n\nfunction TransferPanel({\n  title,\n  items,\n  checkedKeys,\n  onToggle,\n  onToggleAll,\n  searchable,\n  searchPlaceholder,\n  listHeight,\n  pageSize,\n  columns,\n  render,\n}: TransferPanelProps) {\n  const [search, setSearch] = useState(\"\");\n  const [page, setPage] = useState(1);\n\n  const q = search.trim().toLowerCase();\n  const visible = q\n    ? items.filter((i) => itemText(i, columns).toLowerCase().includes(q))\n    : items;\n\n  // 컬럼 모드: [체크박스 2rem, ...컬럼 너비] 그리드 트랙\n  const useColumns = !!columns?.length;\n  const gridTemplate = useColumns\n    ? [\n        \"1.5rem\",\n        ...columns!.map((c) =>\n          c.width == null\n            ? \"minmax(0,1fr)\"\n            : typeof c.width === \"number\"\n              ? `${c.width}px`\n              : c.width\n        ),\n      ].join(\" \")\n    : undefined;\n\n  // 전체선택은 검색결과(visible) 전체의 활성 항목 기준\n  const enabled = visible.filter((i) => !i.disabled);\n  const checkedCount = visible.filter((i) => checkedKeys.has(i.key)).length;\n  const allChecked =\n    enabled.length > 0 && enabled.every((i) => checkedKeys.has(i.key));\n  const someChecked = checkedCount > 0 && !allChecked;\n\n  // 페이지네이션 (선택적, 클라이언트)\n  const curPage = pageSize ? Math.min(page, Math.max(1, Math.ceil(visible.length / pageSize))) : 1;\n  const rows = pageSize\n    ? visible.slice((curPage - 1) * pageSize, curPage * pageSize)\n    : visible;\n\n  return (\n    <div className=\"flex w-full min-w-0 flex-1 flex-col overflow-hidden rounded-lg border bg-card\">\n      {/* ① 건수 */}\n      <div className=\"flex items-center gap-2 px-3 py-2 text-sm\">\n        <span className=\"font-medium\">{title}</span>\n        <span className=\"ml-auto text-xs text-muted-foreground\">\n          총 <b className=\"text-foreground\">{visible.length}</b>건\n          {checkedCount > 0 && (\n            <>\n              {\" · 선택 \"}\n              <b className=\"text-foreground\">{checkedCount}</b>\n            </>\n          )}\n        </span>\n      </div>\n\n      {/* ② 검색 (테두리 박스로 감싸고 여백) */}\n      {searchable && (\n        <div className=\"border-t px-3 py-2\">\n          <div className=\"flex h-9 items-center gap-2 rounded-md border border-input bg-transparent px-3 shadow-xs focus-within:border-ring focus-within:ring-[3px] focus-within:ring-ring/50\">\n            <Search className=\"size-4 shrink-0 text-muted-foreground\" />\n            <input\n              value={search}\n              onChange={(e) => {\n                setSearch(e.target.value);\n                setPage(1);\n              }}\n              placeholder={searchPlaceholder}\n              className=\"h-full w-full bg-transparent text-sm outline-none placeholder:text-muted-foreground\"\n            />\n          </div>\n        </div>\n      )}\n\n      {/* ③ 표 헤더 (전체선택 + 컬럼명) */}\n      {useColumns ? (\n        <div\n          className=\"grid items-center gap-x-3 border-t border-b bg-muted px-4 py-2 text-xs font-medium text-muted-foreground\"\n          style={{ gridTemplateColumns: gridTemplate }}\n        >\n          <Checkbox\n            checked={allChecked ? true : someChecked ? \"indeterminate\" : false}\n            onCheckedChange={(v) =>\n              onToggleAll(\n                enabled.map((i) => i.key),\n                !!v\n              )\n            }\n            aria-label=\"전체 선택\"\n            disabled={enabled.length === 0}\n          />\n          {columns!.map((c, ci) => (\n            <span key={ci} className=\"truncate\">\n              {c.title}\n            </span>\n          ))}\n        </div>\n      ) : (\n        <div className=\"flex items-center gap-2 border-t border-b bg-muted px-4 py-2 text-xs font-medium text-muted-foreground\">\n          <Checkbox\n            checked={allChecked ? true : someChecked ? \"indeterminate\" : false}\n            onCheckedChange={(v) =>\n              onToggleAll(\n                enabled.map((i) => i.key),\n                !!v\n              )\n            }\n            aria-label=\"전체 선택\"\n            disabled={enabled.length === 0}\n          />\n          <span>전체</span>\n          <span className=\"ml-auto\">\n            {checkedCount}/{visible.length}\n          </span>\n        </div>\n      )}\n\n      {/* ③ 행 목록 (스크롤) */}\n      <ul\n        className=\"overflow-y-auto\"\n        style={{ height: listHeight }}\n      >\n        {rows.length === 0 ? (\n          <li className=\"flex h-full items-center justify-center p-4 text-sm text-muted-foreground\">\n            항목이 없습니다.\n          </li>\n        ) : (\n          rows.map((item) => (\n            <li key={item.key} className=\"border-b last:border-0\">\n              <label\n                className={cn(\n                  \"cursor-pointer text-sm transition-colors hover:bg-accent/50\",\n                  useColumns\n                    ? \"grid items-center gap-x-3 px-4 py-2\"\n                    : \"flex items-center gap-2 px-4 py-2\",\n                  item.disabled && \"cursor-not-allowed opacity-50\"\n                )}\n                style={\n                  useColumns\n                    ? { gridTemplateColumns: gridTemplate }\n                    : undefined\n                }\n              >\n                <Checkbox\n                  checked={checkedKeys.has(item.key)}\n                  onCheckedChange={() => onToggle(item.key)}\n                  disabled={item.disabled}\n                />\n                {useColumns ? (\n                  columns!.map((c, ci) => (\n                    <span key={ci} className=\"min-w-0 truncate\">\n                      {c.render\n                        ? c.render(item)\n                        : c.dataIndex\n                          ? (item[c.dataIndex] as ReactNode)\n                          : null}\n                    </span>\n                  ))\n                ) : render ? (\n                  render(item)\n                ) : (\n                  <>\n                    {item.image && (\n                      // eslint-disable-next-line @next/next/no-img-element\n                      <img\n                        src={item.image}\n                        alt=\"\"\n                        className=\"size-8 shrink-0 rounded object-cover\"\n                      />\n                    )}\n                    <span className=\"min-w-0 flex-1\">\n                      <span className=\"block truncate\">{item.title}</span>\n                      {item.description && (\n                        <span className=\"block truncate text-xs text-muted-foreground\">\n                          {item.description}\n                        </span>\n                      )}\n                    </span>\n                  </>\n                )}\n              </label>\n            </li>\n          ))\n        )}\n      </ul>\n\n      {/* 페이지네이션 (선택적) */}\n      {pageSize && visible.length > pageSize && (\n        <div className=\"border-t px-3 py-2\">\n          <AdminPagination\n            page={curPage}\n            pageSize={pageSize}\n            total={visible.length}\n            onPageChange={setPage}\n            showJump={false}\n          />\n        </div>\n      )}\n    </div>\n  );\n}\n","\"use client\";\n\n/**\n * AdminImage — 클릭하면 확대(라이트박스)되는 이미지\n *\n * 썸네일을 보여주고, 클릭하면 전체화면 오버레이에 큰 이미지를 띄운다.\n * 오버레이/X 버튼/Esc 로 닫는다. (Radix Dialog 기반 — 접근성·포커스 처리 포함)\n *\n * 예외 처리:\n * - src 가 없으면 \"이미지 없음\" placeholder 표시 (확대 비활성)\n * - 이미지 로드 실패 시 \"이미지를 불러올 수 없습니다\" 표시 (확대 비활성)\n *\n * @example\n * <AdminImage src={thumbUrl} alt=\"상품\" className=\"size-12 rounded-md\" />\n * <AdminImage src={thumbUrl} previewSrc={fullUrl} className=\"size-16 rounded\" />\n */\nimport { type ComponentProps, useState } from \"react\";\nimport * as DialogPrimitive from \"@radix-ui/react-dialog\";\nimport { ImageOff, X, ZoomIn } from \"lucide-react\";\n\nimport { cn } from \"../../lib/utils\";\n\nexport interface AdminImageProps\n  extends Omit<ComponentProps<\"img\">, \"onClick\" | \"src\"> {\n  /** 이미지 URL (없으면 \"이미지 없음\" 표시) */\n  src?: string | null;\n  alt?: string;\n  /** 확대 시 보여줄 큰 이미지 URL (기본: src) */\n  previewSrc?: string;\n  /** 클릭 확대 사용 (기본 true) */\n  preview?: boolean;\n  /**\n   * 마우스 오버 시 확대 아이콘 오버레이 표시 (기본 true).\n   * 테이블 셀처럼 마우스가 자주 지나가는 좁은 영역에서는 false로 꺼서\n   * 스쳐 지나갈 때마다 오버레이가 반응하는 게 거슬리지 않게 할 수 있다.\n   * (클릭 확대 자체는 preview 로 계속 켜져 있다 — 이 prop 은 hover 표시만 끈다)\n   */\n  hoverOverlay?: boolean;\n  /** 이미지가 없을 때 문구 (기본 \"이미지 없음\") */\n  noImageText?: string;\n  /** 로드 실패 시 문구 (기본 \"이미지를 불러올 수 없습니다\") */\n  errorText?: string;\n}\n\nexport function AdminImage({\n  src,\n  alt = \"\",\n  previewSrc,\n  preview = true,\n  hoverOverlay = true,\n  noImageText = \"이미지 없음\",\n  errorText = \"이미지를 불러올 수 없습니다\",\n  className,\n  ...props\n}: AdminImageProps) {\n  const [open, setOpen] = useState(false);\n  // 에러가 난 src 를 기억 → src 가 바뀌면 자동으로 에러 상태가 풀린다(effect 불필요).\n  const [errorSrc, setErrorSrc] = useState<string | null>(null);\n  const errored = !!src && errorSrc === src;\n\n  // 이미지 없음 / 로드 실패 → placeholder (확대 비활성)\n  if (!src || errored) {\n    const msg = !src ? noImageText : errorText;\n    return (\n      <div\n        title={msg}\n        aria-label={msg}\n        className={cn(\n          \"flex flex-col items-center justify-center gap-0.5 overflow-hidden bg-muted text-muted-foreground\",\n          className\n        )}\n      >\n        <ImageOff className=\"size-4 shrink-0\" />\n        <span className=\"max-w-full truncate px-1 text-center text-[10px] leading-tight\">\n          {msg}\n        </span>\n      </div>\n    );\n  }\n\n  if (!preview) {\n    return (\n      // eslint-disable-next-line @next/next/no-img-element\n      <img\n        src={src}\n        alt={alt}\n        onError={() => setErrorSrc(src)}\n        className={className}\n        {...props}\n      />\n    );\n  }\n\n  return (\n    <>\n      <button\n        type=\"button\"\n        onClick={() => setOpen(true)}\n        className=\"group relative inline-flex cursor-zoom-in overflow-hidden rounded-md outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n        aria-label=\"이미지 확대\"\n      >\n        {/* eslint-disable-next-line @next/next/no-img-element */}\n        <img\n          src={src}\n          alt={alt}\n          onError={() => setErrorSrc(src)}\n          className={cn(\"object-cover\", className)}\n          {...props}\n        />\n        {hoverOverlay && (\n          <span className=\"absolute inset-0 hidden items-center justify-center bg-black/30 text-white group-hover:flex\">\n            <ZoomIn className=\"size-5\" />\n          </span>\n        )}\n      </button>\n\n      <DialogPrimitive.Root open={open} onOpenChange={setOpen}>\n        <DialogPrimitive.Portal>\n          <DialogPrimitive.Overlay className=\"fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\" />\n          <DialogPrimitive.Content\n            onClick={() => setOpen(false)}\n            className=\"fixed inset-0 z-50 flex items-center justify-center p-6 outline-none\"\n          >\n            <DialogPrimitive.Title className=\"sr-only\">\n              이미지 확대 보기\n            </DialogPrimitive.Title>\n            {/* eslint-disable-next-line @next/next/no-img-element */}\n            <img\n              src={previewSrc ?? src}\n              alt={alt}\n              onClick={(e) => e.stopPropagation()}\n              className=\"max-h-[90vh] max-w-[90vw] object-contain data-[state=open]:animate-in data-[state=open]:zoom-in-95\"\n            />\n            <DialogPrimitive.Close className=\"absolute top-4 right-4 rounded-full bg-black/50 p-2 text-white outline-none transition-colors hover:bg-black/70 focus-visible:ring-2 focus-visible:ring-white\">\n              <X className=\"size-5\" />\n              <span className=\"sr-only\">닫기</span>\n            </DialogPrimitive.Close>\n          </DialogPrimitive.Content>\n        </DialogPrimitive.Portal>\n      </DialogPrimitive.Root>\n    </>\n  );\n}\n","/**\n * AdminDescriptions — 라벨/내용 목록 (테두리형, 상세보기용)\n *\n * Ant Design 의 Descriptions 와 유사. 상세 화면에서 \"항목명 + 값\"을 표 형태로 보여준다.\n * content 는 ReactNode 이므로 배지/버튼/링크 등 컴포넌트도 넣을 수 있다.\n *\n * 상호작용이 없어 서버 컴포넌트로도 사용 가능하다.\n *\n * @example\n * <AdminDescriptions\n *   title=\"회원 정보\"\n *   columns={2}\n *   items={[\n *     { label: \"이름\", content: \"홍길동\" },\n *     { label: \"상태\", content: <Badge color=\"green\" text=\"활성\" /> },\n *     { label: \"메모\", content: \"...\", span: 2 }, // 한 줄 전체 차지\n *     // content 엘리먼트에 required prop 이 있으면(AdminFormField 등) 자동으로 * 가 붙는다.\n *     { label: \"이메일\", content: <AdminFormField {...form.field(\"email\", { required: true })} /> },\n *     // required 를 직접 지정하면 그게 우선한다 (content 에 required prop 이 없는 경우 등).\n *     { label: \"상태\", content: <select>...</select>, required: true },\n *   ]}\n * />\n *\n * @example\n * // 상세 조회 로딩 중 — 레이아웃(높이) 유지한 채 흐리게 + 스피너\n * <AdminDescriptions title=\"회원 정보\" items={items} loading={fetch.isLoading} />\n *\n * @example\n * // items 대신 임의의 콘텐츠(AdminTable 등)를 title + 카드 테두리 안에 넣고 싶을 때\n * <AdminDescriptions title=\"상품 정보\">\n *   <AdminTable columns={columns} data={rows} />\n * </AdminDescriptions>\n */\nimport { Fragment, isValidElement, type ReactNode } from \"react\";\nimport { Loader2 } from \"lucide-react\";\n\nimport { cn } from \"../../lib/utils\";\n\n/** content 로 넘긴 엘리먼트 자체가 required=true 를 갖고 있는지 (AdminFormField/AdminInput/AdminTextarea 등) */\nfunction isRequiredContent(content: ReactNode): boolean {\n  return (\n    isValidElement(content) &&\n    (content.props as { required?: boolean }).required === true\n  );\n}\n\nexport interface AdminDescriptionItem {\n  label: ReactNode;\n  content: ReactNode;\n  /** 차지할 열 수 (columns 까지). 기본 1 */\n  span?: number;\n  /**\n   * 라벨 옆에 빨간 * 표시 (입력 필드가 필수일 때).\n   * 지정하지 않으면 content 엘리먼트의 required prop(true)을 자동으로 반영한다.\n   */\n  required?: boolean;\n}\n\nexport interface AdminDescriptionsProps {\n  /** 라벨/내용 목록. children을 대신 쓸 경우 생략 가능 */\n  items?: AdminDescriptionItem[];\n  /** 섹션 제목 (선택) */\n  title?: ReactNode;\n  /**\n   * items 대신 임의의 콘텐츠(AdminTable 등)를 넣고 싶을 때 사용.\n   * 지정하면 items는 무시되고, title + 카드 테두리 안에 children을 그대로 보여준다.\n   */\n  children?: ReactNode;\n  /**\n   * 배치 방식 (기본 \"row\")\n   * - \"row\": 라벨(왼쪽) + 내용(오른쪽), 테두리 표 형태\n   * - \"stacked\": 작은 회색 라벨(위) + 내용(아래) 형태\n   */\n  layout?: \"row\" | \"stacked\";\n  /** 한 줄에 표시할 항목 수 (기본 1) */\n  columns?: number;\n  /** 테두리형 (row 레이아웃에서만, 기본 true). false 면 구분선만 */\n  bordered?: boolean;\n  /** 라벨 셀 최소 너비 (row 레이아웃, 기본 7rem) */\n  labelWidth?: string;\n  className?: string;\n  /**\n   * true 면 내용을 흐리게(opacity) 하고 가운데에 스피너를 겹쳐 보여준다.\n   * 레이아웃 높이가 유지되므로 상세 조회(fetch.isLoading) 중 화면이 흔들리지 않는다.\n   */\n  loading?: boolean;\n}\n\nexport function AdminDescriptions({\n  items = [],\n  title,\n  layout = \"row\",\n  columns = 1,\n  bordered = true,\n  labelWidth = \"7rem\",\n  className,\n  loading = false,\n  children,\n}: AdminDescriptionsProps) {\n  const titleEl = title ? (\n    <div className=\"mb-4 text-sm font-semibold text-foreground\">{title}</div>\n  ) : null;\n\n  let body: ReactNode;\n\n  // children: items 표 렌더링 대신, title + 카드 테두리 안에 그대로 보여준다.\n  if (children) {\n    body = (\n      <div\n        className={cn(\n          bordered && \"rounded-lg border bg-card px-6 py-5\",\n          className\n        )}\n      >\n        {titleEl}\n        {children}\n      </div>\n    );\n  } else if (layout === \"stacked\") {\n    body = (\n      <div\n        className={cn(\n          bordered && \"rounded-lg border bg-card px-6 py-5\",\n          className\n        )}\n      >\n        {titleEl}\n        <div\n          className=\"grid gap-x-6 gap-y-4\"\n          style={{ gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))` }}\n        >\n          {items.map((item, i) => {\n            const span = Math.min(item.span ?? 1, columns);\n            return (\n              <div\n                key={i}\n                style={span > 1 ? { gridColumn: `span ${span}` } : undefined}\n              >\n                <div className=\"text-xs text-muted-foreground\">\n                  {item.label}\n                  {(item.required ?? isRequiredContent(item.content)) && (\n                    <span className=\"ml-0.5 text-destructive\">*</span>\n                  )}\n                </div>\n                <div className=\"mt-1 text-sm text-foreground\">\n                  {item.content}\n                </div>\n              </div>\n            );\n          })}\n        </div>\n      </div>\n    );\n  } else {\n    // row: 라벨(왼쪽) + 내용(오른쪽) 표. 항목을 columns 기준으로 행에 채운다.\n    // CSS 그리드 auto-flow 대신 직접 행을 계산해야 span/순서가 정확하다. (테이블)\n    type Packed = AdminDescriptionItem & { span: number };\n    const rows: Packed[][] = [];\n    let cur: Packed[] = [];\n    let used = 0;\n    for (const item of items) {\n      const span = Math.min(Math.max(item.span ?? 1, 1), columns);\n      // 남은 칸보다 크면 현재 행을 마무리(마지막 항목이 남은 칸 채움)하고 새 행 시작\n      if (used + span > columns) {\n        if (cur.length) cur[cur.length - 1].span += columns - used;\n        rows.push(cur);\n        cur = [];\n        used = 0;\n      }\n      cur.push({ ...item, span });\n      used += span;\n      if (used === columns) {\n        rows.push(cur);\n        cur = [];\n        used = 0;\n      }\n    }\n    if (cur.length) {\n      cur[cur.length - 1].span += columns - used; // 마지막 행 남은 칸 채움\n      rows.push(cur);\n    }\n\n    const cellBorder = bordered ? \"border border-border\" : \"\";\n\n    body = (\n      <div className={className}>\n        {titleEl}\n        <div\n          className={cn(\n            \"overflow-hidden rounded-lg text-sm\",\n            !bordered && \"border-t\"\n          )}\n        >\n          <table className=\"w-full border-collapse\">\n            <tbody>\n              {rows.map((row, ri) => (\n                <tr key={ri}>\n                  {row.map((item, ci) => (\n                    <Fragment key={ci}>\n                      <th\n                        scope=\"row\"\n                        style={{ width: labelWidth }}\n                        className={cn(\n                          \"px-3 py-2 text-left align-top font-medium text-muted-foreground\",\n                          bordered ? \"bg-muted\" : \"border-b\",\n                          cellBorder\n                        )}\n                      >\n                        {item.label}\n                        {(item.required ?? isRequiredContent(item.content)) && (\n                          <span className=\"ml-0.5 text-destructive\">*</span>\n                        )}\n                      </th>\n                      <td\n                        colSpan={item.span * 2 - 1}\n                        className={cn(\n                          \"px-3 py-2 align-top text-foreground\",\n                          bordered ? \"bg-card\" : \"border-b\",\n                          cellBorder\n                        )}\n                      >\n                        {item.content}\n                      </td>\n                    </Fragment>\n                  ))}\n                </tr>\n              ))}\n            </tbody>\n          </table>\n        </div>\n      </div>\n    );\n  }\n\n  if (!loading) return body;\n\n  return (\n    <div className=\"relative\">\n      <div className=\"pointer-events-none opacity-50\">{body}</div>\n      <div className=\"absolute inset-0 flex items-center justify-center\">\n        <Loader2 className=\"size-5 animate-spin text-muted-foreground\" />\n      </div>\n    </div>\n  );\n}\n","\"use client\";\n\n/**\n * Badge — 상태 배지 (우선순위 10)\n *\n * 표의 상태 컬럼, 라벨 등에 쓰는 알약형 배지.\n * - text: 표시할 내용 (children 으로 넣어도 된다)\n * - color: 색상. 프리셋(\"gray\"|\"primary\"|\"green\"|\"red\"|\"amber\"|\"yellow\"|\"blue\") 또는\n *          임의의 CSS 색상 문자열(\"#16a34a\", \"oklch(...)\" 등)을 넣을 수 있다.\n *          프리셋이 아닌 색은 글자색을 검정과 섞어 밝은 색(gold 등)도 대비가 보장된다.\n * - size: 크기 (\"sm\"|\"md\"|\"lg\")\n *\n * 프리셋이 아닌 색을 주면 해당 색을 글자색으로, 옅은 톤을 배경으로 자동 계산한다.\n *\n * @example\n * <Badge text=\"활성\" color=\"green\" />\n * <Badge text=\"정지\" color=\"red\" size=\"sm\" />\n * <Badge text=\"VIP\" color=\"#7c3aed\" />   // 커스텀 색\n */\nimport { type CSSProperties, type ComponentProps, type ReactNode } from \"react\";\n\nimport { cn } from \"../../lib/utils\";\n\nexport type BadgeColor =\n  | \"gray\"\n  | \"primary\"\n  | \"green\"\n  | \"red\"\n  | \"amber\"\n  | \"yellow\"\n  | \"blue\";\n\nexport type BadgeSize = \"sm\" | \"md\" | \"lg\";\n\nexport interface BadgeProps extends ComponentProps<\"span\"> {\n  /** 표시할 텍스트 (children 으로 대체 가능) */\n  text?: ReactNode;\n  /** 프리셋 색상 또는 임의의 CSS 색상 문자열 */\n  color?: BadgeColor | (string & {});\n  /** 크기 (기본 md) */\n  size?: BadgeSize;\n}\n\n// 프리셋 색상 (라이트/다크 모두 대응하는 옅은 톤 + 진한 글자 + 테두리)\nconst PRESET: Record<BadgeColor, string> = {\n  gray: \"bg-muted text-muted-foreground border-border\",\n  primary: \"bg-primary/10 text-primary border-primary/20\",\n  green:\n    \"bg-emerald-100 text-emerald-700 border-emerald-200 dark:bg-emerald-500/15 dark:text-emerald-400 dark:border-emerald-500/30\",\n  red: \"bg-red-100 text-red-700 border-red-200 dark:bg-red-500/15 dark:text-red-400 dark:border-red-500/30\",\n  amber:\n    \"bg-amber-100 text-amber-700 border-amber-200 dark:bg-amber-500/15 dark:text-amber-400 dark:border-amber-500/30\",\n  yellow:\n    \"bg-yellow-100 text-yellow-800 border-yellow-200 dark:bg-yellow-500/15 dark:text-yellow-400 dark:border-yellow-500/30\",\n  blue: \"bg-blue-100 text-blue-700 border-blue-200 dark:bg-blue-500/15 dark:text-blue-400 dark:border-blue-500/30\",\n};\n\nconst SIZE: Record<BadgeSize, string> = {\n  sm: \"h-5 px-1.5 text-[11px]\",\n  md: \"h-6 px-2 text-xs\",\n  lg: \"h-7 px-2.5 text-sm\",\n};\n\nexport function Badge({\n  text,\n  children,\n  color = \"gray\",\n  size = \"md\",\n  className,\n  style,\n  ...props\n}: BadgeProps) {\n  const presetClass = PRESET[color as BadgeColor];\n  const isPreset = Boolean(presetClass);\n\n  // 커스텀 색상: 글자색은 검정과 섞어 밝은 색(yellow, gold 등)도 대비가 보장되게 하고,\n  // 배경은 12%·테두리는 35% 톤으로 자동 계산한다.\n  const customStyle: CSSProperties | undefined = isPreset\n    ? undefined\n    : {\n        color: `color-mix(in oklch, ${color} 65%, black)`,\n        backgroundColor: `color-mix(in srgb, ${color} 12%, transparent)`,\n        borderColor: `color-mix(in srgb, ${color} 35%, transparent)`,\n      };\n\n  return (\n    <span\n      data-slot=\"badge\"\n      className={cn(\n        \"inline-flex items-center justify-center gap-1 rounded-full border font-medium whitespace-nowrap\",\n        SIZE[size],\n        isPreset && presetClass,\n        className\n      )}\n      style={{ ...customStyle, ...style }}\n      {...props}\n    >\n      {text ?? children}\n    </span>\n  );\n}\n","/**\n * useDirtyCheck — API에서 받은 원본 데이터와 현재 폼 값을 비교해 변경 여부를 감지\n *\n * 값 비교는 타입에 관대하다 — useAdminForm 은 폼 값을 항상 string 으로 다루기 때문에\n * (select 의 number 필드, JSON 객체 필드 등) 서버 원본과 타입이 달라도 값만 같으면\n * 같은 것으로 취급한다.\n * - 원시값: number 3 ↔ string \"3\" 처럼 타입만 다르면 문자열로 변환해 비교한다.\n * - 객체/배열: 한쪽이 JSON.stringify 된 문자열이어도(예: address_json) 파싱해서\n *   구조적으로(키 순서 무관) 비교한다.\n *\n * @example\n * // number 필드를 select 로 다뤄서 폼 값은 string 이어도 정상 비교된다\n * // original.partner_key: number(3), form.values.partner_key: string(\"3\") → 같은 값으로 판정\n * const { isDirty } = useDirtyCheck(original, form.values);\n *\n * @example\n * // 기본 사용 — 수정 폼에서 변경 여부 감지\n * // original 은 API 원본(더 많은 필드를 가진 타입)이어도 된다 — form.values 에 있는 키만 비교한다.\n * const { data: original } = useApiQuery({ queryKey: [...], url: \"...\" });\n * const form = useAdminForm({ name: \"\", email: \"\" });\n *\n * const { isDirty, dirtyFields, diff } = useDirtyCheck(original, form.values);\n *\n * // isDirty    → true/false (하나라도 바뀌면 true)\n * // dirtyFields → { name: true, email: false }\n * // diff       → { name: \"새이름\" }  (바뀐 필드만 — PATCH 요청에 사용)\n *\n * @example\n * // PATCH — 변경된 필드만 전송\n * const handleUpdate = () => {\n *   if (!isDirty) return;\n *   updateMutation.mutate({ url: `/users/${id}`, method: \"patch\", data: diff });\n * };\n *\n * @example\n * // 저장하지 않은 변경사항 경고\n * <Button disabled={!isDirty}>저장</Button>\n * {isDirty && <p className=\"text-amber-500\">저장되지 않은 변경사항이 있습니다.</p>}\n *\n * @example\n * // normalizeEmpty: true — null / undefined / \"\" 을 동일하게 처리\n * // API가 null을 반환하고 폼은 \"\"로 초기화할 때 유용\n * const { isDirty } = useDirtyCheck(original, form.values, { normalizeEmpty: true });\n */\n\n\"use client\";\n\nimport { useMemo } from \"react\";\n\n// ─── 내부 유틸 ────────────────────────────────────────────────────────────────\n\ntype AnyObj = Record<string, any>;\n\nfunction normalize(v: unknown, empty: boolean): unknown {\n    if (!empty) return v;\n    return v === null || v === undefined || v === \"\" ? null : v;\n}\n\n/**\n * 문자열이 JSON 객체/배열처럼 보이면(맨 앞이 \"{\" 또는 \"[\") 파싱해서 돌려준다.\n * 파싱 실패하거나 객체/배열 모양이 아니면 원래 값을 그대로 돌려준다 — 일반 텍스트를\n * 잘못 건드리지 않는다 (예: 메모에 \"{이름}\" 같은 템플릿 문구가 있어도 안전).\n */\nfunction tryParseJSON(v: unknown): unknown {\n    if (typeof v !== \"string\") return v;\n    const trimmed = v.trim();\n    if (trimmed[0] !== \"{\" && trimmed[0] !== \"[\") return v;\n    try {\n        return JSON.parse(trimmed);\n    } catch {\n        return v;\n    }\n}\n\nfunction deepEqual(a: unknown, b: unknown, emptyAsEqual: boolean): boolean {\n    const na = normalize(a, emptyAsEqual);\n    const nb = normalize(b, emptyAsEqual);\n\n    if (na === nb) return true;\n    if (na === null || nb === null) return false;\n\n    // select 타입 필드처럼 폼 값은 항상 string 인데, 서버 원본은 number/object 등 원래\n    // 타입 그대로인 경우(예: partner_key, address_json)가 흔하다. 문자열 쪽이 JSON\n    // 객체/배열처럼 보이면 파싱해서(예: address_json 문자열 ↔ 원본 object) 구조적으로\n    // 비교하고, 그래도 하나 이상이 원시값이면 타입 강제 없이 문자열로 변환해 비교한다\n    // (number 3 ↔ string \"3\" 을 같은 값으로 취급) — 타입만 다르고 값은 같은데 \"변경됨\"\n    // 으로 오판하는 걸 막는다.\n    const pa = tryParseJSON(na);\n    const pb = tryParseJSON(nb);\n    if (pa === pb) return true;\n\n    if (typeof pa !== \"object\" && typeof pb !== \"object\") {\n        return String(pa) === String(pb);\n    }\n    if (typeof pa !== \"object\" || typeof pb !== \"object\") return false;\n\n    if (Array.isArray(pa) !== Array.isArray(pb)) return false;\n\n    if (Array.isArray(pa) && Array.isArray(pb)) {\n        if (pa.length !== pb.length) return false;\n        return pa.every((v, i) => deepEqual(v, pb[i], emptyAsEqual));\n    }\n\n    const aKeys = Object.keys(pa as AnyObj);\n    const bKeys = Object.keys(pb as AnyObj);\n    const allKeys = new Set([...aKeys, ...bKeys]);\n\n    for (const k of allKeys) {\n        if (!deepEqual((pa as AnyObj)[k], (pb as AnyObj)[k], emptyAsEqual)) return false;\n    }\n    return true;\n}\n\n// ─── 순수 함수 (React 없이 사용 가능) ────────────────────────────────────────\n\nexport interface DirtyCheckOptions {\n    /**\n     * null / undefined / \"\"를 모두 동일한 \"빈 값\"으로 처리한다.\n     * API가 null을 반환하고 폼은 \"\"로 초기화하는 경우에 유용.\n     * 기본값: false\n     */\n    normalizeEmpty?: boolean;\n}\n\nexport interface DirtyCheckResult<T extends AnyObj> {\n    /** 하나라도 변경된 필드가 있으면 true */\n    isDirty: boolean;\n    /** 필드별 변경 여부 — UI에서 하이라이트 표시 등에 사용 */\n    dirtyFields: Partial<Record<keyof T, boolean>>;\n    /** 변경된 필드만 담은 객체 — PATCH 요청에 사용 */\n    diff: Partial<T>;\n}\n\n/**\n * 순수 함수 버전 — React 없이 서버 또는 이벤트 핸들러에서 사용 가능\n *\n * original 은 current 보다 필드가 많아도 된다 (예: API 원본 전체 타입 vs 폼에서 쓰는 일부 필드만 Pick 한 타입).\n * current 에 있는 키만 기준으로 비교하므로, 폼 모양에 맞춰 original 을 미리 추려낼 필요가 없다.\n */\nexport function getDirtyCheck<T extends AnyObj>(\n    original: Partial<Record<keyof T, unknown>> | null | undefined,\n    current: T,\n    options: DirtyCheckOptions = {}\n): DirtyCheckResult<T> {\n    const emptyAsEqual = options.normalizeEmpty ?? false;\n\n    if (!original) {\n        return { isDirty: false, dirtyFields: {}, diff: {} };\n    }\n\n    const dirtyFields = {} as Partial<Record<keyof T, boolean>>;\n    const diff = {} as Partial<T>;\n\n    const keys = Object.keys(current) as (keyof T & string)[];\n\n    for (const key of keys) {\n        if (!deepEqual(original[key], current[key], emptyAsEqual)) {\n            dirtyFields[key] = true;\n            diff[key] = current[key];\n        }\n    }\n\n    return {\n        isDirty: Object.keys(dirtyFields).length > 0,\n        dirtyFields,\n        diff,\n    };\n}\n\n// ─── React Hook ───────────────────────────────────────────────────────────────\n\n/**\n * useDirtyCheck — 원본과 현재 값을 비교해 변경 여부를 반환하는 훅\n * original이 null/undefined이면 항상 isDirty=false (데이터 로딩 중 처리)\n */\nexport function useDirtyCheck<T extends AnyObj>(\n    original: Partial<Record<keyof T, unknown>> | null | undefined,\n    current: T,\n    options: DirtyCheckOptions = {}\n): DirtyCheckResult<T> {\n    return useMemo(\n        () => getDirtyCheck(original, current, options),\n        // options 객체는 렌더마다 새로 생성되므로 값만 의존성으로 사용\n        // eslint-disable-next-line react-hooks/exhaustive-deps\n        [original, current, options.normalizeEmpty]\n    );\n}\n","\"use client\";\n\n/**\n * usePageSearchState — 목록 페이지의 필터/정렬/페이지네이션 상태를 URL(주소창)에 동기화한다.\n * zod에 의존하지 않는다 — _filters(기본값 객체)의 각 값 타입(배열이면 배열, 아니면 단일값)을\n * 보고 화이트리스트와 캐스팅을 판단한다.\n *\n * 브라우저 뒤로가기/새로고침/공유 링크로 들어와도 같은 필터 상태를 그대로 복원한다.\n * (참고: 이 URL 포맷은 options[key]가 아니라 key=value 평평한 형식이다. 실제 API 요청은\n * axios가 filters 객체를 별도로 직렬화해서 보내므로 이 주소창 URL과 포맷이 달라도 무방하다.)\n *\n * @example\n * const initFilters: BaseFilter = {\n *   keyword: \"\", keywordType: \"\", startDate: null, endDate: null, dateType: \"\",\n *   options: { status: [] as string[] },\n * };\n *\n * const {\n *   pagination, sort, filters,\n *   setPaginationAndSync, setFiltersAndSync, setSortAndSync,\n *   resetFilters, // 필터+페이지+정렬을 한 번에 초기 상태로 되돌리고 URL도 한 번만 갱신한다\n * } = usePageSearchState({ defaultPageSize: 20, _filters: initFilters });\n * // 정렬까지 초기값으로 되돌리고 싶으면 defaultSort도 지정\n * // usePageSearchState({ defaultPageSize: 20, _filters: initFilters, defaultSort: { sortKey: \"createdAt\", sortType: \"DESC\" } });\n */\nimport { usePathname, useRouter, useSearchParams } from \"next/navigation\";\nimport { useMemo, useState } from \"react\";\n\nexport interface PaginationType {\n    page: number;\n    pageSize: number;\n}\n\nexport interface SortType {\n    sortKey?: string;\n    sortType?: \"ASC\" | \"DESC\";\n}\n\nexport interface BaseFilter {\n    keyword: string;\n    keywordType: string;\n    options: Record<string, any>;\n    startDate: string | null;\n    endDate: string | null;\n    dateType: string;\n}\n\nexport interface UsePageSearchStateConfig {\n    defaultPageSize?: number;\n    _filters: BaseFilter;\n    /** resetFilters() 호출 시 되돌아갈 정렬 상태. 기본은 정렬 없음({}) */\n    defaultSort?: SortType;\n    params?: Record<string, any>;\n}\n\nexport const usePageSearchState = (config: UsePageSearchStateConfig) => {\n    const { defaultPageSize = 20, _filters, defaultSort = {}, params = {} } = config;\n    const router = useRouter();\n    const pathname = usePathname();\n    const searchParams = useSearchParams();\n\n    const { initPagination, initSort, initFilters } = useMemo(() => {\n        const page = Number(searchParams.get(\"page\") ?? \"1\");\n        const pageSize = Number(searchParams.get(\"pageSize\") ?? defaultPageSize.toString());\n        const sortKey = searchParams.get(\"sortKey\") ?? undefined;\n        const sortType = (searchParams.get(\"sortType\") as \"ASC\" | \"DESC\" | null) ?? undefined;\n        const keyword = searchParams.get(\"keyword\") ?? _filters.keyword;\n        const keywordType = searchParams.get(\"keywordType\") ?? _filters.keywordType;\n        const startDate = searchParams.get(\"startDate\") ?? _filters.startDate;\n        const endDate = searchParams.get(\"endDate\") ?? _filters.endDate;\n        const dateType = searchParams.get(\"dateType\") ?? _filters.dateType;\n        const optionsFromQuery = { ..._filters.options };\n        Object.keys(_filters.options || {}).forEach((key) => {\n            const defaultVal = _filters.options[key];\n            if (Array.isArray(defaultVal)) {\n                const all = searchParams.getAll(key);\n                if (all.length > 0) {\n                    optionsFromQuery[key] = all;\n                }\n            } else {\n                const v = searchParams.get(key);\n                if (v !== null) {\n                    optionsFromQuery[key] = v;\n                }\n            }\n        });\n        return {\n            initPagination: { page, pageSize } as PaginationType,\n            initSort: { sortKey, sortType } as SortType,\n            initFilters: {\n                keyword,\n                keywordType,\n                startDate,\n                endDate,\n                dateType,\n                options: optionsFromQuery,\n            } as BaseFilter,\n        };\n        // eslint-disable-next-line react-hooks/exhaustive-deps\n    }, [searchParams, params, _filters, defaultPageSize]);\n\n    const [pagination, setPagination] = useState<PaginationType>(initPagination);\n    const [sort, setSort] = useState<SortType>(initSort);\n    const [filters, setFilters] = useState<BaseFilter>(initFilters);\n\n    const buildSearchParams = (\n        nextPagination: PaginationType,\n        nextFilters: BaseFilter,\n        nextSort: SortType\n    ) => {\n        const sp = new URLSearchParams();\n        sp.set(\"page\", nextPagination.page.toString());\n        sp.set(\"pageSize\", nextPagination.pageSize.toString());\n\n        // filters\n        if (nextFilters.keyword) sp.set(\"keyword\", nextFilters.keyword);\n        if (nextFilters.keywordType) sp.set(\"keywordType\", nextFilters.keywordType);\n        if (nextFilters.dateType) sp.set(\"dateType\", nextFilters.dateType);\n        if (nextFilters.startDate) sp.set(\"startDate\", nextFilters.startDate);\n        if (nextFilters.endDate) sp.set(\"endDate\", nextFilters.endDate);\n        Object.entries(nextFilters.options || {}).forEach(([key, value]) => {\n            if (value === undefined || value === null || value === \"\") return;\n            if (Array.isArray(value)) {\n                value.forEach((v) => sp.append(key, String(v)));\n            } else {\n                sp.set(key, String(value));\n            }\n        });\n        // sort\n        if (nextSort.sortKey) sp.set(\"sortKey\", nextSort.sortKey);\n        if (nextSort.sortType) sp.set(\"sortType\", nextSort.sortType);\n        if (params) {\n            Object.entries(params).forEach(([key, value]) => {\n                if (value === undefined || value === null || value === \"\") return;\n                if (Array.isArray(value)) {\n                    value.forEach((v) => sp.append(key, String(v)));\n                } else {\n                    sp.set(key, String(value));\n                }\n            });\n        }\n        return sp;\n    };\n\n    const syncUrl = (\n        nextPagination: PaginationType,\n        nextFilters: BaseFilter,\n        nextSort: SortType\n    ) => {\n        const sp = buildSearchParams(nextPagination, nextFilters, nextSort);\n        const href = `${pathname}?${sp.toString()}`;\n        router.replace(href, { scroll: false });\n    };\n\n    const setPaginationAndSync = (\n        updater: PaginationType | ((prev: PaginationType) => PaginationType)\n    ) => {\n        const next =\n            typeof updater === \"function\"\n                ? (updater as (prev: PaginationType) => PaginationType)(pagination)\n                : updater;\n        setPagination(next);\n        syncUrl(next, filters, sort);\n    };\n\n    const setFiltersAndSync = (\n        updater: BaseFilter | ((prev: BaseFilter) => BaseFilter)\n    ) => {\n        const next =\n            typeof updater === \"function\"\n                ? (updater as (prev: BaseFilter) => BaseFilter)(filters)\n                : updater;\n        setFilters(next);\n        syncUrl(pagination, next, sort);\n    };\n\n    const setSortAndSync = (updater: SortType | ((prev: SortType) => SortType)) => {\n        const next =\n            typeof updater === \"function\"\n                ? (updater as (prev: SortType) => SortType)(sort)\n                : updater;\n        setSort(next);\n        syncUrl(pagination, filters, next);\n    };\n\n    // 필터 + 페이지 + 정렬을 한 번에 되돌리고, syncUrl은 딱 한 번만 호출한다.\n    // (resetFilters 따로 호출 + setSort/syncUrl 따로 또 호출하면 router.replace가 두 번 일어나서\n    //  API 요청도 두 번 나간다 — 그걸 방지하려고 여기서 한 번에 처리한다.)\n    const resetFilters = () => {\n        const reset: BaseFilter = { ..._filters, options: _filters.options };\n        const resetPagination = { page: 1, pageSize: pagination.pageSize };\n        setFilters(reset);\n        setPagination(resetPagination);\n        setSort(defaultSort);\n        syncUrl(resetPagination, reset, defaultSort);\n    };\n\n    return {\n        pagination,\n        sort,\n        filters,\n\n        // state만 바꾸고 싶을 때\n        setPagination,\n        setFilters,\n        setSort,\n\n        // state + URL 같이 바꾸기용\n        setPaginationAndSync,\n        setFiltersAndSync,\n        setSortAndSync,\n\n        resetFilters,\n        syncUrl,\n    };\n};\n"]}