@nextelco/common-ui 2.1.103 → 2.1.105

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 (53) hide show
  1. package/dist/esm/assets/imagem-6ee08a37d9.png +0 -0
  2. package/dist/esm/assets/imagem-6fcae1b87b.png +0 -0
  3. package/dist/esm/index.js +142 -119
  4. package/dist/esm/index.js.map +1 -1
  5. package/dist/esm/legacy/components/layout/Header/Header.css +1 -1
  6. package/dist/esm/legacy/components/molecules/PhotoAvatar/PhotoAvatar.js +9 -4
  7. package/dist/esm/legacy/components/molecules/PhotoAvatar/PhotoAvatar.js.map +1 -1
  8. package/dist/esm/legacy/components/molecules/Sidebar/Sidebar.css +1 -1
  9. package/dist/esm/legacy/components/organisms/RoleGuard/RoleGuard.js +14 -3
  10. package/dist/esm/legacy/components/organisms/RoleGuard/RoleGuard.js.map +1 -1
  11. package/dist/esm/legacy/pages/Error/ErrorPage.css +1 -1
  12. package/dist/esm/legacy/pages/Loading/Loading.css +2 -2
  13. package/dist/esm/legacy/pages/NotFound/NotFound.css +1 -1
  14. package/dist/esm/v1/components/lists/ListFinder/ListFinder.js +214 -0
  15. package/dist/esm/v1/components/lists/ListFinder/ListFinder.js.map +1 -0
  16. package/dist/esm/v1/components/lists/ListFinder/labels.js +18 -0
  17. package/dist/esm/v1/components/lists/ListFinder/labels.js.map +1 -0
  18. package/dist/esm/v1/components/tables/PaginatedTable/PaginatedTable.js +50 -0
  19. package/dist/esm/v1/components/tables/PaginatedTable/PaginatedTable.js.map +1 -0
  20. package/dist/esm/v1/components/tables/Table/ColumnFilter.js +292 -0
  21. package/dist/esm/v1/components/tables/Table/ColumnFilter.js.map +1 -0
  22. package/dist/esm/v1/components/tables/Table/OverlayScrollbar.js +129 -0
  23. package/dist/esm/v1/components/tables/Table/OverlayScrollbar.js.map +1 -0
  24. package/dist/esm/v1/components/tables/Table/Table.js +1410 -0
  25. package/dist/esm/v1/components/tables/Table/Table.js.map +1 -0
  26. package/dist/esm/v1/components/tables/Table/labels.js +44 -0
  27. package/dist/esm/v1/components/tables/Table/labels.js.map +1 -0
  28. package/dist/esm/v1/foundations/icons/icons.js +45 -2
  29. package/dist/esm/v1/foundations/icons/icons.js.map +1 -1
  30. package/dist/esm/v1/primitives/forms/Checkbox/Checkbox.js +32 -0
  31. package/dist/esm/v1/primitives/forms/Checkbox/Checkbox.js.map +1 -0
  32. package/dist/esm/v1/primitives/lists/ListItem/ListCheckbox.js +28 -0
  33. package/dist/esm/v1/primitives/lists/ListItem/ListCheckbox.js.map +1 -0
  34. package/dist/esm/v1/primitives/lists/ListItem/ListItem.js +39 -0
  35. package/dist/esm/v1/primitives/lists/ListItem/ListItem.js.map +1 -0
  36. package/dist/style.components.css +1 -1
  37. package/dist/style.css +1 -1
  38. package/dist/style.layered.css +1 -1
  39. package/dist/theme.css +256 -0
  40. package/dist/types/legacy/components/molecules/PhotoAvatar/PhotoAvatar.d.ts +2 -0
  41. package/dist/types/v1/components/lists/ListFinder/ListFinder.d.ts +60 -0
  42. package/dist/types/v1/components/lists/ListFinder/labels.d.ts +24 -0
  43. package/dist/types/v1/components/tables/PaginatedTable/PaginatedTable.d.ts +41 -0
  44. package/dist/types/v1/components/tables/Table/ColumnFilter.d.ts +48 -0
  45. package/dist/types/v1/components/tables/Table/OverlayScrollbar.d.ts +34 -0
  46. package/dist/types/v1/components/tables/Table/Table.d.ts +250 -0
  47. package/dist/types/v1/components/tables/Table/labels.d.ts +54 -0
  48. package/dist/types/v1/foundations/icons/icons.d.ts +17 -0
  49. package/dist/types/v1/index.d.ts +15 -1
  50. package/dist/types/v1/primitives/forms/Checkbox/Checkbox.d.ts +18 -0
  51. package/dist/types/v1/primitives/lists/ListItem/ListCheckbox.d.ts +14 -0
  52. package/dist/types/v1/primitives/lists/ListItem/ListItem.d.ts +35 -0
  53. package/package.json +2 -2
@@ -34,26 +34,37 @@ function RoleGuard({
34
34
  if (!temSessao || aAutenticar || jaCorreu.current) return;
35
35
  jaCorreu.current = true;
36
36
  let cancelado = false;
37
+ let concluida = false;
37
38
  void (async () => {
38
39
  if (!refRoles.current.length) {
39
- if (!cancelado) setDecisao("permitido");
40
+ if (!cancelado) {
41
+ concluida = true;
42
+ setDecisao("permitido");
43
+ }
40
44
  return;
41
45
  }
42
46
  try {
43
47
  const temAlguma = (t) => lerRolesDoToken(t).some((r) => refRoles.current.includes(r));
44
48
  let ok = temAlguma(await refObterToken.current());
45
49
  if (!ok) ok = temAlguma(await refObterToken.current(true));
46
- if (!cancelado) setDecisao(ok ? "permitido" : "negado");
50
+ if (!cancelado) {
51
+ concluida = true;
52
+ setDecisao(ok ? "permitido" : "negado");
53
+ }
47
54
  } catch {
55
+ if (cancelado) return;
48
56
  if (refPrecisaInteracao.current) {
57
+ concluida = true;
49
58
  refPrecisaInteracao.current();
50
59
  return;
51
60
  }
52
- if (!cancelado) setDecisao("negado");
61
+ concluida = true;
62
+ setDecisao("negado");
53
63
  }
54
64
  })();
55
65
  return () => {
56
66
  cancelado = true;
67
+ if (!concluida) jaCorreu.current = false;
57
68
  };
58
69
  }, [temSessao, aAutenticar]);
59
70
  if (!temSessao) return /* @__PURE__ */ jsx(Fragment, { children: semSessao });
@@ -1 +1 @@
1
- {"version":3,"file":"RoleGuard.js","sources":["../../../../../../src/legacy/components/organisms/RoleGuard/RoleGuard.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState, type ReactNode } from 'react'\r\n\r\n/**\r\n * Restringe o acesso ao portal a um conjunto de app roles.\r\n *\r\n * Não conhece o MSAL da aplicação: recebe funções para obter o token. É\r\n * deliberado — quando o bundler duplica o `@azure/msal-react`, um `useMsal`\r\n * dentro da biblioteca lê um contexto diferente do da app, a conta vem a null e\r\n * o acesso é negado a quem tem a role certa. Passando o token por fora, isso\r\n * não pode acontecer.\r\n *\r\n * As roles vêm no ACCESS token da API, não no id token — é o erro mais comum\r\n * nesta integração, e a razão de `obterToken` dever pedir o scope da API.\r\n * @deprecated Legacy — não usar em código novo. Ver Storybook › Legacy.\r\n */\r\n\r\nexport interface RoleGuardProps {\r\n /** Roles com acesso. Lista vazia = qualquer autenticado entra. */\r\n rolesPermitidas: string[]\r\n /** Há sessão iniciada? Enquanto false, mostra-se `semSessao`. */\r\n temSessao: boolean\r\n /** Ainda a resolver a autenticação — evita decidir cedo de mais. */\r\n aAutenticar?: boolean\r\n /** Token de acesso da API. `forcarRenovacao` ignora a cache. */\r\n obterToken: (forcarRenovacao?: boolean) => Promise<string>\r\n /** Chamado quando falta consentimento e é preciso um redirect interactivo. */\r\n onPrecisaInteracao?: () => void\r\n\r\n semSessao: ReactNode\r\n aCarregar: ReactNode\r\n semPermissao: ReactNode\r\n children: ReactNode\r\n}\r\n\r\ntype Decisao = 'aResolver' | 'permitido' | 'negado'\r\n\r\n/**\r\n * Lê a claim `roles` de um JWT, sem validar a assinatura (quem valida é a API).\r\n * @deprecated Legacy — não usar em código novo. Ver Storybook › Legacy.\r\n */\r\nexport function lerRolesDoToken(accessToken: string): string[] {\r\n try {\r\n const corpo = accessToken.split('.')[1]\r\n if (!corpo) return []\r\n const json = atob(corpo.replace(/-/g, '+').replace(/_/g, '/'))\r\n const payload = JSON.parse(json) as { roles?: string[] }\r\n return payload.roles ?? []\r\n } catch {\r\n return []\r\n }\r\n}\r\n\r\n/** @deprecated Legacy — não usar em código novo. Ver Storybook › Legacy. */\r\nexport default function RoleGuard({\r\n rolesPermitidas,\r\n temSessao,\r\n aAutenticar = false,\r\n obterToken,\r\n onPrecisaInteracao,\r\n semSessao,\r\n aCarregar,\r\n semPermissao,\r\n children,\r\n}: RoleGuardProps) {\r\n const [decisao, setDecisao] = useState<Decisao>('aResolver')\r\n\r\n /**\r\n * Decidir uma só vez. Em `useState` isto era um bug: a marca entrava nas\r\n * dependências do efeito, o efeito voltava a correr, a limpeza cancelava a\r\n * tentativa em curso e a segunda passagem saía logo — a decisão nunca chegava\r\n * e o portal ficava eternamente em `aCarregar`. Só não dava quando o token\r\n * estava em cache (um F5), porque aí resolve antes da limpeza.\r\n */\r\n const jaCorreu = useRef(false)\r\n\r\n /**\r\n * As três funções/arrays abaixo chegam quase sempre inline de quem usa o\r\n * componente, ou seja com identidade nova a cada render. Em dependências,\r\n * faziam o efeito re-correr e cancelar o pedido em voo. Ficam em refs: o\r\n * efeito usa sempre a última versão sem reagir a ela.\r\n */\r\n const refRoles = useRef(rolesPermitidas)\r\n const refObterToken = useRef(obterToken)\r\n const refPrecisaInteracao = useRef(onPrecisaInteracao)\r\n refRoles.current = rolesPermitidas\r\n refObterToken.current = obterToken\r\n refPrecisaInteracao.current = onPrecisaInteracao\r\n\r\n useEffect(() => {\r\n if (!temSessao || aAutenticar || jaCorreu.current) return\r\n jaCorreu.current = true\r\n\r\n let cancelado = false\r\n void (async () => {\r\n if (!refRoles.current.length) {\r\n if (!cancelado) setDecisao('permitido')\r\n return\r\n }\r\n try {\r\n const temAlguma = (t: string): boolean =>\r\n lerRolesDoToken(t).some((r) => refRoles.current.includes(r))\r\n\r\n let ok = temAlguma(await refObterToken.current())\r\n\r\n // Sem correspondência, uma segunda tentativa sem cache: uma role\r\n // atribuída há pouco ainda não está no token guardado, e negar o acesso\r\n // a quem acabou de a receber é o pior desfecho possível.\r\n if (!ok) ok = temAlguma(await refObterToken.current(true))\r\n\r\n if (!cancelado) setDecisao(ok ? 'permitido' : 'negado')\r\n } catch {\r\n // Falta de consentimento resolve-se com um redirect, uma única vez.\r\n if (refPrecisaInteracao.current) {\r\n refPrecisaInteracao.current()\r\n return\r\n }\r\n if (!cancelado) setDecisao('negado')\r\n }\r\n })()\r\n\r\n return () => {\r\n cancelado = true\r\n }\r\n }, [temSessao, aAutenticar])\r\n\r\n if (!temSessao) return <>{semSessao}</>\r\n if (decisao === 'aResolver') return <>{aCarregar}</>\r\n if (decisao === 'negado') return <>{semPermissao}</>\r\n return <>{children}</>\r\n}\r\n"],"names":[],"mappings":";;AAwCO,SAAS,gBAAgB,aAA+B;AAC7D,MAAI;AACF,UAAM,QAAQ,YAAY,MAAM,GAAG,EAAE,CAAC;AACtC,QAAI,CAAC,MAAO,QAAO,CAAA;AACnB,UAAM,OAAO,KAAK,MAAM,QAAQ,MAAM,GAAG,EAAE,QAAQ,MAAM,GAAG,CAAC;AAC7D,UAAM,UAAU,KAAK,MAAM,IAAI;AAC/B,WAAO,QAAQ,SAAS,CAAA;AAAA,EAC1B,QAAQ;AACN,WAAO,CAAA;AAAA,EACT;AACF;AAGA,SAAwB,UAAU;AAAA,EAChC;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAmB;AACjB,QAAM,CAAC,SAAS,UAAU,IAAI,SAAkB,WAAW;AAS3D,QAAM,WAAW,OAAO,KAAK;AAQ7B,QAAM,WAAW,OAAO,eAAe;AACvC,QAAM,gBAAgB,OAAO,UAAU;AACvC,QAAM,sBAAsB,OAAO,kBAAkB;AACrD,WAAS,UAAU;AACnB,gBAAc,UAAU;AACxB,sBAAoB,UAAU;AAE9B,YAAU,MAAM;AACd,QAAI,CAAC,aAAa,eAAe,SAAS,QAAS;AACnD,aAAS,UAAU;AAEnB,QAAI,YAAY;AAChB,UAAM,YAAY;AAChB,UAAI,CAAC,SAAS,QAAQ,QAAQ;AAC5B,YAAI,CAAC,UAAW,YAAW,WAAW;AACtC;AAAA,MACF;AACA,UAAI;AACF,cAAM,YAAY,CAAC,MACjB,gBAAgB,CAAC,EAAE,KAAK,CAAC,MAAM,SAAS,QAAQ,SAAS,CAAC,CAAC;AAE7D,YAAI,KAAK,UAAU,MAAM,cAAc,SAAS;AAKhD,YAAI,CAAC,GAAI,MAAK,UAAU,MAAM,cAAc,QAAQ,IAAI,CAAC;AAEzD,YAAI,CAAC,UAAW,YAAW,KAAK,cAAc,QAAQ;AAAA,MACxD,QAAQ;AAEN,YAAI,oBAAoB,SAAS;AAC/B,8BAAoB,QAAA;AACpB;AAAA,QACF;AACA,YAAI,CAAC,UAAW,YAAW,QAAQ;AAAA,MACrC;AAAA,IACF,GAAA;AAEA,WAAO,MAAM;AACX,kBAAY;AAAA,IACd;AAAA,EACF,GAAG,CAAC,WAAW,WAAW,CAAC;AAE3B,MAAI,CAAC,UAAW,QAAO,oBAAA,UAAA,EAAG,UAAA,WAAU;AACpC,MAAI,YAAY,YAAa,QAAO,oBAAA,UAAA,EAAG,UAAA,WAAU;AACjD,MAAI,YAAY,SAAU,QAAO,oBAAA,UAAA,EAAG,UAAA,cAAa;AACjD,yCAAU,UAAS;AACrB;"}
1
+ {"version":3,"file":"RoleGuard.js","sources":["../../../../../../src/legacy/components/organisms/RoleGuard/RoleGuard.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState, type ReactNode } from 'react'\r\n\r\n/**\r\n * Restringe o acesso ao portal a um conjunto de app roles.\r\n *\r\n * Não conhece o MSAL da aplicação: recebe funções para obter o token. É\r\n * deliberado — quando o bundler duplica o `@azure/msal-react`, um `useMsal`\r\n * dentro da biblioteca lê um contexto diferente do da app, a conta vem a null e\r\n * o acesso é negado a quem tem a role certa. Passando o token por fora, isso\r\n * não pode acontecer.\r\n *\r\n * As roles vêm no ACCESS token da API, não no id token — é o erro mais comum\r\n * nesta integração, e a razão de `obterToken` dever pedir o scope da API.\r\n * @deprecated Legacy — não usar em código novo. Ver Storybook › Legacy.\r\n */\r\n\r\nexport interface RoleGuardProps {\r\n /** Roles com acesso. Lista vazia = qualquer autenticado entra. */\r\n rolesPermitidas: string[]\r\n /** Há sessão iniciada? Enquanto false, mostra-se `semSessao`. */\r\n temSessao: boolean\r\n /** Ainda a resolver a autenticação — evita decidir cedo de mais. */\r\n aAutenticar?: boolean\r\n /** Token de acesso da API. `forcarRenovacao` ignora a cache. */\r\n obterToken: (forcarRenovacao?: boolean) => Promise<string>\r\n /** Chamado quando falta consentimento e é preciso um redirect interactivo. */\r\n onPrecisaInteracao?: () => void\r\n\r\n semSessao: ReactNode\r\n aCarregar: ReactNode\r\n semPermissao: ReactNode\r\n children: ReactNode\r\n}\r\n\r\ntype Decisao = 'aResolver' | 'permitido' | 'negado'\r\n\r\n/**\r\n * Lê a claim `roles` de um JWT, sem validar a assinatura (quem valida é a API).\r\n * @deprecated Legacy — não usar em código novo. Ver Storybook › Legacy.\r\n */\r\nexport function lerRolesDoToken(accessToken: string): string[] {\r\n try {\r\n const corpo = accessToken.split('.')[1]\r\n if (!corpo) return []\r\n const json = atob(corpo.replace(/-/g, '+').replace(/_/g, '/'))\r\n const payload = JSON.parse(json) as { roles?: string[] }\r\n return payload.roles ?? []\r\n } catch {\r\n return []\r\n }\r\n}\r\n\r\n/** @deprecated Legacy — não usar em código novo. Ver Storybook › Legacy. */\r\nexport default function RoleGuard({\r\n rolesPermitidas,\r\n temSessao,\r\n aAutenticar = false,\r\n obterToken,\r\n onPrecisaInteracao,\r\n semSessao,\r\n aCarregar,\r\n semPermissao,\r\n children,\r\n}: RoleGuardProps) {\r\n const [decisao, setDecisao] = useState<Decisao>('aResolver')\r\n\r\n /**\r\n * Decidir uma só vez. Em `useState` isto era um bug: a marca entrava nas\r\n * dependências do efeito, o efeito voltava a correr, a limpeza cancelava a\r\n * tentativa em curso e a segunda passagem saía logo — a decisão nunca chegava\r\n * e o portal ficava eternamente em `aCarregar`. Só não dava quando o token\r\n * estava em cache (um F5), porque aí resolve antes da limpeza.\r\n */\r\n const jaCorreu = useRef(false)\r\n\r\n /**\r\n * As três funções/arrays abaixo chegam quase sempre inline de quem usa o\r\n * componente, ou seja com identidade nova a cada render. Em dependências,\r\n * faziam o efeito re-correr e cancelar o pedido em voo. Ficam em refs: o\r\n * efeito usa sempre a última versão sem reagir a ela.\r\n */\r\n const refRoles = useRef(rolesPermitidas)\r\n const refObterToken = useRef(obterToken)\r\n const refPrecisaInteracao = useRef(onPrecisaInteracao)\r\n refRoles.current = rolesPermitidas\r\n refObterToken.current = obterToken\r\n refPrecisaInteracao.current = onPrecisaInteracao\r\n\r\n useEffect(() => {\r\n if (!temSessao || aAutenticar || jaCorreu.current) return\r\n jaCorreu.current = true\r\n\r\n let cancelado = false\r\n // Chegou a uma conclusão (decisão ou pedido de interação): só então a marca\r\n // `jaCorreu` fica posta para sempre.\r\n let concluida = false\r\n void (async () => {\r\n if (!refRoles.current.length) {\r\n if (!cancelado) {\r\n concluida = true\r\n setDecisao('permitido')\r\n }\r\n return\r\n }\r\n try {\r\n const temAlguma = (t: string): boolean =>\r\n lerRolesDoToken(t).some((r) => refRoles.current.includes(r))\r\n\r\n let ok = temAlguma(await refObterToken.current())\r\n\r\n // Sem correspondência, uma segunda tentativa sem cache: uma role\r\n // atribuída há pouco ainda não está no token guardado, e negar o acesso\r\n // a quem acabou de a receber é o pior desfecho possível.\r\n if (!ok) ok = temAlguma(await refObterToken.current(true))\r\n\r\n if (!cancelado) {\r\n concluida = true\r\n setDecisao(ok ? 'permitido' : 'negado')\r\n }\r\n } catch {\r\n // Uma tentativa já cancelada não decide nada nem redireciona: quem a\r\n // substituiu é que responde (senão, no StrictMode, haveria dois redirects).\r\n if (cancelado) return\r\n // Falta de consentimento resolve-se com um redirect, uma única vez.\r\n if (refPrecisaInteracao.current) {\r\n concluida = true\r\n refPrecisaInteracao.current()\r\n return\r\n }\r\n concluida = true\r\n setDecisao('negado')\r\n }\r\n })()\r\n\r\n return () => {\r\n cancelado = true\r\n // Limpeza antes de haver conclusão: o StrictMode (só em desenvolvimento)\r\n // monta, limpa e volta a montar o efeito. Sem libertar a marca, a segunda\r\n // passagem saía logo e a primeira, já cancelada, nunca decidia — spinner\r\n // para sempre. Com a decisão já tomada a marca fica, para não repetir o pedido.\r\n if (!concluida) jaCorreu.current = false\r\n }\r\n }, [temSessao, aAutenticar])\r\n\r\n if (!temSessao) return <>{semSessao}</>\r\n if (decisao === 'aResolver') return <>{aCarregar}</>\r\n if (decisao === 'negado') return <>{semPermissao}</>\r\n return <>{children}</>\r\n}\r\n"],"names":[],"mappings":";;AAwCO,SAAS,gBAAgB,aAA+B;AAC7D,MAAI;AACF,UAAM,QAAQ,YAAY,MAAM,GAAG,EAAE,CAAC;AACtC,QAAI,CAAC,MAAO,QAAO,CAAA;AACnB,UAAM,OAAO,KAAK,MAAM,QAAQ,MAAM,GAAG,EAAE,QAAQ,MAAM,GAAG,CAAC;AAC7D,UAAM,UAAU,KAAK,MAAM,IAAI;AAC/B,WAAO,QAAQ,SAAS,CAAA;AAAA,EAC1B,QAAQ;AACN,WAAO,CAAA;AAAA,EACT;AACF;AAGA,SAAwB,UAAU;AAAA,EAChC;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAmB;AACjB,QAAM,CAAC,SAAS,UAAU,IAAI,SAAkB,WAAW;AAS3D,QAAM,WAAW,OAAO,KAAK;AAQ7B,QAAM,WAAW,OAAO,eAAe;AACvC,QAAM,gBAAgB,OAAO,UAAU;AACvC,QAAM,sBAAsB,OAAO,kBAAkB;AACrD,WAAS,UAAU;AACnB,gBAAc,UAAU;AACxB,sBAAoB,UAAU;AAE9B,YAAU,MAAM;AACd,QAAI,CAAC,aAAa,eAAe,SAAS,QAAS;AACnD,aAAS,UAAU;AAEnB,QAAI,YAAY;AAGhB,QAAI,YAAY;AAChB,UAAM,YAAY;AAChB,UAAI,CAAC,SAAS,QAAQ,QAAQ;AAC5B,YAAI,CAAC,WAAW;AACd,sBAAY;AACZ,qBAAW,WAAW;AAAA,QACxB;AACA;AAAA,MACF;AACA,UAAI;AACF,cAAM,YAAY,CAAC,MACjB,gBAAgB,CAAC,EAAE,KAAK,CAAC,MAAM,SAAS,QAAQ,SAAS,CAAC,CAAC;AAE7D,YAAI,KAAK,UAAU,MAAM,cAAc,SAAS;AAKhD,YAAI,CAAC,GAAI,MAAK,UAAU,MAAM,cAAc,QAAQ,IAAI,CAAC;AAEzD,YAAI,CAAC,WAAW;AACd,sBAAY;AACZ,qBAAW,KAAK,cAAc,QAAQ;AAAA,QACxC;AAAA,MACF,QAAQ;AAGN,YAAI,UAAW;AAEf,YAAI,oBAAoB,SAAS;AAC/B,sBAAY;AACZ,8BAAoB,QAAA;AACpB;AAAA,QACF;AACA,oBAAY;AACZ,mBAAW,QAAQ;AAAA,MACrB;AAAA,IACF,GAAA;AAEA,WAAO,MAAM;AACX,kBAAY;AAKZ,UAAI,CAAC,UAAW,UAAS,UAAU;AAAA,IACrC;AAAA,EACF,GAAG,CAAC,WAAW,WAAW,CAAC;AAE3B,MAAI,CAAC,UAAW,QAAO,oBAAA,UAAA,EAAG,UAAA,WAAU;AACpC,MAAI,YAAY,YAAa,QAAO,oBAAA,UAAA,EAAG,UAAA,WAAU;AACjD,MAAI,YAAY,SAAU,QAAO,oBAAA,UAAA,EAAG,UAAA,cAAa;AACjD,yCAAU,UAAS;AACrB;"}