uitec-ng-header 1.0.16 → 1.1.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 (50) hide show
  1. package/README.md +196 -24
  2. package/esm2020/lib/assistant/components/assistant-action-card/ui-assistant-action-card.component.mjs +102 -0
  3. package/esm2020/lib/assistant/components/assistant-button/ui-assistant-button.component.mjs +18 -0
  4. package/esm2020/lib/assistant/components/assistant-composer/ui-assistant-composer.component.mjs +79 -0
  5. package/esm2020/lib/assistant/components/assistant-layout/ui-assistant-layout.component.mjs +140 -0
  6. package/esm2020/lib/assistant/components/assistant-messages/ui-assistant-messages.component.mjs +144 -0
  7. package/esm2020/lib/assistant/components/assistant-panel/ui-assistant-panel.component.mjs +156 -0
  8. package/esm2020/lib/assistant/components/assistant-text/ui-assistant-text.component.mjs +26 -0
  9. package/esm2020/lib/assistant/models/uiny-api.models.mjs +12 -0
  10. package/esm2020/lib/assistant/models/uiny.models.mjs +2 -0
  11. package/esm2020/lib/assistant/services/ui-assistant.service.mjs +137 -0
  12. package/esm2020/lib/assistant/services/uiny-api.service.mjs +149 -0
  13. package/esm2020/lib/assistant/services/uiny-chat.service.mjs +368 -0
  14. package/esm2020/lib/assistant/services/uiny-session.service.mjs +74 -0
  15. package/esm2020/lib/assistant/ui-assistant.module.mjs +59 -0
  16. package/esm2020/lib/assistant/uiny.config.mjs +53 -0
  17. package/esm2020/lib/assistant/utils/uiny-api.adapter.mjs +154 -0
  18. package/esm2020/lib/assistant/utils/uiny-contexto.mjs +43 -0
  19. package/esm2020/lib/assistant/utils/uiny-markdown.mjs +122 -0
  20. package/esm2020/lib/my-account/my-account.component.mjs +3 -3
  21. package/esm2020/lib/ui-header.component.mjs +26 -10
  22. package/esm2020/lib/ui-header.module.mjs +10 -4
  23. package/esm2020/lib/ui-header.service.mjs +1 -1
  24. package/esm2020/public-api.mjs +17 -1
  25. package/fesm2015/uitec-ng-header.mjs +1809 -15
  26. package/fesm2015/uitec-ng-header.mjs.map +1 -1
  27. package/fesm2020/uitec-ng-header.mjs +1772 -15
  28. package/fesm2020/uitec-ng-header.mjs.map +1 -1
  29. package/lib/assistant/components/assistant-action-card/ui-assistant-action-card.component.d.ts +33 -0
  30. package/lib/assistant/components/assistant-button/ui-assistant-button.component.d.ts +9 -0
  31. package/lib/assistant/components/assistant-composer/ui-assistant-composer.component.d.ts +24 -0
  32. package/lib/assistant/components/assistant-layout/ui-assistant-layout.component.d.ts +51 -0
  33. package/lib/assistant/components/assistant-messages/ui-assistant-messages.component.d.ts +38 -0
  34. package/lib/assistant/components/assistant-panel/ui-assistant-panel.component.d.ts +53 -0
  35. package/lib/assistant/components/assistant-text/ui-assistant-text.component.d.ts +14 -0
  36. package/lib/assistant/models/uiny-api.models.d.ts +109 -0
  37. package/lib/assistant/models/uiny.models.d.ts +104 -0
  38. package/lib/assistant/services/ui-assistant.service.d.ts +55 -0
  39. package/lib/assistant/services/uiny-api.service.d.ts +38 -0
  40. package/lib/assistant/services/uiny-chat.service.d.ts +82 -0
  41. package/lib/assistant/services/uiny-session.service.d.ts +38 -0
  42. package/lib/assistant/ui-assistant.module.d.ts +19 -0
  43. package/lib/assistant/uiny.config.d.ts +31 -0
  44. package/lib/assistant/utils/uiny-api.adapter.d.ts +22 -0
  45. package/lib/assistant/utils/uiny-contexto.d.ts +7 -0
  46. package/lib/assistant/utils/uiny-markdown.d.ts +37 -0
  47. package/lib/ui-header.component.d.ts +10 -4
  48. package/lib/ui-header.module.d.ts +2 -1
  49. package/package.json +3 -2
  50. package/public-api.d.ts +15 -0
package/README.md CHANGED
@@ -1,24 +1,196 @@
1
- # UiHeader
2
-
3
- This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 15.2.0.
4
-
5
- ## Code scaffolding
6
-
7
- Run `ng generate component component-name --project ui-header` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project ui-header`.
8
- > Note: Don't forget to add `--project ui-header` or else it will be added to the default project in your `angular.json` file.
9
-
10
- ## Build
11
-
12
- Run `ng build ui-header` to build the project. The build artifacts will be stored in the `dist/` directory.
13
-
14
- ## Publishing
15
-
16
- After building your library with `ng build ui-header`, go to the dist folder `cd dist/ui-header` and run `npm publish`.
17
-
18
- ## Running unit tests
19
-
20
- Run `ng test ui-header` to execute the unit tests via [Karma](https://karma-runner.github.io).
21
-
22
- ## Further help
23
-
24
- To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.
1
+ # uitec-ng-header
2
+
3
+ Cabeçalho compartilhado (`<ui-header>`) e a **Uiny**, assistente virtual da Uishop.
4
+
5
+ ```bash
6
+ ng build ui-header # gera dist/ui-header
7
+ ng test ui-header --watch=false --browsers=ChromeHeadless --karma-config=karma.conf.js
8
+ ```
9
+
10
+ ---
11
+
12
+ ## Uiny
13
+
14
+ O header só mostra o botão. A conversa fica no `<ui-assistant-layout>`, que envolve a aplicação e abre o painel **à direita, ocupando espaço real**: a aplicação (header e sidebar fixos inclusive) passa a usar a largura restante à esquerda, sem ficar coberta.
15
+
16
+ O botão só aparece quando **todas** as condições valem:
17
+
18
+ 1. o header está com `[showAssistant]="true"` (padrão `false`; quem não liga continua igual);
19
+ 2. existe um `<ui-assistant-layout>` envolvendo a aplicação;
20
+ 3. o `AuthService` do `uitec-ng-core` tem usuário com token e empresa atual;
21
+ 4. a URL da API está configurada.
22
+
23
+ ### 1. Configurar a URL da API e o sistema
24
+
25
+ `AppModule`:
26
+
27
+ ```ts
28
+ import { UiAssistantModule } from 'uitec-ng-header';
29
+
30
+ @NgModule({
31
+ imports: [
32
+ UiHeaderModule, // já reexporta os componentes da Uiny
33
+ UiAssistantModule.forRoot({ sistemaOrigem: 'studio' }), // 'erp' no ERP
34
+ ],
35
+ })
36
+ ```
37
+
38
+ A URL vem de `environment.domain.uiny`. Inclua o `/api/v1`:
39
+
40
+ ```ts
41
+ // environment.ts
42
+ domain: {
43
+ api: 'http://localhost:8000/api',
44
+ uiny: 'http://localhost:8100/api/v1', // uishop-ia
45
+ }
46
+ // environment.prod.ts
47
+ domain: { uiny: 'https://<host-da-uiny>/api/v1' }
48
+ ```
49
+
50
+ `forRoot({ apiUrl })` sobrescreve o environment se precisar. Opções: `larguraPainel` (340–400, padrão 380) e `larguraMinimaLadoALado` (padrão 1200).
51
+
52
+ **Avatar:** como as outras imagens das libs (logo, coroa), o arquivo fica nos `assets` de cada aplicação. Coloque em `src/assets/images/uiny/avatar.svg` no Studio, no ERP e na demo, ou informe outro caminho em `forRoot({ avatarUrl })`. Se a imagem não carregar, o painel mostra o ícone padrão.
53
+
54
+ A origem do Angular precisa estar em `CORS_ORIGINS` do uishop-ia.
55
+
56
+ ### 2. Autenticação
57
+
58
+ Nada novo para configurar. A Uiny lê o token de `AuthService.currentUserValue.token`, a mesma fonte do `JwtInterceptor`, e envia `Authorization: Bearer` **somente** para a URL da Uiny.
59
+
60
+ As chamadas da Uiny usam um `HttpClient` próprio, sem os interceptors da aplicação. Motivo: o `ErrorInterceptor` troca o erro por uma string e perde o status. Sem o status não dá para distinguir sessão expirada, ação expirada e conflito. Além disso, ele mostraria toasts globais, e o `SpinnerInterceptor` cobriria a tela a cada mensagem.
61
+
62
+ A Uiny fecha o painel, cancela as requisições e descarta conversa, ações e catálogo em memória quando:
63
+
64
+ - acontece logout (`currentUser` vira `null`);
65
+ - muda o usuário, a empresa atual ou o token (inclusive no re-login do mesmo usuário);
66
+ - a API responde 401 (a Uiny fica oculta até a sessão mudar).
67
+
68
+ Nada vai para `localStorage`/`sessionStorage`. Sem internet (`navigator.onLine`), o painel mostra o aviso e bloqueia o envio.
69
+
70
+ ### 3. Integrar ao layout (Studio e ERP)
71
+
72
+ **A flag no header sozinha não desloca a aplicação.** Envolva o conteúdo do `content.component.html`:
73
+
74
+ ```html
75
+ <ui-assistant-layout (assistantEvent)="aoEventoUiny($event)">
76
+ <div [ngClass]="layout.config.settings.layout_type" [class]="layout.config.settings.layout_version">
77
+ <div class="page-wrapper" id="canvas-bookmark" [ngClass]="layoutClass">
78
+ <app-header *ngIf="userObs | async"></app-header>
79
+ ...
80
+ </div>
81
+ </div>
82
+ <ui-suporte></ui-suporte> <!-- ERP: dentro do layout, para acompanhar a coluna -->
83
+ </ui-assistant-layout>
84
+ <app-spinner *ngIf="spinnerService.spinnerObservable | async"></app-spinner>
85
+ ```
86
+
87
+ E no wrapper do header (`header.component.html`):
88
+
89
+ ```html
90
+ <ui-header [showAssistant]="true" ...>
91
+ ```
92
+
93
+ Como funciona:
94
+
95
+ - **Fechado:** wrappers neutros, a janela rola normalmente. Nada muda para o usuário.
96
+ - **Aberto (≥ 1200 px):** linha flex `[aplicação | painel]` com a altura da viewport. A coluna da aplicação recebe `contain: layout paint`, então os elementos `position: fixed` do tema Cuba (`.page-header`, `.sidebar-wrapper`) passam a se posicionar dentro dela, e ela ganha rolagem própria. A posição de rolagem é transferida na abertura e devolvida no fechamento. A cada `NavigationEnd`, a coluna volta ao topo (o `scrollPositionRestoration` do router só atua na janela).
97
+ - **Aberto (< 1200 px):** o painel ocupa a largura toda e a aplicação fica recolhida (`inert`) até o usuário tocar em "Voltar".
98
+ - Transição de largura de 240 ms, desligada com `prefers-reduced-motion`.
99
+
100
+ Efeitos colaterais conhecidos com o painel aberto:
101
+
102
+ - Listeners de `window.scroll` não disparam, porque quem rola é a coluna.
103
+ - As media queries do tema continuam medindo a viewport: o layout desktop do Cuba é mantido na coluna, que tem no mínimo 800 px.
104
+ - Modais e overlays anexados ao `body` continuam cobrindo a tela toda, como hoje.
105
+
106
+ O header da lib passou a usar `width: 100%` em `.not-sidebar` (antes `100vw`) para acompanhar a coluna.
107
+
108
+ ### 4. Contexto da tela
109
+
110
+ ```ts
111
+ constructor(private uiny: UiAssistantService) { }
112
+
113
+ ngOnInit() {
114
+ this.uiny.definirContexto({
115
+ tela: 'loja-leiaute/editar', // até 60 caracteres [a-z0-9_-/.]
116
+ idLoja: this.loja.id_loja,
117
+ idLojaLeiaute: this.lojaLeiaute.id_loja_leiaute,
118
+ // também: idTema, idProduto, idPedido
119
+ });
120
+ }
121
+ ngOnDestroy() { this.uiny.definirContexto(null); }
122
+ ```
123
+
124
+ Os campos seguem o `ContextoTela` do backend, que recusa campos extras com 422. O `sistema` vem do `forRoot`. `atualizarContexto({ idLoja })` altera só os campos informados, e valores inválidos são descartados. O contexto é só uma indicação: quem autoriza é o backend. Com `idLoja`, o backend confere no Studio se a loja é da empresa (403 se não for) e restringe a conversa a ela.
125
+
126
+ **Trocar de loja encerra a conversa atual.** A lista "Conversas anteriores" mostra só as do mesmo sistema e da mesma loja. Trocar de empresa limpa tudo (seção 2).
127
+
128
+ ### 5. Eventos de ações concluídas
129
+
130
+ ```ts
131
+ aoEventoUiny(e: UinyEvento) {
132
+ switch (e.tipo) {
133
+ case 'acao_concluida': // a API devolveu a ação como "executada"
134
+ break;
135
+ case 'tema_atualizado': // instrução "atualizar_preview_tema" do backend
136
+ if (e.idLojaLeiaute === this.lojaLeiaute?.id_loja_leiaute) this.recarregarPreview();
137
+ break;
138
+ }
139
+ }
140
+ ```
141
+
142
+ Também disponível como `UiAssistantService.eventos$`. Eventos só saem de respostas novas, nunca do histórico. Instruções fora da lista são descartadas. O componente não navega e não executa nada recebido da API.
143
+
144
+ ### Exemplos
145
+
146
+ **Studio** (`sistemaOrigem: 'studio'`): contexto com `idLoja` e `idLojaLeiaute` na tela do editor; recarregar a prévia em `tema_atualizado`.
147
+
148
+ **ERP** (`sistemaOrigem: 'erp'`): contexto com `tela` (ex.: `produto/form`) e `idProduto` ou `idPedido` quando houver. As ferramentas atuais do ERP são só de consulta.
149
+
150
+ ### Confirmação de ações
151
+
152
+ O card mostra o `resumo` e os `detalhes` da ação (na troca de cor: tema, loja, cor, valor atual e novo, com amostra), o prazo e os botões **Confirmar** e **Cancelar**:
153
+
154
+ - A confirmação só acontece pelo clique. O card envia `POST /acoes/{id}/confirmar` com corpo `{}`: nenhum argumento sai do frontend.
155
+ - Cliques repetidos são ignorados enquanto a ação não está `pendente`.
156
+ - Sucesso só aparece com `situacao: executada` na resposta. Situação desconhecida vira "Resultado a verificar".
157
+ - 409 `ACAO_INVALIDADA`: o card antigo vira "Precisa de nova confirmação" e a nova proposta aparece com seus próprios botões.
158
+ - 409 de expirada, cancelada ou em execução, e 502/504: o card usa a situação que vem no corpo do erro.
159
+ - Timeout ou erro de rede depois de confirmar: **nada é repetido**. O card fica "Resultado a verificar" com o botão "Verificar resultado", que relê o histórico da conversa.
160
+ - Ação vencida pelo relógio local não é enviada.
161
+
162
+ Pedidos de esclarecimento (`estado: esclarecimento` com bloco `opcoes`) mostram as opções como botões na última mensagem; o clique envia a opção como texto.
163
+
164
+ ### Segurança e acessibilidade
165
+
166
+ - O texto é renderizado como um subconjunto de Markdown por interpolação (sem `innerHTML`, sem bypass). Links só `http`, `https` e `mailto`, abertos com `noopener noreferrer`.
167
+ - Mensagens de 5xx não são exibidas cruas. O id de correlação aparece para o suporte.
168
+ - Painel `aside` não modal no desktop, com rótulo acessível. O foco vai para o campo ao abrir e volta ao botão ao fechar. Escape fecha. Há uma região `aria-live` discreta para "respondendo", "nova resposta" e "alteração concluída".
169
+ - Enter envia e Shift+Enter quebra a linha. Composição (IME) é respeitada. Envio vazio ou duplicado é bloqueado. O limite é de 2000 caracteres (`UINY_MENSAGEM_MAX_CARACTERES` do backend).
170
+
171
+ ### API pública
172
+
173
+ `UiAssistantModule`, `UiAssistantService`, `UinyChatService`, `UinyApiService`, `UinySessionService`, os componentes `ui-assistant-*`, os tipos `UinyConfig`, `UinyContexto`, `UinyEvento` e `Uiny*Api`, e `UINY_CONFIG`.
174
+
175
+ ### Contrato
176
+
177
+ Fonte: `C:\git\uishop\uishop-ia` (README, `config/web.php`, `services/uiny/ApresentadorConversa.php`, `ContextoTela.php`, `ConfirmacaoService.php`, `config/Constants.php`). Tipos em `lib/assistant/models/uiny-api.models.ts`, conversão em `utils/uiny-api.adapter.ts`.
178
+
179
+ | Rota (`/api/v1`) | Uso no frontend |
180
+ |---|---|
181
+ | `POST /conversas` `{ contexto }` | criada no primeiro envio |
182
+ | `POST /conversas/{id}/mensagens` `{ texto, contexto }` | resposta com `conversa`, `estado`, `mensagem`, `acao_pendente` |
183
+ | `GET /conversas?page=1&per_page=20` | "Conversas anteriores", filtrada pelo sistema e pela loja atuais |
184
+ | `GET /conversas/{id}?page=1&per_page=100` | abrir conversa anterior e "Verificar resultado" |
185
+ | `POST /acoes/{id}/confirmar` e `/cancelar` | corpo `{}` |
186
+
187
+ Pontos em aberto:
188
+
189
+ - **Sugestões iniciais:** a API não expõe o catálogo de ferramentas. As sugestões ficam em `UINY_SUGESTOES` (`uiny.config.ts`) e acompanham as ferramentas listadas no README do backend; mantenha os dois em sincronia.
190
+ - **Blocos de `apresentacao`:** só `opcoes` é renderizado. `lista_produtos`, `resumo_vendas`, `lista_lojas`, `tema` e `alteracao_cor` aparecem apenas pelo texto da mensagem.
191
+ - **Histórico longo:** abrir uma conversa carrega as 100 mensagens mais recentes; não há "carregar anteriores".
192
+ - **401:** o backend sugere redirecionar para o login. A Uiny apenas se esconde, para não derrubar a sessão da aplicação por causa da idade máxima de token, que é mais curta na Uiny.
193
+
194
+ ### Demonstração
195
+
196
+ App `cuba`, rota `#/assistente` ("Uiny (assistente)" no menu). A API é simulada por `src/app/site/pages/assistente/demo/uiny-demo.backend.ts`, no formato do contrato real, que só responde a `https://uiny-demo.local/api/v1` e repassa o resto ao `HttpXhrBackend`. O usuário é trocado só em memória. A página tem controles para recurso ligado/desligado, login/logout, troca de loja, resultado da confirmação e atraso. Para usar a API real na demo, defina `environment.domain.uiny` (a demo passa a usá-la no lugar da simulada) e entre no Studio ou no ERP em `localhost` para ter o cookie de sessão.
@@ -0,0 +1,102 @@
1
+ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Input, NgZone, Output } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ import * as i1 from "@angular/common";
4
+ import * as i2 from "uitec-ng-icon";
5
+ const ROTULOS = {
6
+ pendente: 'Aguardando sua confirmação',
7
+ executando: 'Executando…',
8
+ concluida: 'Concluída',
9
+ cancelada: 'Cancelada',
10
+ expirada: 'Expirada',
11
+ invalidada: 'Precisa de nova confirmação',
12
+ falha: 'Não concluída',
13
+ indeterminada: 'Resultado a verificar',
14
+ };
15
+ const DESCRICOES = {
16
+ concluida: 'A alteração foi aplicada.',
17
+ cancelada: 'Nada foi alterado.',
18
+ expirada: 'O prazo para confirmar terminou. Nada foi alterado; peça de novo se ainda quiser.',
19
+ invalidada: 'Os dados mudaram desde a proposta. Peça a alteração de novo para revisar.',
20
+ falha: 'A alteração não foi aplicada.',
21
+ };
22
+ /**
23
+ * Card de ação pendente. A confirmação só acontece pelo clique em "Confirmar":
24
+ * o card emite apenas o id da ação persistida, sem argumentos.
25
+ */
26
+ export class UiAssistantActionCardComponent {
27
+ constructor(cdr, zone) {
28
+ this.cdr = cdr;
29
+ this.zone = zone;
30
+ this.confirmar = new EventEmitter();
31
+ this.cancelar = new EventEmitter();
32
+ this.verificar = new EventEmitter();
33
+ this.agora = Date.now();
34
+ }
35
+ ngOnChanges() {
36
+ this.agendar();
37
+ }
38
+ ngOnDestroy() {
39
+ clearInterval(this.timer);
40
+ }
41
+ /** O servidor decide a expiração; aqui só evitamos oferecer um clique que já vai falhar. */
42
+ get expiradaLocalmente() {
43
+ return this.acao?.estado === 'pendente' && !!this.acao.expiraEm && this.acao.expiraEm.getTime() <= this.agora;
44
+ }
45
+ get estado() {
46
+ return this.expiradaLocalmente ? 'expirada' : this.acao?.estado;
47
+ }
48
+ get rotulo() {
49
+ return ROTULOS[this.estado] ?? '';
50
+ }
51
+ get descricao() {
52
+ return this.acao?.aviso || DESCRICOES[this.estado] || null;
53
+ }
54
+ get podeDecidir() {
55
+ return this.estado === 'pendente' && !this.acao.enviando;
56
+ }
57
+ get minutosRestantes() {
58
+ if (this.estado !== 'pendente' || !this.acao.expiraEm)
59
+ return null;
60
+ return Math.max(1, Math.ceil((this.acao.expiraEm.getTime() - this.agora) / 60000));
61
+ }
62
+ ehCor(valor) {
63
+ return /^#(?:[0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$/i.test(valor);
64
+ }
65
+ aoConfirmar() {
66
+ if (this.podeDecidir)
67
+ this.confirmar.emit(this.acao.id);
68
+ }
69
+ aoCancelar() {
70
+ if (this.podeDecidir)
71
+ this.cancelar.emit(this.acao.id);
72
+ }
73
+ agendar() {
74
+ clearInterval(this.timer);
75
+ this.agora = Date.now();
76
+ if (this.acao?.estado !== 'pendente' || !this.acao.expiraEm)
77
+ return;
78
+ this.zone.runOutsideAngular(() => {
79
+ this.timer = setInterval(() => this.zone.run(() => {
80
+ this.agora = Date.now();
81
+ if (this.expiradaLocalmente)
82
+ clearInterval(this.timer);
83
+ this.cdr.markForCheck();
84
+ }), 15000);
85
+ });
86
+ }
87
+ }
88
+ UiAssistantActionCardComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: UiAssistantActionCardComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
89
+ UiAssistantActionCardComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: UiAssistantActionCardComponent, selector: "ui-assistant-action-card", inputs: { acao: "acao" }, outputs: { confirmar: "confirmar", cancelar: "cancelar", verificar: "verificar" }, usesOnChanges: true, ngImport: i0, template: "<article class=\"uiny-acao\" [ngClass]=\"'uiny-acao--' + estado\" [attr.aria-busy]=\"acao.enviando ? 'true' : null\"\n [attr.aria-labelledby]=\"'uiny-acao-' + acao.id\">\n <header class=\"uiny-acao__topo\">\n <span class=\"uiny-acao__selo\">\n <span *ngIf=\"estado === 'executando' || acao.enviando\" class=\"uiny-acao__spinner\" aria-hidden=\"true\"></span>\n <ui-icon *ngIf=\"estado === 'concluida'\" icon=\"check_circle\" size=\"16\"></ui-icon>\n <ui-icon *ngIf=\"estado === 'falha' || estado === 'indeterminada'\" icon=\"error\" size=\"16\"></ui-icon>\n <ui-icon *ngIf=\"estado === 'pendente' && !acao.enviando\" icon=\"pending_actions\" size=\"16\"></ui-icon>\n {{ rotulo }}\n </span>\n <span *ngIf=\"minutosRestantes\" class=\"uiny-acao__prazo\">expira em {{ minutosRestantes }} min</span>\n </header>\n\n <p class=\"uiny-acao__resumo\" [id]=\"'uiny-acao-' + acao.id\">{{ acao.resumo }}</p>\n\n <dl *ngIf=\"acao.detalhes?.length\" class=\"uiny-acao__detalhes\">\n <div *ngFor=\"let d of acao.detalhes\" class=\"uiny-acao__item\">\n <dt>{{ d.rotulo }}</dt>\n <dd>\n <span *ngIf=\"ehCor(d.valor)\" class=\"uiny-acao__cor\" [style.background-color]=\"d.valor\" aria-hidden=\"true\"></span>\n {{ d.valor }}\n </dd>\n </div>\n </dl>\n\n <p *ngIf=\"descricao\" class=\"uiny-acao__descricao\" role=\"status\">{{ descricao }}</p>\n\n <div *ngIf=\"estado === 'pendente'\" class=\"uiny-acao__botoes\">\n <button type=\"button\" class=\"uiny-acao__botao uiny-acao__botao--secundario\" [disabled]=\"!podeDecidir\" (click)=\"aoCancelar()\">\n Cancelar\n </button>\n <button type=\"button\" class=\"uiny-acao__botao uiny-acao__botao--primario\" [disabled]=\"!podeDecidir\" (click)=\"aoConfirmar()\">\n Confirmar\n </button>\n </div>\n\n <div *ngIf=\"estado === 'indeterminada'\" class=\"uiny-acao__botoes\">\n <button type=\"button\" class=\"uiny-acao__botao uiny-acao__botao--secundario\" [disabled]=\"acao.enviando\" (click)=\"verificar.emit(acao.id)\">\n Verificar resultado\n </button>\n </div>\n</article>\n", styles: [":host{display:block;margin-top:8px}.uiny-acao{padding:12px 14px;border:1px solid var(--uiny-borda, #ececf3);border-left:3px solid var(--uiny-primaria, #7366ff);border-radius:12px;background:var(--uiny-fundo, #fff);box-shadow:0 2px 10px #1f1b4d0d}.uiny-acao--concluida{border-left-color:#1aa467}.uiny-acao--falha,.uiny-acao--indeterminada{border-left-color:var(--uiny-erro, #d9364f)}.uiny-acao--cancelada,.uiny-acao--expirada,.uiny-acao--invalidada{border-left-color:var(--uiny-texto-suave, #6b6b80)}.uiny-acao__topo{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:6px}.uiny-acao__selo{display:inline-flex;align-items:center;gap:5px;font-size:12px;font-weight:600;color:var(--uiny-primaria, #7366ff)}.uiny-acao--concluida .uiny-acao__selo{color:#1aa467}.uiny-acao--falha .uiny-acao__selo,.uiny-acao--indeterminada .uiny-acao__selo{color:var(--uiny-erro, #d9364f)}.uiny-acao--cancelada .uiny-acao__selo,.uiny-acao--expirada .uiny-acao__selo,.uiny-acao--invalidada .uiny-acao__selo{color:var(--uiny-texto-suave, #6b6b80)}.uiny-acao__prazo{font-size:11px;color:var(--uiny-texto-suave, #6b6b80)}.uiny-acao__resumo{margin:0;font-weight:600;line-height:1.45;color:var(--uiny-texto, #2b2b2b);overflow-wrap:anywhere}.uiny-acao__detalhes{margin:10px 0 0;padding:8px 10px;border-radius:9px;background:var(--uiny-fundo-suave, #f7f7fb);font-size:13px}.uiny-acao__item{display:flex;justify-content:space-between;gap:12px}.uiny-acao__item+.uiny-acao__item{margin-top:4px}.uiny-acao__item dt{font-weight:400;color:var(--uiny-texto-suave, #6b6b80)}.uiny-acao__item dd{display:inline-flex;align-items:center;gap:6px;margin:0;font-weight:600;text-align:right;overflow-wrap:anywhere}.uiny-acao__cor{flex:0 0 auto;width:14px;height:14px;border:1px solid rgba(0,0,0,.12);border-radius:4px}.uiny-acao__descricao{margin:8px 0 0;font-size:12.5px;line-height:1.45;color:var(--uiny-texto-suave, #6b6b80)}.uiny-acao__botoes{display:flex;justify-content:flex-end;gap:8px;margin-top:12px}.uiny-acao__botao{min-height:34px;padding:0 14px;border-radius:9px;font-size:13px;font-weight:600;cursor:pointer}.uiny-acao__botao:disabled{opacity:.5;cursor:not-allowed}.uiny-acao__botao:focus-visible{outline:2px solid var(--uiny-primaria, #7366ff);outline-offset:2px}.uiny-acao__botao--primario{border:1px solid var(--uiny-primaria, #7366ff);background:var(--uiny-primaria, #7366ff);color:#fff}.uiny-acao__botao--secundario{border:1px solid var(--uiny-borda, #ececf3);background:transparent;color:var(--uiny-texto, #2b2b2b)}.uiny-acao__spinner{width:12px;height:12px;border:2px solid var(--uiny-borda, #ececf3);border-top-color:var(--uiny-primaria, #7366ff);border-radius:50%;animation:uiny-girar .8s linear infinite}@keyframes uiny-girar{to{transform:rotate(360deg)}}@media (prefers-reduced-motion: reduce){.uiny-acao__spinner{animation-duration:2.4s}}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.UiIconComponent, selector: "ui-icon", inputs: ["icon", "size", "class"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
90
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: UiAssistantActionCardComponent, decorators: [{
91
+ type: Component,
92
+ args: [{ selector: 'ui-assistant-action-card', changeDetection: ChangeDetectionStrategy.OnPush, template: "<article class=\"uiny-acao\" [ngClass]=\"'uiny-acao--' + estado\" [attr.aria-busy]=\"acao.enviando ? 'true' : null\"\n [attr.aria-labelledby]=\"'uiny-acao-' + acao.id\">\n <header class=\"uiny-acao__topo\">\n <span class=\"uiny-acao__selo\">\n <span *ngIf=\"estado === 'executando' || acao.enviando\" class=\"uiny-acao__spinner\" aria-hidden=\"true\"></span>\n <ui-icon *ngIf=\"estado === 'concluida'\" icon=\"check_circle\" size=\"16\"></ui-icon>\n <ui-icon *ngIf=\"estado === 'falha' || estado === 'indeterminada'\" icon=\"error\" size=\"16\"></ui-icon>\n <ui-icon *ngIf=\"estado === 'pendente' && !acao.enviando\" icon=\"pending_actions\" size=\"16\"></ui-icon>\n {{ rotulo }}\n </span>\n <span *ngIf=\"minutosRestantes\" class=\"uiny-acao__prazo\">expira em {{ minutosRestantes }} min</span>\n </header>\n\n <p class=\"uiny-acao__resumo\" [id]=\"'uiny-acao-' + acao.id\">{{ acao.resumo }}</p>\n\n <dl *ngIf=\"acao.detalhes?.length\" class=\"uiny-acao__detalhes\">\n <div *ngFor=\"let d of acao.detalhes\" class=\"uiny-acao__item\">\n <dt>{{ d.rotulo }}</dt>\n <dd>\n <span *ngIf=\"ehCor(d.valor)\" class=\"uiny-acao__cor\" [style.background-color]=\"d.valor\" aria-hidden=\"true\"></span>\n {{ d.valor }}\n </dd>\n </div>\n </dl>\n\n <p *ngIf=\"descricao\" class=\"uiny-acao__descricao\" role=\"status\">{{ descricao }}</p>\n\n <div *ngIf=\"estado === 'pendente'\" class=\"uiny-acao__botoes\">\n <button type=\"button\" class=\"uiny-acao__botao uiny-acao__botao--secundario\" [disabled]=\"!podeDecidir\" (click)=\"aoCancelar()\">\n Cancelar\n </button>\n <button type=\"button\" class=\"uiny-acao__botao uiny-acao__botao--primario\" [disabled]=\"!podeDecidir\" (click)=\"aoConfirmar()\">\n Confirmar\n </button>\n </div>\n\n <div *ngIf=\"estado === 'indeterminada'\" class=\"uiny-acao__botoes\">\n <button type=\"button\" class=\"uiny-acao__botao uiny-acao__botao--secundario\" [disabled]=\"acao.enviando\" (click)=\"verificar.emit(acao.id)\">\n Verificar resultado\n </button>\n </div>\n</article>\n", styles: [":host{display:block;margin-top:8px}.uiny-acao{padding:12px 14px;border:1px solid var(--uiny-borda, #ececf3);border-left:3px solid var(--uiny-primaria, #7366ff);border-radius:12px;background:var(--uiny-fundo, #fff);box-shadow:0 2px 10px #1f1b4d0d}.uiny-acao--concluida{border-left-color:#1aa467}.uiny-acao--falha,.uiny-acao--indeterminada{border-left-color:var(--uiny-erro, #d9364f)}.uiny-acao--cancelada,.uiny-acao--expirada,.uiny-acao--invalidada{border-left-color:var(--uiny-texto-suave, #6b6b80)}.uiny-acao__topo{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:6px}.uiny-acao__selo{display:inline-flex;align-items:center;gap:5px;font-size:12px;font-weight:600;color:var(--uiny-primaria, #7366ff)}.uiny-acao--concluida .uiny-acao__selo{color:#1aa467}.uiny-acao--falha .uiny-acao__selo,.uiny-acao--indeterminada .uiny-acao__selo{color:var(--uiny-erro, #d9364f)}.uiny-acao--cancelada .uiny-acao__selo,.uiny-acao--expirada .uiny-acao__selo,.uiny-acao--invalidada .uiny-acao__selo{color:var(--uiny-texto-suave, #6b6b80)}.uiny-acao__prazo{font-size:11px;color:var(--uiny-texto-suave, #6b6b80)}.uiny-acao__resumo{margin:0;font-weight:600;line-height:1.45;color:var(--uiny-texto, #2b2b2b);overflow-wrap:anywhere}.uiny-acao__detalhes{margin:10px 0 0;padding:8px 10px;border-radius:9px;background:var(--uiny-fundo-suave, #f7f7fb);font-size:13px}.uiny-acao__item{display:flex;justify-content:space-between;gap:12px}.uiny-acao__item+.uiny-acao__item{margin-top:4px}.uiny-acao__item dt{font-weight:400;color:var(--uiny-texto-suave, #6b6b80)}.uiny-acao__item dd{display:inline-flex;align-items:center;gap:6px;margin:0;font-weight:600;text-align:right;overflow-wrap:anywhere}.uiny-acao__cor{flex:0 0 auto;width:14px;height:14px;border:1px solid rgba(0,0,0,.12);border-radius:4px}.uiny-acao__descricao{margin:8px 0 0;font-size:12.5px;line-height:1.45;color:var(--uiny-texto-suave, #6b6b80)}.uiny-acao__botoes{display:flex;justify-content:flex-end;gap:8px;margin-top:12px}.uiny-acao__botao{min-height:34px;padding:0 14px;border-radius:9px;font-size:13px;font-weight:600;cursor:pointer}.uiny-acao__botao:disabled{opacity:.5;cursor:not-allowed}.uiny-acao__botao:focus-visible{outline:2px solid var(--uiny-primaria, #7366ff);outline-offset:2px}.uiny-acao__botao--primario{border:1px solid var(--uiny-primaria, #7366ff);background:var(--uiny-primaria, #7366ff);color:#fff}.uiny-acao__botao--secundario{border:1px solid var(--uiny-borda, #ececf3);background:transparent;color:var(--uiny-texto, #2b2b2b)}.uiny-acao__spinner{width:12px;height:12px;border:2px solid var(--uiny-borda, #ececf3);border-top-color:var(--uiny-primaria, #7366ff);border-radius:50%;animation:uiny-girar .8s linear infinite}@keyframes uiny-girar{to{transform:rotate(360deg)}}@media (prefers-reduced-motion: reduce){.uiny-acao__spinner{animation-duration:2.4s}}\n"] }]
93
+ }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i0.NgZone }]; }, propDecorators: { acao: [{
94
+ type: Input
95
+ }], confirmar: [{
96
+ type: Output
97
+ }], cancelar: [{
98
+ type: Output
99
+ }], verificar: [{
100
+ type: Output
101
+ }] } });
102
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidWktYXNzaXN0YW50LWFjdGlvbi1jYXJkLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3VpLWhlYWRlci9zcmMvbGliL2Fzc2lzdGFudC9jb21wb25lbnRzL2Fzc2lzdGFudC1hY3Rpb24tY2FyZC91aS1hc3Npc3RhbnQtYWN0aW9uLWNhcmQuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvdWktaGVhZGVyL3NyYy9saWIvYXNzaXN0YW50L2NvbXBvbmVudHMvYXNzaXN0YW50LWFjdGlvbi1jYXJkL3VpLWFzc2lzdGFudC1hY3Rpb24tY2FyZC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0gsdUJBQXVCLEVBQ3ZCLGlCQUFpQixFQUNqQixTQUFTLEVBQ1QsWUFBWSxFQUNaLEtBQUssRUFDTCxNQUFNLEVBR04sTUFBTSxFQUNULE1BQU0sZUFBZSxDQUFDOzs7O0FBR3ZCLE1BQU0sT0FBTyxHQUFtQztJQUM1QyxRQUFRLEVBQUUsNEJBQTRCO0lBQ3RDLFVBQVUsRUFBRSxhQUFhO0lBQ3pCLFNBQVMsRUFBRSxXQUFXO0lBQ3RCLFNBQVMsRUFBRSxXQUFXO0lBQ3RCLFFBQVEsRUFBRSxVQUFVO0lBQ3BCLFVBQVUsRUFBRSw2QkFBNkI7SUFDekMsS0FBSyxFQUFFLGVBQWU7SUFDdEIsYUFBYSxFQUFFLHVCQUF1QjtDQUN6QyxDQUFDO0FBRUYsTUFBTSxVQUFVLEdBQTRDO0lBQ3hELFNBQVMsRUFBRSwyQkFBMkI7SUFDdEMsU0FBUyxFQUFFLG9CQUFvQjtJQUMvQixRQUFRLEVBQUUsbUZBQW1GO0lBQzdGLFVBQVUsRUFBRSwyRUFBMkU7SUFDdkYsS0FBSyxFQUFFLCtCQUErQjtDQUN6QyxDQUFDO0FBRUY7OztHQUdHO0FBT0gsTUFBTSxPQUFPLDhCQUE4QjtJQVd2QyxZQUFvQixHQUFzQixFQUFVLElBQVk7UUFBNUMsUUFBRyxHQUFILEdBQUcsQ0FBbUI7UUFBVSxTQUFJLEdBQUosSUFBSSxDQUFRO1FBUHRELGNBQVMsR0FBRyxJQUFJLFlBQVksRUFBVSxDQUFDO1FBQ3ZDLGFBQVEsR0FBRyxJQUFJLFlBQVksRUFBVSxDQUFDO1FBQ3RDLGNBQVMsR0FBRyxJQUFJLFlBQVksRUFBVSxDQUFDO1FBRTFDLFVBQUssR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7SUFHMEMsQ0FBQztJQUVyRSxXQUFXO1FBQ1AsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQ25CLENBQUM7SUFFRCxXQUFXO1FBQ1AsYUFBYSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUM5QixDQUFDO0lBRUQsNEZBQTRGO0lBQzVGLElBQUksa0JBQWtCO1FBQ2xCLE9BQU8sSUFBSSxDQUFDLElBQUksRUFBRSxNQUFNLEtBQUssVUFBVSxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLEVBQUUsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDO0lBQ2xILENBQUM7SUFFRCxJQUFJLE1BQU07UUFDTixPQUFPLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQztJQUNwRSxDQUFDO0lBRUQsSUFBSSxNQUFNO1FBQ04sT0FBTyxPQUFPLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUN0QyxDQUFDO0lBRUQsSUFBSSxTQUFTO1FBQ1QsT0FBTyxJQUFJLENBQUMsSUFBSSxFQUFFLEtBQUssSUFBSSxVQUFVLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLElBQUksQ0FBQztJQUMvRCxDQUFDO0lBRUQsSUFBSSxXQUFXO1FBQ1gsT0FBTyxJQUFJLENBQUMsTUFBTSxLQUFLLFVBQVUsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDO0lBQzdELENBQUM7SUFFRCxJQUFJLGdCQUFnQjtRQUNoQixJQUFJLElBQUksQ0FBQyxNQUFNLEtBQUssVUFBVSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRO1lBQUUsT0FBTyxJQUFJLENBQUM7UUFDbkUsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxFQUFFLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7SUFDdkYsQ0FBQztJQUVELEtBQUssQ0FBQyxLQUFhO1FBQ2YsT0FBTyw2Q0FBNkMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDckUsQ0FBQztJQUVELFdBQVc7UUFDUCxJQUFJLElBQUksQ0FBQyxXQUFXO1lBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUM1RCxDQUFDO0lBRUQsVUFBVTtRQUNOLElBQUksSUFBSSxDQUFDLFdBQVc7WUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQzNELENBQUM7SUFFTyxPQUFPO1FBQ1gsYUFBYSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMxQixJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUN4QixJQUFJLElBQUksQ0FBQyxJQUFJLEVBQUUsTUFBTSxLQUFLLFVBQVUsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUTtZQUFFLE9BQU87UUFDcEUsSUFBSSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLEVBQUU7WUFDN0IsSUFBSSxDQUFDLEtBQUssR0FBRyxXQUFXLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFO2dCQUM5QyxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztnQkFDeEIsSUFBSSxJQUFJLENBQUMsa0JBQWtCO29CQUFFLGFBQWEsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQ3ZELElBQUksQ0FBQyxHQUFHLENBQUMsWUFBWSxFQUFFLENBQUM7WUFDNUIsQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDZixDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7OzRIQXRFUSw4QkFBOEI7Z0hBQTlCLDhCQUE4QixrTUMxQzNDLDJ0RUEwQ0E7NEZEQWEsOEJBQThCO2tCQU4xQyxTQUFTOytCQUNJLDBCQUEwQixtQkFHbkIsdUJBQXVCLENBQUMsTUFBTTs2SEFJdEMsSUFBSTtzQkFBWixLQUFLO2dCQUVJLFNBQVM7c0JBQWxCLE1BQU07Z0JBQ0csUUFBUTtzQkFBakIsTUFBTTtnQkFDRyxTQUFTO3NCQUFsQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcclxuICAgIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxyXG4gICAgQ2hhbmdlRGV0ZWN0b3JSZWYsXHJcbiAgICBDb21wb25lbnQsXHJcbiAgICBFdmVudEVtaXR0ZXIsXHJcbiAgICBJbnB1dCxcclxuICAgIE5nWm9uZSxcclxuICAgIE9uQ2hhbmdlcyxcclxuICAgIE9uRGVzdHJveSxcclxuICAgIE91dHB1dFxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBVaW55QWNhbywgVWlueUVzdGFkb0FjYW8gfSBmcm9tICcuLi8uLi9tb2RlbHMvdWlueS5tb2RlbHMnO1xyXG5cclxuY29uc3QgUk9UVUxPUzogUmVjb3JkPFVpbnlFc3RhZG9BY2FvLCBzdHJpbmc+ID0ge1xyXG4gICAgcGVuZGVudGU6ICdBZ3VhcmRhbmRvIHN1YSBjb25maXJtYcOnw6NvJyxcclxuICAgIGV4ZWN1dGFuZG86ICdFeGVjdXRhbmRv4oCmJyxcclxuICAgIGNvbmNsdWlkYTogJ0NvbmNsdcOtZGEnLFxyXG4gICAgY2FuY2VsYWRhOiAnQ2FuY2VsYWRhJyxcclxuICAgIGV4cGlyYWRhOiAnRXhwaXJhZGEnLFxyXG4gICAgaW52YWxpZGFkYTogJ1ByZWNpc2EgZGUgbm92YSBjb25maXJtYcOnw6NvJyxcclxuICAgIGZhbGhhOiAnTsOjbyBjb25jbHXDrWRhJyxcclxuICAgIGluZGV0ZXJtaW5hZGE6ICdSZXN1bHRhZG8gYSB2ZXJpZmljYXInLFxyXG59O1xyXG5cclxuY29uc3QgREVTQ1JJQ09FUzogUGFydGlhbDxSZWNvcmQ8VWlueUVzdGFkb0FjYW8sIHN0cmluZz4+ID0ge1xyXG4gICAgY29uY2x1aWRhOiAnQSBhbHRlcmHDp8OjbyBmb2kgYXBsaWNhZGEuJyxcclxuICAgIGNhbmNlbGFkYTogJ05hZGEgZm9pIGFsdGVyYWRvLicsXHJcbiAgICBleHBpcmFkYTogJ08gcHJhem8gcGFyYSBjb25maXJtYXIgdGVybWlub3UuIE5hZGEgZm9pIGFsdGVyYWRvOyBwZcOnYSBkZSBub3ZvIHNlIGFpbmRhIHF1aXNlci4nLFxyXG4gICAgaW52YWxpZGFkYTogJ09zIGRhZG9zIG11ZGFyYW0gZGVzZGUgYSBwcm9wb3N0YS4gUGXDp2EgYSBhbHRlcmHDp8OjbyBkZSBub3ZvIHBhcmEgcmV2aXNhci4nLFxyXG4gICAgZmFsaGE6ICdBIGFsdGVyYcOnw6NvIG7Do28gZm9pIGFwbGljYWRhLicsXHJcbn07XHJcblxyXG4vKipcclxuICogQ2FyZCBkZSBhw6fDo28gcGVuZGVudGUuIEEgY29uZmlybWHDp8OjbyBzw7MgYWNvbnRlY2UgcGVsbyBjbGlxdWUgZW0gXCJDb25maXJtYXJcIjpcclxuICogbyBjYXJkIGVtaXRlIGFwZW5hcyBvIGlkIGRhIGHDp8OjbyBwZXJzaXN0aWRhLCBzZW0gYXJndW1lbnRvcy5cclxuICovXHJcbkBDb21wb25lbnQoe1xyXG4gICAgc2VsZWN0b3I6ICd1aS1hc3Npc3RhbnQtYWN0aW9uLWNhcmQnLFxyXG4gICAgdGVtcGxhdGVVcmw6ICcuL3VpLWFzc2lzdGFudC1hY3Rpb24tY2FyZC5jb21wb25lbnQuaHRtbCcsXHJcbiAgICBzdHlsZVVybHM6IFsnLi91aS1hc3Npc3RhbnQtYWN0aW9uLWNhcmQuY29tcG9uZW50LnNjc3MnXSxcclxuICAgIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBVaUFzc2lzdGFudEFjdGlvbkNhcmRDb21wb25lbnQgaW1wbGVtZW50cyBPbkNoYW5nZXMsIE9uRGVzdHJveSB7XHJcblxyXG4gICAgQElucHV0KCkgYWNhbzogVWlueUFjYW87XHJcblxyXG4gICAgQE91dHB1dCgpIGNvbmZpcm1hciA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xyXG4gICAgQE91dHB1dCgpIGNhbmNlbGFyID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XHJcbiAgICBAT3V0cHV0KCkgdmVyaWZpY2FyID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XHJcblxyXG4gICAgcHVibGljIGFnb3JhID0gRGF0ZS5ub3coKTtcclxuICAgIHByaXZhdGUgdGltZXI6IGFueTtcclxuXHJcbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWYsIHByaXZhdGUgem9uZTogTmdab25lKSB7IH1cclxuXHJcbiAgICBuZ09uQ2hhbmdlcygpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLmFnZW5kYXIoKTtcclxuICAgIH1cclxuXHJcbiAgICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcclxuICAgICAgICBjbGVhckludGVydmFsKHRoaXMudGltZXIpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBPIHNlcnZpZG9yIGRlY2lkZSBhIGV4cGlyYcOnw6NvOyBhcXVpIHPDsyBldml0YW1vcyBvZmVyZWNlciB1bSBjbGlxdWUgcXVlIGrDoSB2YWkgZmFsaGFyLiAqL1xyXG4gICAgZ2V0IGV4cGlyYWRhTG9jYWxtZW50ZSgpOiBib29sZWFuIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5hY2FvPy5lc3RhZG8gPT09ICdwZW5kZW50ZScgJiYgISF0aGlzLmFjYW8uZXhwaXJhRW0gJiYgdGhpcy5hY2FvLmV4cGlyYUVtLmdldFRpbWUoKSA8PSB0aGlzLmFnb3JhO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBlc3RhZG8oKTogVWlueUVzdGFkb0FjYW8ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmV4cGlyYWRhTG9jYWxtZW50ZSA/ICdleHBpcmFkYScgOiB0aGlzLmFjYW8/LmVzdGFkbztcclxuICAgIH1cclxuXHJcbiAgICBnZXQgcm90dWxvKCk6IHN0cmluZyB7XHJcbiAgICAgICAgcmV0dXJuIFJPVFVMT1NbdGhpcy5lc3RhZG9dID8/ICcnO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBkZXNjcmljYW8oKTogc3RyaW5nIHwgbnVsbCB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuYWNhbz8uYXZpc28gfHwgREVTQ1JJQ09FU1t0aGlzLmVzdGFkb10gfHwgbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgcG9kZURlY2lkaXIoKTogYm9vbGVhbiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZXN0YWRvID09PSAncGVuZGVudGUnICYmICF0aGlzLmFjYW8uZW52aWFuZG87XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IG1pbnV0b3NSZXN0YW50ZXMoKTogbnVtYmVyIHwgbnVsbCB7XHJcbiAgICAgICAgaWYgKHRoaXMuZXN0YWRvICE9PSAncGVuZGVudGUnIHx8ICF0aGlzLmFjYW8uZXhwaXJhRW0pIHJldHVybiBudWxsO1xyXG4gICAgICAgIHJldHVybiBNYXRoLm1heCgxLCBNYXRoLmNlaWwoKHRoaXMuYWNhby5leHBpcmFFbS5nZXRUaW1lKCkgLSB0aGlzLmFnb3JhKSAvIDYwMDAwKSk7XHJcbiAgICB9XHJcblxyXG4gICAgZWhDb3IodmFsb3I6IHN0cmluZyk6IGJvb2xlYW4ge1xyXG4gICAgICAgIHJldHVybiAvXiMoPzpbMC05YS1mXXszfXxbMC05YS1mXXs2fXxbMC05YS1mXXs4fSkkL2kudGVzdCh2YWxvcik7XHJcbiAgICB9XHJcblxyXG4gICAgYW9Db25maXJtYXIoKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKHRoaXMucG9kZURlY2lkaXIpIHRoaXMuY29uZmlybWFyLmVtaXQodGhpcy5hY2FvLmlkKTtcclxuICAgIH1cclxuXHJcbiAgICBhb0NhbmNlbGFyKCk6IHZvaWQge1xyXG4gICAgICAgIGlmICh0aGlzLnBvZGVEZWNpZGlyKSB0aGlzLmNhbmNlbGFyLmVtaXQodGhpcy5hY2FvLmlkKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGFnZW5kYXIoKTogdm9pZCB7XHJcbiAgICAgICAgY2xlYXJJbnRlcnZhbCh0aGlzLnRpbWVyKTtcclxuICAgICAgICB0aGlzLmFnb3JhID0gRGF0ZS5ub3coKTtcclxuICAgICAgICBpZiAodGhpcy5hY2FvPy5lc3RhZG8gIT09ICdwZW5kZW50ZScgfHwgIXRoaXMuYWNhby5leHBpcmFFbSkgcmV0dXJuO1xyXG4gICAgICAgIHRoaXMuem9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMudGltZXIgPSBzZXRJbnRlcnZhbCgoKSA9PiB0aGlzLnpvbmUucnVuKCgpID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuYWdvcmEgPSBEYXRlLm5vdygpO1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuZXhwaXJhZGFMb2NhbG1lbnRlKSBjbGVhckludGVydmFsKHRoaXMudGltZXIpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XHJcbiAgICAgICAgICAgIH0pLCAxNTAwMCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbn1cclxuIiwiPGFydGljbGUgY2xhc3M9XCJ1aW55LWFjYW9cIiBbbmdDbGFzc109XCIndWlueS1hY2FvLS0nICsgZXN0YWRvXCIgW2F0dHIuYXJpYS1idXN5XT1cImFjYW8uZW52aWFuZG8gPyAndHJ1ZScgOiBudWxsXCJcbiAgICBbYXR0ci5hcmlhLWxhYmVsbGVkYnldPVwiJ3VpbnktYWNhby0nICsgYWNhby5pZFwiPlxuICAgIDxoZWFkZXIgY2xhc3M9XCJ1aW55LWFjYW9fX3RvcG9cIj5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJ1aW55LWFjYW9fX3NlbG9cIj5cbiAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwiZXN0YWRvID09PSAnZXhlY3V0YW5kbycgfHwgYWNhby5lbnZpYW5kb1wiIGNsYXNzPVwidWlueS1hY2FvX19zcGlubmVyXCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+PC9zcGFuPlxuICAgICAgICAgICAgPHVpLWljb24gKm5nSWY9XCJlc3RhZG8gPT09ICdjb25jbHVpZGEnXCIgaWNvbj1cImNoZWNrX2NpcmNsZVwiIHNpemU9XCIxNlwiPjwvdWktaWNvbj5cbiAgICAgICAgICAgIDx1aS1pY29uICpuZ0lmPVwiZXN0YWRvID09PSAnZmFsaGEnIHx8IGVzdGFkbyA9PT0gJ2luZGV0ZXJtaW5hZGEnXCIgaWNvbj1cImVycm9yXCIgc2l6ZT1cIjE2XCI+PC91aS1pY29uPlxuICAgICAgICAgICAgPHVpLWljb24gKm5nSWY9XCJlc3RhZG8gPT09ICdwZW5kZW50ZScgJiYgIWFjYW8uZW52aWFuZG9cIiBpY29uPVwicGVuZGluZ19hY3Rpb25zXCIgc2l6ZT1cIjE2XCI+PC91aS1pY29uPlxuICAgICAgICAgICAge3sgcm90dWxvIH19XG4gICAgICAgIDwvc3Bhbj5cbiAgICAgICAgPHNwYW4gKm5nSWY9XCJtaW51dG9zUmVzdGFudGVzXCIgY2xhc3M9XCJ1aW55LWFjYW9fX3ByYXpvXCI+ZXhwaXJhIGVtIHt7IG1pbnV0b3NSZXN0YW50ZXMgfX0gbWluPC9zcGFuPlxuICAgIDwvaGVhZGVyPlxuXG4gICAgPHAgY2xhc3M9XCJ1aW55LWFjYW9fX3Jlc3Vtb1wiIFtpZF09XCIndWlueS1hY2FvLScgKyBhY2FvLmlkXCI+e3sgYWNhby5yZXN1bW8gfX08L3A+XG5cbiAgICA8ZGwgKm5nSWY9XCJhY2FvLmRldGFsaGVzPy5sZW5ndGhcIiBjbGFzcz1cInVpbnktYWNhb19fZGV0YWxoZXNcIj5cbiAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgZCBvZiBhY2FvLmRldGFsaGVzXCIgY2xhc3M9XCJ1aW55LWFjYW9fX2l0ZW1cIj5cbiAgICAgICAgICAgIDxkdD57eyBkLnJvdHVsbyB9fTwvZHQ+XG4gICAgICAgICAgICA8ZGQ+XG4gICAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJlaENvcihkLnZhbG9yKVwiIGNsYXNzPVwidWlueS1hY2FvX19jb3JcIiBbc3R5bGUuYmFja2dyb3VuZC1jb2xvcl09XCJkLnZhbG9yXCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+PC9zcGFuPlxuICAgICAgICAgICAgICAgIHt7IGQudmFsb3IgfX1cbiAgICAgICAgICAgIDwvZGQ+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGw+XG5cbiAgICA8cCAqbmdJZj1cImRlc2NyaWNhb1wiIGNsYXNzPVwidWlueS1hY2FvX19kZXNjcmljYW9cIiByb2xlPVwic3RhdHVzXCI+e3sgZGVzY3JpY2FvIH19PC9wPlxuXG4gICAgPGRpdiAqbmdJZj1cImVzdGFkbyA9PT0gJ3BlbmRlbnRlJ1wiIGNsYXNzPVwidWlueS1hY2FvX19ib3RvZXNcIj5cbiAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJ1aW55LWFjYW9fX2JvdGFvIHVpbnktYWNhb19fYm90YW8tLXNlY3VuZGFyaW9cIiBbZGlzYWJsZWRdPVwiIXBvZGVEZWNpZGlyXCIgKGNsaWNrKT1cImFvQ2FuY2VsYXIoKVwiPlxuICAgICAgICAgICAgQ2FuY2VsYXJcbiAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwidWlueS1hY2FvX19ib3RhbyB1aW55LWFjYW9fX2JvdGFvLS1wcmltYXJpb1wiIFtkaXNhYmxlZF09XCIhcG9kZURlY2lkaXJcIiAoY2xpY2spPVwiYW9Db25maXJtYXIoKVwiPlxuICAgICAgICAgICAgQ29uZmlybWFyXG4gICAgICAgIDwvYnV0dG9uPlxuICAgIDwvZGl2PlxuXG4gICAgPGRpdiAqbmdJZj1cImVzdGFkbyA9PT0gJ2luZGV0ZXJtaW5hZGEnXCIgY2xhc3M9XCJ1aW55LWFjYW9fX2JvdG9lc1wiPlxuICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInVpbnktYWNhb19fYm90YW8gdWlueS1hY2FvX19ib3Rhby0tc2VjdW5kYXJpb1wiIFtkaXNhYmxlZF09XCJhY2FvLmVudmlhbmRvXCIgKGNsaWNrKT1cInZlcmlmaWNhci5lbWl0KGFjYW8uaWQpXCI+XG4gICAgICAgICAgICBWZXJpZmljYXIgcmVzdWx0YWRvXG4gICAgICAgIDwvYnV0dG9uPlxuICAgIDwvZGl2PlxuPC9hcnRpY2xlPlxuIl19
@@ -0,0 +1,18 @@
1
+ import { ChangeDetectionStrategy, Component } from '@angular/core';
2
+ import { UiAssistantService } from '../../services/ui-assistant.service';
3
+ import * as i0 from "@angular/core";
4
+ import * as i1 from "../../services/ui-assistant.service";
5
+ import * as i2 from "@angular/common";
6
+ /** Botão que abre/fecha a Uiny. Só aparece quando a assistente está disponível. */
7
+ export class UiAssistantButtonComponent {
8
+ constructor(assistant) {
9
+ this.assistant = assistant;
10
+ }
11
+ }
12
+ UiAssistantButtonComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: UiAssistantButtonComponent, deps: [{ token: i1.UiAssistantService }], target: i0.ɵɵFactoryTarget.Component });
13
+ UiAssistantButtonComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: UiAssistantButtonComponent, selector: "ui-assistant-button", ngImport: i0, template: "<button *ngIf=\"assistant.disponivel$ | async\" #botao type=\"button\" class=\"uiny-trigger\"\n [class.is-open]=\"assistant.aberto$ | async\"\n [attr.aria-expanded]=\"(assistant.aberto$ | async) ? 'true' : 'false'\"\n aria-controls=\"uiny-painel\"\n [attr.aria-label]=\"(assistant.aberto$ | async) ? 'Fechar a Uiny, assistente da Uishop' : 'Abrir a Uiny, assistente da Uishop'\"\n [title]=\"(assistant.aberto$ | async) ? 'Fechar a Uiny' : 'Falar com a Uiny'\"\n (click)=\"assistant.alternar(botao)\">\n <svg class=\"uiny-trigger__mark\" viewBox=\"0 0 24 24\" width=\"18\" height=\"18\" aria-hidden=\"true\" focusable=\"false\">\n <path d=\"M12 2.5c.5 3.9 2.6 6.9 6.4 8.2.5.2.5.9 0 1.1-3.8 1.3-5.9 4.3-6.4 8.2-.1.6-.9.6-1 0-.5-3.9-2.6-6.9-6.4-8.2-.5-.2-.5-.9 0-1.1 3.8-1.3 5.9-4.3 6.4-8.2.1-.6.9-.6 1 0Z\" fill=\"currentColor\"/>\n <path d=\"M19 2.8c.2 1.3.9 2.2 2.1 2.6.2.1.2.3 0 .4-1.2.4-1.9 1.3-2.1 2.6 0 .2-.3.2-.3 0-.2-1.3-.9-2.2-2.1-2.6-.2-.1-.2-.3 0-.4 1.2-.4 1.9-1.3 2.1-2.6 0-.2.3-.2.3 0Z\" fill=\"currentColor\" opacity=\".7\"/>\n </svg>\n <span class=\"uiny-trigger__label\">Uiny</span>\n</button>\n", styles: [":host{display:inline-flex}.uiny-trigger{display:inline-flex;align-items:center;gap:6px;height:34px;padding:0 14px 0 10px;border:1px solid rgba(115,102,255,.28);border-radius:999px;background:rgba(115,102,255,.08);color:var(--theme-default, #7366ff);font-size:13px;font-weight:600;line-height:1;cursor:pointer;transition:background-color .15s ease,border-color .15s ease,color .15s ease}.uiny-trigger:hover{background:rgba(115,102,255,.14);border-color:#7366ff73}.uiny-trigger:focus-visible{outline:2px solid var(--theme-default, #7366ff);outline-offset:2px}.uiny-trigger.is-open{background:var(--theme-default, #7366ff);border-color:var(--theme-default, #7366ff);color:#fff}.uiny-trigger__mark{flex:0 0 auto}@media (max-width: 575.98px){.uiny-trigger{width:34px;padding:0;justify-content:center}.uiny-trigger__label{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}}@media (prefers-reduced-motion: reduce){.uiny-trigger{transition:none}}\n"], dependencies: [{ kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i2.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
14
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: UiAssistantButtonComponent, decorators: [{
15
+ type: Component,
16
+ args: [{ selector: 'ui-assistant-button', changeDetection: ChangeDetectionStrategy.OnPush, template: "<button *ngIf=\"assistant.disponivel$ | async\" #botao type=\"button\" class=\"uiny-trigger\"\n [class.is-open]=\"assistant.aberto$ | async\"\n [attr.aria-expanded]=\"(assistant.aberto$ | async) ? 'true' : 'false'\"\n aria-controls=\"uiny-painel\"\n [attr.aria-label]=\"(assistant.aberto$ | async) ? 'Fechar a Uiny, assistente da Uishop' : 'Abrir a Uiny, assistente da Uishop'\"\n [title]=\"(assistant.aberto$ | async) ? 'Fechar a Uiny' : 'Falar com a Uiny'\"\n (click)=\"assistant.alternar(botao)\">\n <svg class=\"uiny-trigger__mark\" viewBox=\"0 0 24 24\" width=\"18\" height=\"18\" aria-hidden=\"true\" focusable=\"false\">\n <path d=\"M12 2.5c.5 3.9 2.6 6.9 6.4 8.2.5.2.5.9 0 1.1-3.8 1.3-5.9 4.3-6.4 8.2-.1.6-.9.6-1 0-.5-3.9-2.6-6.9-6.4-8.2-.5-.2-.5-.9 0-1.1 3.8-1.3 5.9-4.3 6.4-8.2.1-.6.9-.6 1 0Z\" fill=\"currentColor\"/>\n <path d=\"M19 2.8c.2 1.3.9 2.2 2.1 2.6.2.1.2.3 0 .4-1.2.4-1.9 1.3-2.1 2.6 0 .2-.3.2-.3 0-.2-1.3-.9-2.2-2.1-2.6-.2-.1-.2-.3 0-.4 1.2-.4 1.9-1.3 2.1-2.6 0-.2.3-.2.3 0Z\" fill=\"currentColor\" opacity=\".7\"/>\n </svg>\n <span class=\"uiny-trigger__label\">Uiny</span>\n</button>\n", styles: [":host{display:inline-flex}.uiny-trigger{display:inline-flex;align-items:center;gap:6px;height:34px;padding:0 14px 0 10px;border:1px solid rgba(115,102,255,.28);border-radius:999px;background:rgba(115,102,255,.08);color:var(--theme-default, #7366ff);font-size:13px;font-weight:600;line-height:1;cursor:pointer;transition:background-color .15s ease,border-color .15s ease,color .15s ease}.uiny-trigger:hover{background:rgba(115,102,255,.14);border-color:#7366ff73}.uiny-trigger:focus-visible{outline:2px solid var(--theme-default, #7366ff);outline-offset:2px}.uiny-trigger.is-open{background:var(--theme-default, #7366ff);border-color:var(--theme-default, #7366ff);color:#fff}.uiny-trigger__mark{flex:0 0 auto}@media (max-width: 575.98px){.uiny-trigger{width:34px;padding:0;justify-content:center}.uiny-trigger__label{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}}@media (prefers-reduced-motion: reduce){.uiny-trigger{transition:none}}\n"] }]
17
+ }], ctorParameters: function () { return [{ type: i1.UiAssistantService }]; } });
18
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidWktYXNzaXN0YW50LWJ1dHRvbi5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy91aS1oZWFkZXIvc3JjL2xpYi9hc3Npc3RhbnQvY29tcG9uZW50cy9hc3Npc3RhbnQtYnV0dG9uL3VpLWFzc2lzdGFudC1idXR0b24uY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvdWktaGVhZGVyL3NyYy9saWIvYXNzaXN0YW50L2NvbXBvbmVudHMvYXNzaXN0YW50LWJ1dHRvbi91aS1hc3Npc3RhbnQtYnV0dG9uLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbkUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0scUNBQXFDLENBQUM7Ozs7QUFFekUsbUZBQW1GO0FBT25GLE1BQU0sT0FBTywwQkFBMEI7SUFDbkMsWUFBbUIsU0FBNkI7UUFBN0IsY0FBUyxHQUFULFNBQVMsQ0FBb0I7SUFBSSxDQUFDOzt3SEFENUMsMEJBQTBCOzRHQUExQiwwQkFBMEIsMkRDVnZDLGdvQ0FhQTs0RkRIYSwwQkFBMEI7a0JBTnRDLFNBQVM7K0JBQ0kscUJBQXFCLG1CQUdkLHVCQUF1QixDQUFDLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ29tcG9uZW50IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBVaUFzc2lzdGFudFNlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy91aS1hc3Npc3RhbnQuc2VydmljZSc7XG5cbi8qKiBCb3TDo28gcXVlIGFicmUvZmVjaGEgYSBVaW55LiBTw7MgYXBhcmVjZSBxdWFuZG8gYSBhc3Npc3RlbnRlIGVzdMOhIGRpc3BvbsOtdmVsLiAqL1xuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICd1aS1hc3Npc3RhbnQtYnV0dG9uJyxcbiAgICB0ZW1wbGF0ZVVybDogJy4vdWktYXNzaXN0YW50LWJ1dHRvbi5jb21wb25lbnQuaHRtbCcsXG4gICAgc3R5bGVVcmxzOiBbJy4vdWktYXNzaXN0YW50LWJ1dHRvbi5jb21wb25lbnQuc2NzcyddLFxuICAgIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoXG59KVxuZXhwb3J0IGNsYXNzIFVpQXNzaXN0YW50QnV0dG9uQ29tcG9uZW50IHtcbiAgICBjb25zdHJ1Y3RvcihwdWJsaWMgYXNzaXN0YW50OiBVaUFzc2lzdGFudFNlcnZpY2UpIHsgfVxufVxuIiwiPGJ1dHRvbiAqbmdJZj1cImFzc2lzdGFudC5kaXNwb25pdmVsJCB8IGFzeW5jXCIgI2JvdGFvIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInVpbnktdHJpZ2dlclwiXG4gICAgW2NsYXNzLmlzLW9wZW5dPVwiYXNzaXN0YW50LmFiZXJ0byQgfCBhc3luY1wiXG4gICAgW2F0dHIuYXJpYS1leHBhbmRlZF09XCIoYXNzaXN0YW50LmFiZXJ0byQgfCBhc3luYykgPyAndHJ1ZScgOiAnZmFsc2UnXCJcbiAgICBhcmlhLWNvbnRyb2xzPVwidWlueS1wYWluZWxcIlxuICAgIFthdHRyLmFyaWEtbGFiZWxdPVwiKGFzc2lzdGFudC5hYmVydG8kIHwgYXN5bmMpID8gJ0ZlY2hhciBhIFVpbnksIGFzc2lzdGVudGUgZGEgVWlzaG9wJyA6ICdBYnJpciBhIFVpbnksIGFzc2lzdGVudGUgZGEgVWlzaG9wJ1wiXG4gICAgW3RpdGxlXT1cIihhc3Npc3RhbnQuYWJlcnRvJCB8IGFzeW5jKSA/ICdGZWNoYXIgYSBVaW55JyA6ICdGYWxhciBjb20gYSBVaW55J1wiXG4gICAgKGNsaWNrKT1cImFzc2lzdGFudC5hbHRlcm5hcihib3RhbylcIj5cbiAgICA8c3ZnIGNsYXNzPVwidWlueS10cmlnZ2VyX19tYXJrXCIgdmlld0JveD1cIjAgMCAyNCAyNFwiIHdpZHRoPVwiMThcIiBoZWlnaHQ9XCIxOFwiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiIGZvY3VzYWJsZT1cImZhbHNlXCI+XG4gICAgICAgIDxwYXRoIGQ9XCJNMTIgMi41Yy41IDMuOSAyLjYgNi45IDYuNCA4LjIuNS4yLjUuOSAwIDEuMS0zLjggMS4zLTUuOSA0LjMtNi40IDguMi0uMS42LS45LjYtMSAwLS41LTMuOS0yLjYtNi45LTYuNC04LjItLjUtLjItLjUtLjkgMC0xLjEgMy44LTEuMyA1LjktNC4zIDYuNC04LjIuMS0uNi45LS42IDEgMFpcIiBmaWxsPVwiY3VycmVudENvbG9yXCIvPlxuICAgICAgICA8cGF0aCBkPVwiTTE5IDIuOGMuMiAxLjMuOSAyLjIgMi4xIDIuNi4yLjEuMi4zIDAgLjQtMS4yLjQtMS45IDEuMy0yLjEgMi42IDAgLjItLjMuMi0uMyAwLS4yLTEuMy0uOS0yLjItMi4xLTIuNi0uMi0uMS0uMi0uMyAwLS40IDEuMi0uNCAxLjktMS4zIDIuMS0yLjYgMC0uMi4zLS4yLjMgMFpcIiBmaWxsPVwiY3VycmVudENvbG9yXCIgb3BhY2l0eT1cIi43XCIvPlxuICAgIDwvc3ZnPlxuICAgIDxzcGFuIGNsYXNzPVwidWlueS10cmlnZ2VyX19sYWJlbFwiPlVpbnk8L3NwYW4+XG48L2J1dHRvbj5cbiJdfQ==
@@ -0,0 +1,79 @@
1
+ import { ChangeDetectionStrategy, Component, ElementRef, EventEmitter, Input, Output, ViewChild } from '@angular/core';
2
+ import { UINY_MENSAGEM_MAX_CARACTERES } from '../../uiny.config';
3
+ import * as i0 from "@angular/core";
4
+ import * as i1 from "@angular/common";
5
+ import * as i2 from "uitec-ng-icon";
6
+ const ALTURA_MAXIMA = 160;
7
+ /** Campo de mensagem: Enter envia, Shift+Enter quebra linha, cresce até ALTURA_MAXIMA. */
8
+ export class UiAssistantComposerComponent {
9
+ constructor() {
10
+ this.desabilitado = false;
11
+ this.enviando = false;
12
+ /** Explica por que o envio está bloqueado (sem internet, carregando...). */
13
+ this.motivo = null;
14
+ this.enviar = new EventEmitter();
15
+ this.max = UINY_MENSAGEM_MAX_CARACTERES;
16
+ this.texto = '';
17
+ }
18
+ get vazio() {
19
+ return !this.texto.trim();
20
+ }
21
+ get bloqueado() {
22
+ return this.desabilitado || this.enviando || this.vazio || this.texto.length > this.max;
23
+ }
24
+ get mostrarContador() {
25
+ return this.texto.length > this.max - 400;
26
+ }
27
+ focar() {
28
+ this.campo?.nativeElement.focus({ preventScroll: true });
29
+ }
30
+ limpar() {
31
+ this.texto = '';
32
+ if (this.campo) {
33
+ this.campo.nativeElement.value = '';
34
+ this.ajustarAltura();
35
+ }
36
+ }
37
+ aoDigitar(valor) {
38
+ this.texto = valor;
39
+ this.ajustarAltura();
40
+ }
41
+ aoTeclar(evento) {
42
+ if (evento.key !== 'Enter' || evento.shiftKey)
43
+ return;
44
+ // durante a composição (IME, acentos em alguns teclados) Enter confirma o caractere
45
+ if (evento.isComposing || evento.keyCode === 229)
46
+ return;
47
+ evento.preventDefault();
48
+ this.submeter();
49
+ }
50
+ submeter() {
51
+ if (this.bloqueado)
52
+ return;
53
+ this.enviar.emit(this.texto.trim());
54
+ }
55
+ ajustarAltura() {
56
+ const el = this.campo.nativeElement;
57
+ el.style.height = 'auto';
58
+ el.style.height = Math.min(el.scrollHeight, ALTURA_MAXIMA) + 'px';
59
+ el.style.overflowY = el.scrollHeight > ALTURA_MAXIMA ? 'auto' : 'hidden';
60
+ }
61
+ }
62
+ UiAssistantComposerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: UiAssistantComposerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
63
+ UiAssistantComposerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: UiAssistantComposerComponent, selector: "ui-assistant-composer", inputs: { desabilitado: "desabilitado", enviando: "enviando", motivo: "motivo" }, outputs: { enviar: "enviar" }, viewQueries: [{ propertyName: "campo", first: true, predicate: ["campo"], descendants: true, static: true }], ngImport: i0, template: "<form class=\"uiny-composer\" (submit)=\"$event.preventDefault(); submeter()\">\n <label for=\"uiny-campo\" class=\"uiny-sr\">Mensagem para a Uiny</label>\n <div class=\"uiny-composer__caixa\" [class.is-desabilitado]=\"desabilitado\">\n <textarea #campo id=\"uiny-campo\" class=\"uiny-composer__campo\" rows=\"1\"\n placeholder=\"Pergunte algo para a Uiny\"\n [value]=\"texto\"\n [attr.aria-describedby]=\"motivo ? 'uiny-campo-motivo' : 'uiny-campo-dica'\"\n [attr.maxlength]=\"max + 200\"\n (input)=\"aoDigitar(campo.value)\"\n (keydown)=\"aoTeclar($event)\"></textarea>\n\n <button type=\"submit\" class=\"uiny-composer__enviar\" [disabled]=\"bloqueado\"\n [attr.aria-label]=\"enviando ? 'Aguardando a resposta da Uiny' : 'Enviar mensagem'\"\n [title]=\"enviando ? 'Aguardando a resposta' : 'Enviar (Enter)'\">\n <span *ngIf=\"enviando\" class=\"uiny-composer__spinner\" aria-hidden=\"true\"></span>\n <ui-icon *ngIf=\"!enviando\" icon=\"arrow_upward\" size=\"20\"></ui-icon>\n </button>\n </div>\n\n <div class=\"uiny-composer__rodape\">\n <span *ngIf=\"motivo\" id=\"uiny-campo-motivo\" class=\"uiny-composer__motivo\">{{ motivo }}</span>\n <span *ngIf=\"!motivo\" id=\"uiny-campo-dica\">Enter envia \u00B7 Shift+Enter quebra a linha</span>\n <span *ngIf=\"mostrarContador\" class=\"uiny-composer__contador\" [class.is-excedido]=\"texto.length > max\">\n {{ texto.length }}/{{ max }}\n </span>\n </div>\n</form>\n", styles: [":host{display:block;padding:10px 12px 12px;border-top:1px solid var(--uiny-borda, #ececf3);background:var(--uiny-fundo, #fff)}.uiny-composer__caixa{display:flex;align-items:flex-end;gap:8px;padding:6px 6px 6px 12px;border:1px solid var(--uiny-borda, #ececf3);border-radius:14px;background:var(--uiny-fundo-suave, #f7f7fb);transition:border-color .15s ease,box-shadow .15s ease}.uiny-composer__caixa:focus-within{border-color:var(--uiny-primaria, #7366ff);box-shadow:0 0 0 3px #7366ff26}.uiny-composer__caixa.is-desabilitado{opacity:.75}.uiny-composer__campo{flex:1 1 auto;min-width:0;max-height:160px;padding:6px 0;border:0;outline:0;background:transparent;color:var(--uiny-texto, #2b2b2b);font:inherit;font-size:14px;line-height:1.45;resize:none;overflow-y:hidden}.uiny-composer__campo::placeholder{color:var(--uiny-texto-suave, #6b6b80)}.uiny-composer__enviar{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;width:34px;height:34px;border:0;border-radius:10px;background:var(--uiny-primaria, #7366ff);color:#fff;cursor:pointer;transition:opacity .15s ease}.uiny-composer__enviar:disabled{opacity:.35;cursor:not-allowed}.uiny-composer__enviar:focus-visible{outline:2px solid var(--uiny-primaria, #7366ff);outline-offset:2px}.uiny-composer__spinner{width:16px;height:16px;border:2px solid rgba(255,255,255,.4);border-top-color:#fff;border-radius:50%;animation:uiny-girar .8s linear infinite}.uiny-composer__rodape{display:flex;justify-content:space-between;gap:8px;margin-top:6px;padding:0 4px;font-size:11px;color:var(--uiny-texto-suave, #6b6b80)}.uiny-composer__motivo{color:var(--uiny-offline-texto, #8a5300)}.uiny-composer__contador.is-excedido{color:var(--uiny-erro, #d9364f);font-weight:600}.uiny-sr{position:absolute;width:1px;height:1px;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}@keyframes uiny-girar{to{transform:rotate(360deg)}}@media (prefers-reduced-motion: reduce){.uiny-composer__caixa,.uiny-composer__enviar{transition:none}.uiny-composer__spinner{animation-duration:2.4s}}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.UiIconComponent, selector: "ui-icon", inputs: ["icon", "size", "class"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
64
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: UiAssistantComposerComponent, decorators: [{
65
+ type: Component,
66
+ args: [{ selector: 'ui-assistant-composer', changeDetection: ChangeDetectionStrategy.OnPush, template: "<form class=\"uiny-composer\" (submit)=\"$event.preventDefault(); submeter()\">\n <label for=\"uiny-campo\" class=\"uiny-sr\">Mensagem para a Uiny</label>\n <div class=\"uiny-composer__caixa\" [class.is-desabilitado]=\"desabilitado\">\n <textarea #campo id=\"uiny-campo\" class=\"uiny-composer__campo\" rows=\"1\"\n placeholder=\"Pergunte algo para a Uiny\"\n [value]=\"texto\"\n [attr.aria-describedby]=\"motivo ? 'uiny-campo-motivo' : 'uiny-campo-dica'\"\n [attr.maxlength]=\"max + 200\"\n (input)=\"aoDigitar(campo.value)\"\n (keydown)=\"aoTeclar($event)\"></textarea>\n\n <button type=\"submit\" class=\"uiny-composer__enviar\" [disabled]=\"bloqueado\"\n [attr.aria-label]=\"enviando ? 'Aguardando a resposta da Uiny' : 'Enviar mensagem'\"\n [title]=\"enviando ? 'Aguardando a resposta' : 'Enviar (Enter)'\">\n <span *ngIf=\"enviando\" class=\"uiny-composer__spinner\" aria-hidden=\"true\"></span>\n <ui-icon *ngIf=\"!enviando\" icon=\"arrow_upward\" size=\"20\"></ui-icon>\n </button>\n </div>\n\n <div class=\"uiny-composer__rodape\">\n <span *ngIf=\"motivo\" id=\"uiny-campo-motivo\" class=\"uiny-composer__motivo\">{{ motivo }}</span>\n <span *ngIf=\"!motivo\" id=\"uiny-campo-dica\">Enter envia \u00B7 Shift+Enter quebra a linha</span>\n <span *ngIf=\"mostrarContador\" class=\"uiny-composer__contador\" [class.is-excedido]=\"texto.length > max\">\n {{ texto.length }}/{{ max }}\n </span>\n </div>\n</form>\n", styles: [":host{display:block;padding:10px 12px 12px;border-top:1px solid var(--uiny-borda, #ececf3);background:var(--uiny-fundo, #fff)}.uiny-composer__caixa{display:flex;align-items:flex-end;gap:8px;padding:6px 6px 6px 12px;border:1px solid var(--uiny-borda, #ececf3);border-radius:14px;background:var(--uiny-fundo-suave, #f7f7fb);transition:border-color .15s ease,box-shadow .15s ease}.uiny-composer__caixa:focus-within{border-color:var(--uiny-primaria, #7366ff);box-shadow:0 0 0 3px #7366ff26}.uiny-composer__caixa.is-desabilitado{opacity:.75}.uiny-composer__campo{flex:1 1 auto;min-width:0;max-height:160px;padding:6px 0;border:0;outline:0;background:transparent;color:var(--uiny-texto, #2b2b2b);font:inherit;font-size:14px;line-height:1.45;resize:none;overflow-y:hidden}.uiny-composer__campo::placeholder{color:var(--uiny-texto-suave, #6b6b80)}.uiny-composer__enviar{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;width:34px;height:34px;border:0;border-radius:10px;background:var(--uiny-primaria, #7366ff);color:#fff;cursor:pointer;transition:opacity .15s ease}.uiny-composer__enviar:disabled{opacity:.35;cursor:not-allowed}.uiny-composer__enviar:focus-visible{outline:2px solid var(--uiny-primaria, #7366ff);outline-offset:2px}.uiny-composer__spinner{width:16px;height:16px;border:2px solid rgba(255,255,255,.4);border-top-color:#fff;border-radius:50%;animation:uiny-girar .8s linear infinite}.uiny-composer__rodape{display:flex;justify-content:space-between;gap:8px;margin-top:6px;padding:0 4px;font-size:11px;color:var(--uiny-texto-suave, #6b6b80)}.uiny-composer__motivo{color:var(--uiny-offline-texto, #8a5300)}.uiny-composer__contador.is-excedido{color:var(--uiny-erro, #d9364f);font-weight:600}.uiny-sr{position:absolute;width:1px;height:1px;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}@keyframes uiny-girar{to{transform:rotate(360deg)}}@media (prefers-reduced-motion: reduce){.uiny-composer__caixa,.uiny-composer__enviar{transition:none}.uiny-composer__spinner{animation-duration:2.4s}}\n"] }]
67
+ }], propDecorators: { desabilitado: [{
68
+ type: Input
69
+ }], enviando: [{
70
+ type: Input
71
+ }], motivo: [{
72
+ type: Input
73
+ }], enviar: [{
74
+ type: Output
75
+ }], campo: [{
76
+ type: ViewChild,
77
+ args: ['campo', { static: true }]
78
+ }] } });
79
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidWktYXNzaXN0YW50LWNvbXBvc2VyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3VpLWhlYWRlci9zcmMvbGliL2Fzc2lzdGFudC9jb21wb25lbnRzL2Fzc2lzdGFudC1jb21wb3Nlci91aS1hc3Npc3RhbnQtY29tcG9zZXIuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvdWktaGVhZGVyL3NyYy9saWIvYXNzaXN0YW50L2NvbXBvbmVudHMvYXNzaXN0YW50LWNvbXBvc2VyL3VpLWFzc2lzdGFudC1jb21wb3Nlci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDdkgsT0FBTyxFQUFFLDRCQUE0QixFQUFFLE1BQU0sbUJBQW1CLENBQUM7Ozs7QUFFakUsTUFBTSxhQUFhLEdBQUcsR0FBRyxDQUFDO0FBRTFCLDBGQUEwRjtBQU8xRixNQUFNLE9BQU8sNEJBQTRCO0lBTnpDO1FBUWEsaUJBQVksR0FBRyxLQUFLLENBQUM7UUFDckIsYUFBUSxHQUFHLEtBQUssQ0FBQztRQUMxQiw0RUFBNEU7UUFDbkUsV0FBTSxHQUFrQixJQUFJLENBQUM7UUFFNUIsV0FBTSxHQUFHLElBQUksWUFBWSxFQUFVLENBQUM7UUFJOUIsUUFBRyxHQUFHLDRCQUE0QixDQUFDO1FBQzVDLFVBQUssR0FBRyxFQUFFLENBQUM7S0FrRHJCO0lBaERHLElBQUksS0FBSztRQUNMLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDO0lBQzlCLENBQUM7SUFFRCxJQUFJLFNBQVM7UUFDVCxPQUFPLElBQUksQ0FBQyxZQUFZLElBQUksSUFBSSxDQUFDLFFBQVEsSUFBSSxJQUFJLENBQUMsS0FBSyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUM7SUFDNUYsQ0FBQztJQUVELElBQUksZUFBZTtRQUNmLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUM7SUFDOUMsQ0FBQztJQUVELEtBQUs7UUFDRCxJQUFJLENBQUMsS0FBSyxFQUFFLGFBQWEsQ0FBQyxLQUFLLENBQUMsRUFBRSxhQUFhLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUM3RCxDQUFDO0lBRUQsTUFBTTtRQUNGLElBQUksQ0FBQyxLQUFLLEdBQUcsRUFBRSxDQUFDO1FBQ2hCLElBQUksSUFBSSxDQUFDLEtBQUssRUFBRTtZQUNaLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLEtBQUssR0FBRyxFQUFFLENBQUM7WUFDcEMsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1NBQ3hCO0lBQ0wsQ0FBQztJQUVELFNBQVMsQ0FBQyxLQUFhO1FBQ25CLElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO1FBQ25CLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztJQUN6QixDQUFDO0lBRUQsUUFBUSxDQUFDLE1BQXFCO1FBQzFCLElBQUksTUFBTSxDQUFDLEdBQUcsS0FBSyxPQUFPLElBQUksTUFBTSxDQUFDLFFBQVE7WUFBRSxPQUFPO1FBQ3RELG9GQUFvRjtRQUNwRixJQUFJLE1BQU0sQ0FBQyxXQUFXLElBQUksTUFBTSxDQUFDLE9BQU8sS0FBSyxHQUFHO1lBQUUsT0FBTztRQUN6RCxNQUFNLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDeEIsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO0lBQ3BCLENBQUM7SUFFRCxRQUFRO1FBQ0osSUFBSSxJQUFJLENBQUMsU0FBUztZQUFFLE9BQU87UUFDM0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQ3hDLENBQUM7SUFFTyxhQUFhO1FBQ2pCLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDO1FBQ3BDLEVBQUUsQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztRQUN6QixFQUFFLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxZQUFZLEVBQUUsYUFBYSxDQUFDLEdBQUcsSUFBSSxDQUFDO1FBQ2xFLEVBQUUsQ0FBQyxLQUFLLENBQUMsU0FBUyxHQUFHLEVBQUUsQ0FBQyxZQUFZLEdBQUcsYUFBYSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQztJQUM3RSxDQUFDOzswSEE3RFEsNEJBQTRCOzhHQUE1Qiw0QkFBNEIsNFJDWnpDLG9rREEyQkE7NEZEZmEsNEJBQTRCO2tCQU54QyxTQUFTOytCQUNJLHVCQUF1QixtQkFHaEIsdUJBQXVCLENBQUMsTUFBTTs4QkFJdEMsWUFBWTtzQkFBcEIsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUVHLE1BQU07c0JBQWQsS0FBSztnQkFFSSxNQUFNO3NCQUFmLE1BQU07Z0JBRStCLEtBQUs7c0JBQTFDLFNBQVM7dUJBQUMsT0FBTyxFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDb21wb25lbnQsIEVsZW1lbnRSZWYsIEV2ZW50RW1pdHRlciwgSW5wdXQsIE91dHB1dCwgVmlld0NoaWxkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBVSU5ZX01FTlNBR0VNX01BWF9DQVJBQ1RFUkVTIH0gZnJvbSAnLi4vLi4vdWlueS5jb25maWcnO1xuXG5jb25zdCBBTFRVUkFfTUFYSU1BID0gMTYwO1xuXG4vKiogQ2FtcG8gZGUgbWVuc2FnZW06IEVudGVyIGVudmlhLCBTaGlmdCtFbnRlciBxdWVicmEgbGluaGEsIGNyZXNjZSBhdMOpIEFMVFVSQV9NQVhJTUEuICovXG5AQ29tcG9uZW50KHtcbiAgICBzZWxlY3RvcjogJ3VpLWFzc2lzdGFudC1jb21wb3NlcicsXG4gICAgdGVtcGxhdGVVcmw6ICcuL3VpLWFzc2lzdGFudC1jb21wb3Nlci5jb21wb25lbnQuaHRtbCcsXG4gICAgc3R5bGVVcmxzOiBbJy4vdWktYXNzaXN0YW50LWNvbXBvc2VyLmNvbXBvbmVudC5zY3NzJ10sXG4gICAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2hcbn0pXG5leHBvcnQgY2xhc3MgVWlBc3Npc3RhbnRDb21wb3NlckNvbXBvbmVudCB7XG5cbiAgICBASW5wdXQoKSBkZXNhYmlsaXRhZG8gPSBmYWxzZTtcbiAgICBASW5wdXQoKSBlbnZpYW5kbyA9IGZhbHNlO1xuICAgIC8qKiBFeHBsaWNhIHBvciBxdWUgbyBlbnZpbyBlc3TDoSBibG9xdWVhZG8gKHNlbSBpbnRlcm5ldCwgY2FycmVnYW5kby4uLikuICovXG4gICAgQElucHV0KCkgbW90aXZvOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcblxuICAgIEBPdXRwdXQoKSBlbnZpYXIgPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKTtcblxuICAgIEBWaWV3Q2hpbGQoJ2NhbXBvJywgeyBzdGF0aWM6IHRydWUgfSkgY2FtcG86IEVsZW1lbnRSZWY8SFRNTFRleHRBcmVhRWxlbWVudD47XG5cbiAgICBwdWJsaWMgcmVhZG9ubHkgbWF4ID0gVUlOWV9NRU5TQUdFTV9NQVhfQ0FSQUNURVJFUztcbiAgICBwdWJsaWMgdGV4dG8gPSAnJztcblxuICAgIGdldCB2YXppbygpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuICF0aGlzLnRleHRvLnRyaW0oKTtcbiAgICB9XG5cbiAgICBnZXQgYmxvcXVlYWRvKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5kZXNhYmlsaXRhZG8gfHwgdGhpcy5lbnZpYW5kbyB8fCB0aGlzLnZhemlvIHx8IHRoaXMudGV4dG8ubGVuZ3RoID4gdGhpcy5tYXg7XG4gICAgfVxuXG4gICAgZ2V0IG1vc3RyYXJDb250YWRvcigpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudGV4dG8ubGVuZ3RoID4gdGhpcy5tYXggLSA0MDA7XG4gICAgfVxuXG4gICAgZm9jYXIoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuY2FtcG8/Lm5hdGl2ZUVsZW1lbnQuZm9jdXMoeyBwcmV2ZW50U2Nyb2xsOiB0cnVlIH0pO1xuICAgIH1cblxuICAgIGxpbXBhcigpOiB2b2lkIHtcbiAgICAgICAgdGhpcy50ZXh0byA9ICcnO1xuICAgICAgICBpZiAodGhpcy5jYW1wbykge1xuICAgICAgICAgICAgdGhpcy5jYW1wby5uYXRpdmVFbGVtZW50LnZhbHVlID0gJyc7XG4gICAgICAgICAgICB0aGlzLmFqdXN0YXJBbHR1cmEoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGFvRGlnaXRhcih2YWxvcjogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIHRoaXMudGV4dG8gPSB2YWxvcjtcbiAgICAgICAgdGhpcy5hanVzdGFyQWx0dXJhKCk7XG4gICAgfVxuXG4gICAgYW9UZWNsYXIoZXZlbnRvOiBLZXlib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgICAgIGlmIChldmVudG8ua2V5ICE9PSAnRW50ZXInIHx8IGV2ZW50by5zaGlmdEtleSkgcmV0dXJuO1xuICAgICAgICAvLyBkdXJhbnRlIGEgY29tcG9zacOnw6NvIChJTUUsIGFjZW50b3MgZW0gYWxndW5zIHRlY2xhZG9zKSBFbnRlciBjb25maXJtYSBvIGNhcmFjdGVyZVxuICAgICAgICBpZiAoZXZlbnRvLmlzQ29tcG9zaW5nIHx8IGV2ZW50by5rZXlDb2RlID09PSAyMjkpIHJldHVybjtcbiAgICAgICAgZXZlbnRvLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIHRoaXMuc3VibWV0ZXIoKTtcbiAgICB9XG5cbiAgICBzdWJtZXRlcigpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuYmxvcXVlYWRvKSByZXR1cm47XG4gICAgICAgIHRoaXMuZW52aWFyLmVtaXQodGhpcy50ZXh0by50cmltKCkpO1xuICAgIH1cblxuICAgIHByaXZhdGUgYWp1c3RhckFsdHVyYSgpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgZWwgPSB0aGlzLmNhbXBvLm5hdGl2ZUVsZW1lbnQ7XG4gICAgICAgIGVsLnN0eWxlLmhlaWdodCA9ICdhdXRvJztcbiAgICAgICAgZWwuc3R5bGUuaGVpZ2h0ID0gTWF0aC5taW4oZWwuc2Nyb2xsSGVpZ2h0LCBBTFRVUkFfTUFYSU1BKSArICdweCc7XG4gICAgICAgIGVsLnN0eWxlLm92ZXJmbG93WSA9IGVsLnNjcm9sbEhlaWdodCA+IEFMVFVSQV9NQVhJTUEgPyAnYXV0bycgOiAnaGlkZGVuJztcbiAgICB9XG59XG4iLCI8Zm9ybSBjbGFzcz1cInVpbnktY29tcG9zZXJcIiAoc3VibWl0KT1cIiRldmVudC5wcmV2ZW50RGVmYXVsdCgpOyBzdWJtZXRlcigpXCI+XG4gICAgPGxhYmVsIGZvcj1cInVpbnktY2FtcG9cIiBjbGFzcz1cInVpbnktc3JcIj5NZW5zYWdlbSBwYXJhIGEgVWlueTwvbGFiZWw+XG4gICAgPGRpdiBjbGFzcz1cInVpbnktY29tcG9zZXJfX2NhaXhhXCIgW2NsYXNzLmlzLWRlc2FiaWxpdGFkb109XCJkZXNhYmlsaXRhZG9cIj5cbiAgICAgICAgPHRleHRhcmVhICNjYW1wbyBpZD1cInVpbnktY2FtcG9cIiBjbGFzcz1cInVpbnktY29tcG9zZXJfX2NhbXBvXCIgcm93cz1cIjFcIlxuICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJQZXJndW50ZSBhbGdvIHBhcmEgYSBVaW55XCJcbiAgICAgICAgICAgIFt2YWx1ZV09XCJ0ZXh0b1wiXG4gICAgICAgICAgICBbYXR0ci5hcmlhLWRlc2NyaWJlZGJ5XT1cIm1vdGl2byA/ICd1aW55LWNhbXBvLW1vdGl2bycgOiAndWlueS1jYW1wby1kaWNhJ1wiXG4gICAgICAgICAgICBbYXR0ci5tYXhsZW5ndGhdPVwibWF4ICsgMjAwXCJcbiAgICAgICAgICAgIChpbnB1dCk9XCJhb0RpZ2l0YXIoY2FtcG8udmFsdWUpXCJcbiAgICAgICAgICAgIChrZXlkb3duKT1cImFvVGVjbGFyKCRldmVudClcIj48L3RleHRhcmVhPlxuXG4gICAgICAgIDxidXR0b24gdHlwZT1cInN1Ym1pdFwiIGNsYXNzPVwidWlueS1jb21wb3Nlcl9fZW52aWFyXCIgW2Rpc2FibGVkXT1cImJsb3F1ZWFkb1wiXG4gICAgICAgICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cImVudmlhbmRvID8gJ0FndWFyZGFuZG8gYSByZXNwb3N0YSBkYSBVaW55JyA6ICdFbnZpYXIgbWVuc2FnZW0nXCJcbiAgICAgICAgICAgIFt0aXRsZV09XCJlbnZpYW5kbyA/ICdBZ3VhcmRhbmRvIGEgcmVzcG9zdGEnIDogJ0VudmlhciAoRW50ZXIpJ1wiPlxuICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJlbnZpYW5kb1wiIGNsYXNzPVwidWlueS1jb21wb3Nlcl9fc3Bpbm5lclwiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPjwvc3Bhbj5cbiAgICAgICAgICAgIDx1aS1pY29uICpuZ0lmPVwiIWVudmlhbmRvXCIgaWNvbj1cImFycm93X3Vwd2FyZFwiIHNpemU9XCIyMFwiPjwvdWktaWNvbj5cbiAgICAgICAgPC9idXR0b24+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwidWlueS1jb21wb3Nlcl9fcm9kYXBlXCI+XG4gICAgICAgIDxzcGFuICpuZ0lmPVwibW90aXZvXCIgaWQ9XCJ1aW55LWNhbXBvLW1vdGl2b1wiIGNsYXNzPVwidWlueS1jb21wb3Nlcl9fbW90aXZvXCI+e3sgbW90aXZvIH19PC9zcGFuPlxuICAgICAgICA8c3BhbiAqbmdJZj1cIiFtb3Rpdm9cIiBpZD1cInVpbnktY2FtcG8tZGljYVwiPkVudGVyIGVudmlhIMK3IFNoaWZ0K0VudGVyIHF1ZWJyYSBhIGxpbmhhPC9zcGFuPlxuICAgICAgICA8c3BhbiAqbmdJZj1cIm1vc3RyYXJDb250YWRvclwiIGNsYXNzPVwidWlueS1jb21wb3Nlcl9fY29udGFkb3JcIiBbY2xhc3MuaXMtZXhjZWRpZG9dPVwidGV4dG8ubGVuZ3RoID4gbWF4XCI+XG4gICAgICAgICAgICB7eyB0ZXh0by5sZW5ndGggfX0ve3sgbWF4IH19XG4gICAgICAgIDwvc3Bhbj5cbiAgICA8L2Rpdj5cbjwvZm9ybT5cbiJdfQ==