@jbpark/live-editor 5.0.0 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/README.ko.md +34 -32
  2. package/README.md +34 -32
  3. package/dist/{boundary-6_nTsWxP.js → boundary-CySnDUs2.js} +5 -4
  4. package/dist/boundary-CySnDUs2.js.map +1 -0
  5. package/dist/{compile-DwOyWrmI.js → compile-my0AjsCw.js} +3 -3
  6. package/dist/{compile-DwOyWrmI.js.map → compile-my0AjsCw.js.map} +1 -1
  7. package/dist/{constants-D-XKuEY2.js → constants-st9gnJ5g.js} +1 -4
  8. package/dist/{constants-D-XKuEY2.js.map → constants-st9gnJ5g.js.map} +1 -1
  9. package/dist/{context-DDR1xVKo.js → context-Bjq0CvBE.js} +3 -3
  10. package/dist/{context-DDR1xVKo.js.map → context-Bjq0CvBE.js.map} +1 -1
  11. package/dist/{core-CKazr4tT.js → core-BNVuH8-l.js} +51 -14
  12. package/dist/core-BNVuH8-l.js.map +1 -0
  13. package/dist/{detect-typescript-CoAO-QUJ.js → detect-typescript-CMF0FVKD.js} +2 -2
  14. package/dist/{detect-typescript-CoAO-QUJ.js.map → detect-typescript-CMF0FVKD.js.map} +1 -1
  15. package/dist/dnd/index.d.ts +2 -1
  16. package/dist/dnd/index.js +2 -1
  17. package/dist/{dnd-BlC1gqUy.js → dnd-BvjEDo-x.js} +1208 -1457
  18. package/dist/dnd-BvjEDo-x.js.map +1 -0
  19. package/dist/{document-DcwIEHRV.js → document-uHqw0mvr.js} +7 -7
  20. package/dist/{document-DcwIEHRV.js.map → document-uHqw0mvr.js.map} +1 -1
  21. package/dist/edit-options-C_r9aCz4.d.ts +100 -0
  22. package/dist/editor/index.d.ts +1 -1
  23. package/dist/editor/index.js +2 -2
  24. package/dist/{editor-Bty5XzpV.js → editor-CvnzrM9J.js} +2 -2
  25. package/dist/{editor-Bty5XzpV.js.map → editor-CvnzrM9J.js.map} +1 -1
  26. package/dist/error/index.d.ts +1 -1
  27. package/dist/error/index.js +2 -2
  28. package/dist/{error-DyYx2NQ2.js → error-CFzvnLCf.js} +4 -4
  29. package/dist/error-CFzvnLCf.js.map +1 -0
  30. package/dist/{index-tAiuHZsC.d.ts → index-BZpZwrxT.d.ts} +2 -2
  31. package/dist/{index-13BDSrQc.d.ts → index-C93npmTU.d.ts} +4 -6
  32. package/dist/{index-Cl79M7ZJ.d.ts → index-CqsS207F.d.ts} +2 -10
  33. package/dist/{index-0VB5C3Jk.d.ts → index-DQcdHg_V.d.ts} +4 -100
  34. package/dist/{index-kKUjo9lr.d.ts → index-DfIvkht8.d.ts} +3 -3
  35. package/dist/index.d.ts +8 -7
  36. package/dist/index.js +6 -6
  37. package/dist/{messages-Yb3b7YJt.d.ts → messages-BpN3QIhj.d.ts} +4 -1
  38. package/dist/{messages-Bt5WXKTE.js → messages-DrINcRdG.js} +4 -1
  39. package/dist/messages-DrINcRdG.js.map +1 -0
  40. package/dist/preview/index.d.ts +2 -2
  41. package/dist/preview/index.js +2 -3
  42. package/dist/{preview-DC0pyOdu.js → preview-B05MkVIQ.js} +16 -13
  43. package/dist/preview-B05MkVIQ.js.map +1 -0
  44. package/dist/provider/index.d.ts +2 -2
  45. package/dist/provider/index.js +2 -2
  46. package/dist/{sections-4uirsXRU.js → sections-DhH_aVf5.js} +3 -3
  47. package/dist/{sections-4uirsXRU.js.map → sections-DhH_aVf5.js.map} +1 -1
  48. package/dist/style.css +801 -5372
  49. package/dist/ui-kit/index.d.ts +22 -0
  50. package/dist/ui-kit/index.js +1552 -0
  51. package/dist/ui-kit/index.js.map +1 -0
  52. package/dist/ui-kit/style.css +5039 -0
  53. package/dist/{update-DNInQSM7.js → update-BuYQJqjq.js} +3 -3
  54. package/dist/{update-DNInQSM7.js.map → update-BuYQJqjq.js.map} +1 -1
  55. package/dist/{use-dynamic-tailwind-CSYKXDmX.js → use-dynamic-tailwind-B3l1qZRW.js} +21 -18
  56. package/dist/use-dynamic-tailwind-B3l1qZRW.js.map +1 -0
  57. package/dist/use-field-state-iQGW0vc6.js +131 -0
  58. package/dist/use-field-state-iQGW0vc6.js.map +1 -0
  59. package/dist/utils/ast/index.js +2 -2
  60. package/dist/utils/index.js +2 -2
  61. package/package.json +13 -3
  62. package/dist/boundary-6_nTsWxP.js.map +0 -1
  63. package/dist/core-CKazr4tT.js.map +0 -1
  64. package/dist/dnd-BlC1gqUy.js.map +0 -1
  65. package/dist/error-DyYx2NQ2.js.map +0 -1
  66. package/dist/messages-Bt5WXKTE.js.map +0 -1
  67. package/dist/preview-DC0pyOdu.js.map +0 -1
  68. package/dist/use-dynamic-tailwind-CSYKXDmX.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preview-B05MkVIQ.js","names":["styles","LiveError"],"sources":["../src/components/preview/preview.module.css","../src/components/preview/client.tsx","../src/components/preview/preview.tsx"],"sourcesContent":["@layer components {\n .fill {\n position: relative;\n width: 100%;\n height: 100%;\n }\n\n .scroll {\n overflow-x: hidden;\n overflow-y: auto;\n }\n\n /* Hides the preview while the runtime error overlay covers it. */\n .hidden {\n display: none;\n }\n}\n","'use client';\n\nimport { useMemo } from 'react';\n\nimport { useLiveMessages } from '~/components/context/messages';\nimport { useError, usePreview } from '~/components/context/states';\nimport LiveError from '~/components/error';\nimport Frame, { type FrameProps } from '~/components/frame';\nimport { cn } from '~/utils/cn';\n\nimport styles from './preview.module.css';\n\nimport { NO_MODULES, NO_PROPS } from './defaults';\nimport { renderStableComponent } from './stable-component';\nimport type { Props } from './types';\nimport { useCompiledModule } from './use-compiled-module';\nimport { useDynamicTailwind } from './use-dynamic-tailwind';\n\nconst Client = ({\n code: _code,\n className,\n showError,\n props = NO_PROPS,\n modules = NO_MODULES,\n frame,\n dynamicTailwind = false,\n provider,\n}: Props) => {\n const { code } = usePreview();\n const { error, setError } = useError();\n const messages = useLiveMessages();\n const isError = !!showError && !!error;\n\n const classNames = cn(isError && styles.hidden, className);\n\n const effectiveCode = _code === undefined ? code : _code;\n\n const module = useCompiledModule(effectiveCode, modules);\n\n // Attached to the wrapper below; scans the rendered DOM so classes coming\n // from an imported component are picked up too. See the hook for details.\n const { ref: contentRef, css: dynamicCSS } = useDynamicTailwind(\n effectiveCode,\n dynamicTailwind,\n );\n\n const componentProps = useMemo(\n () => ({\n ...props,\n }),\n [props],\n );\n\n const renderProvider = (component: React.ReactNode) => {\n return provider ? provider(component) : component;\n };\n\n if (module && module.error) {\n return (\n <>\n <div className={cn(styles.fill, classNames)}>\n <LiveError message={module.error} title={messages.errors.compile} />\n </div>\n <LiveError.Runtime open={isError} />\n </>\n );\n }\n\n const Component = module?.exports?.default;\n\n if (!Component) {\n return null;\n }\n\n return (\n <>\n {frame ? (\n <div className={cn(styles.fill, classNames)}>\n <Frame {...(frame as FrameProps)}>\n {container => (\n <div ref={contentRef} style={{ display: 'contents' }}>\n <LiveError.Boundary\n resetKeys={[effectiveCode]}\n onError={(e: Error) => setError(e.message)}\n >\n {renderProvider(\n <LiveError.Guard onError={e => setError(e.message)}>\n {/* Keeps the DOM when an edit leaves the hooks alone. */}\n {renderStableComponent(Component, effectiveCode, {\n ...componentProps,\n container,\n })}\n {dynamicTailwind && dynamicCSS && (\n <style>{dynamicCSS}</style>\n )}\n </LiveError.Guard>,\n )}\n </LiveError.Boundary>\n </div>\n )}\n </Frame>\n </div>\n ) : (\n <div\n ref={contentRef}\n className={cn(styles.fill, styles.scroll, classNames)}\n style={{\n isolation: 'isolate',\n transform: 'translateZ(0)',\n containerType: 'inline-size',\n }}\n >\n <LiveError.Boundary\n resetKeys={[effectiveCode]}\n onError={e => setError(e.message)}\n >\n {renderProvider(\n <LiveError.Guard onError={e => setError(e.message)}>\n {renderStableComponent(\n Component,\n effectiveCode,\n componentProps,\n )}\n {dynamicTailwind && dynamicCSS && <style>{dynamicCSS}</style>}\n </LiveError.Guard>,\n )}\n </LiveError.Boundary>\n </div>\n )}\n <LiveError.Runtime open={isError} />\n </>\n );\n};\n\nexport default Client;\n","import Client from './client';\nimport { NO_MODULES, NO_PROPS } from './defaults';\nimport type { Props } from './types';\n\n// `Live.Preview`: a thin wrapper around `Client`, which compiles, handles\n// errors and wraps the frame. One render path for both `code` and the\n// provider's code (#187).\nconst Preview = ({\n code,\n props = NO_PROPS,\n modules = NO_MODULES,\n dynamicTailwind = false,\n provider,\n ...restProps\n}: Props) => {\n return (\n <Client\n code={code}\n props={props}\n modules={modules}\n dynamicTailwind={dynamicTailwind}\n provider={provider}\n {...restProps}\n />\n );\n};\n\nexport default Preview;\n"],"mappings":";;;;;;;;;;;;;;;ACkBA,MAAM,UAAU,EACd,MAAM,OACN,WACA,WACA,QAAQ,UACR,UAAU,YACV,OACA,kBAAkB,OAClB,eACW;CACX,MAAM,EAAE,SAAS,WAAW;CAC5B,MAAM,EAAE,OAAO,aAAa,SAAS;CACrC,MAAM,WAAW,gBAAgB;CACjC,MAAM,UAAU,CAAC,CAAC,aAAa,CAAC,CAAC;CAEjC,MAAM,aAAa,GAAG,WAAWA,uBAAO,QAAQ,SAAS;CAEzD,MAAM,gBAAgB,UAAU,KAAA,IAAY,OAAO;CAEnD,MAAM,SAAS,kBAAkB,eAAe,OAAO;CAIvD,MAAM,EAAE,KAAK,YAAY,KAAK,eAAe,mBAC3C,eACA,eACF;CAEA,MAAM,iBAAiB,eACd,EACL,GAAG,MACL,IACA,CAAC,KAAK,CACR;CAEA,MAAM,kBAAkB,cAA+B;EACrD,OAAO,WAAW,SAAS,SAAS,IAAI;CAC1C;CAEA,IAAI,UAAU,OAAO,OACnB,OACE,qBAAA,UAAA,EAAA,UAAA,CACE,oBAAC,OAAD;EAAK,WAAW,GAAGA,uBAAO,MAAM,UAAU;EACxC,UAAA,oBAACC,OAAD;GAAW,SAAS,OAAO;GAAO,OAAO,SAAS,OAAO;EAAU,CAAA;CAChE,CAAA,GACL,oBAACA,MAAU,SAAX,EAAmB,MAAM,QAAU,CAAA,CACnC,EAAA,CAAA;CAIN,MAAM,YAAY,QAAQ,SAAS;CAEnC,IAAI,CAAC,WACH,OAAO;CAGT,OACE,qBAAA,UAAA,EAAA,UAAA,CACG,QACC,oBAAC,OAAD;EAAK,WAAW,GAAGD,uBAAO,MAAM,UAAU;EACxC,UAAA,oBAAC,OAAD;GAAO,GAAK;GACT,WAAA,cACC,oBAAC,OAAD;IAAK,KAAK;IAAY,OAAO,EAAE,SAAS,WAAW;IACjD,UAAA,oBAACC,MAAU,UAAX;KACE,WAAW,CAAC,aAAa;KACzB,UAAU,MAAa,SAAS,EAAE,OAAO;KAExC,UAAA,eACC,qBAACA,MAAU,OAAX;MAAiB,UAAS,MAAK,SAAS,EAAE,OAAO;MAAjD,UAAA,CAEG,sBAAsB,WAAW,eAAe;OAC/C,GAAG;OACH;MACF,CAAC,GACA,mBAAmB,cAClB,oBAAC,SAAD,EAAA,UAAQ,WAAkB,CAAA,CAEb;KACnB,CAAA,CAAA;IACkB,CAAA;GACjB,CAAA;EAEF,CAAA;CACJ,CAAA,IAEL,oBAAC,OAAD;EACE,KAAK;EACL,WAAW,GAAGD,uBAAO,MAAMA,uBAAO,QAAQ,UAAU;EACpD,OAAO;GACL,WAAW;GACX,WAAW;GACX,eAAe;EACjB;EAEA,UAAA,oBAACC,MAAU,UAAX;GACE,WAAW,CAAC,aAAa;GACzB,UAAS,MAAK,SAAS,EAAE,OAAO;GAE/B,UAAA,eACC,qBAACA,MAAU,OAAX;IAAiB,UAAS,MAAK,SAAS,EAAE,OAAO;IAAjD,UAAA,CACG,sBACC,WACA,eACA,cACF,GACC,mBAAmB,cAAc,oBAAC,SAAD,EAAA,UAAQ,WAAkB,CAAA,CAC7C;GACnB,CAAA,CAAA;EACkB,CAAA;CACjB,CAAA,GAEP,oBAACA,MAAU,SAAX,EAAmB,MAAM,QAAU,CAAA,CACnC,EAAA,CAAA;AAEN;;;AC7HA,MAAM,WAAW,EACf,MACA,QAAQ,UACR,UAAU,YACV,kBAAkB,OAClB,UACA,GAAG,gBACQ;CACX,OACE,oBAAC,QAAD;EACQ;EACC;EACE;EACQ;EACP;EACV,GAAI;CACL,CAAA;AAEL"}
@@ -1,3 +1,3 @@
1
- import { i as useLiveMessages, n as LiveMessagesInput, r as defaultMessages, t as LiveMessages } from "../messages-Yb3b7YJt.js";
2
- import { n as Props, t as ContextProvider } from "../index-tAiuHZsC.js";
1
+ import { i as useLiveMessages, n as LiveMessagesInput, r as defaultMessages, t as LiveMessages } from "../messages-BpN3QIhj.js";
2
+ import { n as Props, t as ContextProvider } from "../index-BZpZwrxT.js";
3
3
  export { type LiveMessages, type LiveMessagesInput, type Props, ContextProvider as default, defaultMessages, useLiveMessages };
@@ -1,3 +1,3 @@
1
- import { i as useLiveMessages, n as defaultMessages } from "../messages-Bt5WXKTE.js";
2
- import { t as ContextProvider } from "../context-DDR1xVKo.js";
1
+ import { i as useLiveMessages, n as defaultMessages } from "../messages-DrINcRdG.js";
2
+ import { t as ContextProvider } from "../context-Bjq0CvBE.js";
3
3
  export { ContextProvider as default, defaultMessages, useLiveMessages };
@@ -1,5 +1,5 @@
1
- import { a as inspectDocument, i as getSections, o as parseDocument, r as generateSectionPreview, s as replaceDocumentSections } from "./document-DcwIEHRV.js";
2
- import { i as DEFAULT_CONTAINER_ID, l as documentTemplate } from "./constants-D-XKuEY2.js";
1
+ import { a as inspectDocument, i as getSections, o as parseDocument, r as generateSectionPreview, s as replaceDocumentSections } from "./document-uHqw0mvr.js";
2
+ import { i as DEFAULT_CONTAINER_ID, l as documentTemplate } from "./constants-st9gnJ5g.js";
3
3
  //#region src/utils/sections.ts
4
4
  const extractSections = (code, options) => {
5
5
  const doc = parseDocument(code, options);
@@ -23,4 +23,4 @@ const checkDocument = (code, options) => {
23
23
  //#endregion
24
24
  export { replaceSections as a, generateSection as i, createDocument as n, extractSections as r, checkDocument as t };
25
25
 
26
- //# sourceMappingURL=sections-4uirsXRU.js.map
26
+ //# sourceMappingURL=sections-DhH_aVf5.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sections-4uirsXRU.js","names":[],"sources":["../src/utils/sections.ts"],"sourcesContent":["import { DEFAULT_CONTAINER_ID, documentTemplate } from '~/constants';\nimport type { Section } from '~/types';\n\nimport {\n type DocumentOptions,\n type DocumentProblem,\n type SectionOptions,\n createSectionPreviewCache,\n generateSectionPreview,\n getSections,\n inspectDocument,\n parseDocument,\n replaceDocumentSections,\n} from './ast/document';\n\nexport const extractSections = (\n code: string,\n options?: SectionOptions,\n): Section[] => {\n const doc = parseDocument(code, options);\n\n return doc ? getSections(doc, options) : [];\n};\n\nexport const replaceSections = (\n code: string,\n sections: string[],\n options?: DocumentOptions,\n): string => {\n return replaceDocumentSections(code, sections, options);\n};\n\nexport const generateSection = (\n code: string,\n fullCode: string,\n options?: DocumentOptions,\n) => {\n return generateSectionPreview(fullCode, code, options);\n};\n\n// A new, empty document `Live.Dnd` can add sections to: an `App` component\n// rendering the container element and nothing else. Start a controlled\n// `Live.Dnd` from this rather than an empty string, which has no container,\n// so nothing dropped on the canvas would land anywhere (#449). Pass the same\n// `containerId` you give `Live.Dnd`.\nexport const createDocument = ({\n containerId = DEFAULT_CONTAINER_ID,\n}: DocumentOptions = {}): string => {\n // The id is written into a JSX attribute as-is, so anything that could end\n // the attribute or the tag is refused rather than producing broken source.\n if (!/^[^\\s\"'<>{}]+$/.test(containerId)) {\n throw new Error(\n `createDocument: containerId must be a plain element id, got ${JSON.stringify(containerId)}`,\n );\n }\n\n return documentTemplate(containerId);\n};\n\n// Whether `Live.Dnd` can edit a document: it parses, and it has the\n// container. A host can check one before saving or loading it, and gets the\n// same reasons `Live.Dnd` reports through `onEditError` (#522).\nexport type DocumentCheck = { ok: true } | ({ ok: false } & DocumentProblem);\n\nexport const checkDocument = (\n code: string,\n options?: DocumentOptions,\n): DocumentCheck => {\n const inspection = inspectDocument(code, options);\n\n if (inspection.ok) {\n return { ok: true };\n }\n\n // A copy: the inspection is cached and shared with `Live.Dnd`.\n return { ...inspection };\n};\n\n// Generates every section's preview from one parse and reuses an unchanged\n// preview between calls (#131). Keep one instance per editor, as `Live.Dnd`\n// does.\nexport { createSectionPreviewCache };\nexport type {\n DocumentOptions,\n DocumentProblem,\n SectionOptions,\n} from './ast/document';\n"],"mappings":";;;AAeA,MAAa,mBACX,MACA,YACc;CACd,MAAM,MAAM,cAAc,MAAM,OAAO;CAEvC,OAAO,MAAM,YAAY,KAAK,OAAO,IAAI,CAAC;AAC5C;AAEA,MAAa,mBACX,MACA,UACA,YACW;CACX,OAAO,wBAAwB,MAAM,UAAU,OAAO;AACxD;AAEA,MAAa,mBACX,MACA,UACA,YACG;CACH,OAAO,uBAAuB,UAAU,MAAM,OAAO;AACvD;AAOA,MAAa,kBAAkB,EAC7B,cAAc,yBACK,CAAC,MAAc;CAGlC,IAAI,CAAC,iBAAiB,KAAK,WAAW,GACpC,MAAM,IAAI,MACR,+DAA+D,KAAK,UAAU,WAAW,GAC3F;CAGF,OAAO,iBAAiB,WAAW;AACrC;AAOA,MAAa,iBACX,MACA,YACkB;CAClB,MAAM,aAAa,gBAAgB,MAAM,OAAO;CAEhD,IAAI,WAAW,IACb,OAAO,EAAE,IAAI,KAAK;CAIpB,OAAO,EAAE,GAAG,WAAW;AACzB"}
1
+ {"version":3,"file":"sections-DhH_aVf5.js","names":[],"sources":["../src/utils/sections.ts"],"sourcesContent":["import { DEFAULT_CONTAINER_ID, documentTemplate } from '~/constants';\nimport type { Section } from '~/types';\n\nimport {\n type DocumentOptions,\n type DocumentProblem,\n type SectionOptions,\n createSectionPreviewCache,\n generateSectionPreview,\n getSections,\n inspectDocument,\n parseDocument,\n replaceDocumentSections,\n} from './ast/document';\n\nexport const extractSections = (\n code: string,\n options?: SectionOptions,\n): Section[] => {\n const doc = parseDocument(code, options);\n\n return doc ? getSections(doc, options) : [];\n};\n\nexport const replaceSections = (\n code: string,\n sections: string[],\n options?: DocumentOptions,\n): string => {\n return replaceDocumentSections(code, sections, options);\n};\n\nexport const generateSection = (\n code: string,\n fullCode: string,\n options?: DocumentOptions,\n) => {\n return generateSectionPreview(fullCode, code, options);\n};\n\n// A new, empty document `Live.Dnd` can add sections to: an `App` component\n// rendering the container element and nothing else. Start a controlled\n// `Live.Dnd` from this rather than an empty string, which has no container,\n// so nothing dropped on the canvas would land anywhere (#449). Pass the same\n// `containerId` you give `Live.Dnd`.\nexport const createDocument = ({\n containerId = DEFAULT_CONTAINER_ID,\n}: DocumentOptions = {}): string => {\n // The id is written into a JSX attribute as-is, so anything that could end\n // the attribute or the tag is refused rather than producing broken source.\n if (!/^[^\\s\"'<>{}]+$/.test(containerId)) {\n throw new Error(\n `createDocument: containerId must be a plain element id, got ${JSON.stringify(containerId)}`,\n );\n }\n\n return documentTemplate(containerId);\n};\n\n// Whether `Live.Dnd` can edit a document: it parses, and it has the\n// container. A host can check one before saving or loading it, and gets the\n// same reasons `Live.Dnd` reports through `onEditError` (#522).\nexport type DocumentCheck = { ok: true } | ({ ok: false } & DocumentProblem);\n\nexport const checkDocument = (\n code: string,\n options?: DocumentOptions,\n): DocumentCheck => {\n const inspection = inspectDocument(code, options);\n\n if (inspection.ok) {\n return { ok: true };\n }\n\n // A copy: the inspection is cached and shared with `Live.Dnd`.\n return { ...inspection };\n};\n\n// Generates every section's preview from one parse and reuses an unchanged\n// preview between calls (#131). Keep one instance per editor, as `Live.Dnd`\n// does.\nexport { createSectionPreviewCache };\nexport type {\n DocumentOptions,\n DocumentProblem,\n SectionOptions,\n} from './ast/document';\n"],"mappings":";;;AAeA,MAAa,mBACX,MACA,YACc;CACd,MAAM,MAAM,cAAc,MAAM,OAAO;CAEvC,OAAO,MAAM,YAAY,KAAK,OAAO,IAAI,CAAC;AAC5C;AAEA,MAAa,mBACX,MACA,UACA,YACW;CACX,OAAO,wBAAwB,MAAM,UAAU,OAAO;AACxD;AAEA,MAAa,mBACX,MACA,UACA,YACG;CACH,OAAO,uBAAuB,UAAU,MAAM,OAAO;AACvD;AAOA,MAAa,kBAAkB,EAC7B,cAAc,yBACK,CAAC,MAAc;CAGlC,IAAI,CAAC,iBAAiB,KAAK,WAAW,GACpC,MAAM,IAAI,MACR,+DAA+D,KAAK,UAAU,WAAW,GAC3F;CAGF,OAAO,iBAAiB,WAAW;AACrC;AAOA,MAAa,iBACX,MACA,YACkB;CAClB,MAAM,aAAa,gBAAgB,MAAM,OAAO;CAEhD,IAAI,WAAW,IACb,OAAO,EAAE,IAAI,KAAK;CAIpB,OAAO,EAAE,GAAG,WAAW;AACzB"}