login-tsi 0.0.7 → 0.0.9

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.
@@ -1,6 +1,6 @@
1
1
  import { NgClass } from '@angular/common';
2
2
  import * as i0 from '@angular/core';
3
- import { signal, Injectable, inject, input, output, Component, computed, model, HostListener } from '@angular/core';
3
+ import { InjectionToken, signal, Injectable, inject, input, output, Component, computed, viewChild, DestroyRef, effect, untracked, afterRenderEffect, model, HostListener } from '@angular/core';
4
4
  import * as i1 from '@angular/forms';
5
5
  import { ReactiveFormsModule, FormBuilder, Validators, FormsModule } from '@angular/forms';
6
6
  import { trigger, transition, style, animate } from '@angular/animations';
@@ -15,6 +15,33 @@ const fadeInOut = trigger('fadeInOut', [
15
15
  ]),
16
16
  ]);
17
17
 
18
+ const AUTH_API = new InjectionToken('AUTH_API');
19
+ function provideAuthApi(servicio) {
20
+ return { provide: AUTH_API, useExisting: servicio };
21
+ }
22
+
23
+ const textoValido = (valor) => typeof valor == 'string' && !!valor.trim();
24
+ const mensajeDe = (err, defecto) => {
25
+ if (textoValido(err))
26
+ return err;
27
+ if (err && typeof err == 'object' && 'error' in err) {
28
+ const body = err.error;
29
+ if (textoValido(body))
30
+ return body;
31
+ const mensaje = body?.message;
32
+ return textoValido(mensaje) ? mensaje : defecto;
33
+ }
34
+ const mensaje = err?.message;
35
+ return textoValido(mensaje) && !/^\d+$/.test(mensaje) ? mensaje : defecto;
36
+ };
37
+
38
+ function isMfaChallenge(body) {
39
+ return body?.mfaRequerido === true && !!body?.preauthToken;
40
+ }
41
+ function isPushPendiente(body) {
42
+ return body?.result === 'waiting' || body?.result === 'deny' || body?.result === 'expired';
43
+ }
44
+
18
45
  class PwaInstallService {
19
46
  isAndroid = /Android/i.test(navigator.userAgent);
20
47
  isIOS = /iPad|iPhone|iPod/i.test(navigator.userAgent);
@@ -107,11 +134,198 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImpo
107
134
  args: [{ selector: 'app-refresh-floating', template: "<div class=\"refresh-wrap\">\r\n\r\n @if (showGuide()) {\r\n <div class=\"refresh-guide\">\r\n <button class=\"refresh-guide__close\" (click)=\"toggleGuide()\">\r\n <i class=\"fas fa-xmark\"></i>\r\n </button>\r\n\r\n <p class=\"refresh-guide__title\">Actualizar aplicaci\u00F3n</p>\r\n\r\n <button class=\"refresh-guide__option\" (click)=\"actualizar()\">\r\n <i class=\"fas fa-rotate\"></i> Actualizar\r\n </button>\r\n\r\n <button class=\"refresh-guide__option refresh-guide__option--force\" (click)=\"actualizarTotal()\">\r\n <i class=\"fas fa-rotate-right\"></i> Forzar actualizaci\u00F3n\r\n </button>\r\n </div>\r\n }\r\n\r\n <button class=\"refresh-chip\" (click)=\"toggleGuide()\" title=\"Actualizar\">\r\n <i class=\"fas fa-rotate\"></i>\r\n </button>\r\n\r\n</div>\r\n", styles: [".refresh-wrap{position:fixed;bottom:24px;right:24px;z-index:9000;display:flex;flex-direction:column;align-items:flex-end;gap:10px}.refresh-chip{display:flex;align-items:center;justify-content:center;width:40px;height:40px;padding:0;border-radius:50%;border:1px solid rgba(255,255,255,.13);background:#0d6efd;backdrop-filter:blur(12px);color:#fff;font-size:15px;cursor:pointer;box-shadow:0 4px 18px #0006;transition:transform .15s ease,box-shadow .15s ease,background .15s ease;animation:refreshIn .3s cubic-bezier(.25,.46,.45,.94) both}.refresh-chip:hover{transform:translateY(-2px);background:#0b5ed7;box-shadow:0 6px 22px #0d6efd80}.refresh-chip:active{transform:translateY(0)}.refresh-guide{position:relative;width:240px;background:#08122af5;backdrop-filter:blur(16px);border:1px solid rgba(255,255,255,.1);border-radius:16px;padding:18px 18px 20px;box-shadow:0 8px 32px #00000080;animation:refreshIn .25s cubic-bezier(.25,.46,.45,.94) both}.refresh-guide__close{position:absolute;top:12px;right:12px;background:#ffffff14;border:none;border-radius:50%;width:26px;height:26px;display:flex;align-items:center;justify-content:center;color:#fff9;cursor:pointer;transition:background .15s;font-size:12px}.refresh-guide__close:hover{background:#ffffff26}.refresh-guide__title{font-size:13.5px;font-weight:600;color:#fff;margin:0 24px 14px 0}.refresh-guide__option{display:flex;align-items:center;justify-content:center;gap:7px;width:100%;margin-top:8px;padding:9px;border-radius:10px;border:none;background:#ffffff14;color:#fff;font-size:12.5px;font-weight:500;white-space:nowrap;cursor:pointer;transition:background .15s}.refresh-guide__option:hover{background:#ffffff26}.refresh-guide__option--force{background:#c50048d9}.refresh-guide__option--force:hover{background:#c50048}@keyframes refreshIn{0%{transform:translateY(12px);opacity:0}to{transform:translateY(0);opacity:1}}\n"] }]
108
135
  }] });
109
136
 
137
+ const INTERVALO_ESTADO_MS = 2000;
138
+ const MAXIMO_ESPERA_MS = 120000;
139
+ const CAMPOS_CODIGO = {
140
+ totp: {
141
+ label: 'Código de verificación', placeholder: '000000', icon: 'fa-mobile-alt', inputmode: 'numeric',
142
+ patron: /^\d{6}$/,
143
+ descri: 'Ingresa el código de 6 dígitos que muestra tu app de autenticación.',
144
+ mensajeInvalido: 'Ingresa el código de 6 dígitos de tu app.',
145
+ mensajeIncorrecto: 'Código incorrecto. Verifica la hora de tu dispositivo.'
146
+ },
147
+ respaldo: {
148
+ label: 'Código de respaldo', placeholder: 'XXXX-XXXX', icon: 'fa-key', inputmode: 'text',
149
+ patron: /^[A-Z0-9]{4}-[A-Z0-9]{4}$/,
150
+ descri: 'Ingresa uno de tus códigos de respaldo. Cada código sirve una sola vez.',
151
+ mensajeInvalido: 'Ingresa un código de respaldo válido (XXXX-XXXX).',
152
+ mensajeIncorrecto: 'Código de respaldo incorrecto o ya utilizado.'
153
+ }
154
+ };
155
+ const limpiarCodigo = (valor, tipo) => {
156
+ if (tipo == 'totp')
157
+ return valor.replace(/\D/g, '').slice(0, 6);
158
+ const base = valor.toUpperCase().replace(/[^A-Z0-9]/g, '').slice(0, 8);
159
+ return base.length > 4 ? `${base.slice(0, 4)}-${base.slice(4)}` : base;
160
+ };
161
+ const esperar = (ms, signal) => new Promise(resolve => {
162
+ const id = setTimeout(resolve, ms);
163
+ signal.addEventListener('abort', () => { clearTimeout(id); resolve(); }, { once: true });
164
+ });
165
+ class MdVerificarMfaComponent {
166
+ api = inject(AUTH_API);
167
+ challenge = input.required();
168
+ titulo = input('Verificación en dos pasos');
169
+ showCancelar = input(true);
170
+ verificado = output();
171
+ cancelado = output();
172
+ tienePush = computed(() => (this.challenge().tipos ?? []).includes('PUSH'));
173
+ tieneTotp = computed(() => {
174
+ const tipos = this.challenge().tipos ?? [];
175
+ return tipos.length == 0 || tipos.includes('TOTP');
176
+ });
177
+ modo = signal('codigo');
178
+ tipoCodigo = signal('totp');
179
+ campo = computed(() => CAMPOS_CODIGO[this.tipoCodigo()]);
180
+ codigo = signal('');
181
+ codigoError = signal('');
182
+ isEnviando = signal(false);
183
+ estadoPush = signal('idle');
184
+ isPushEnCurso = computed(() => this.estadoPush() == 'enviando' || this.estadoPush() == 'esperando');
185
+ pushError = signal('');
186
+ inputCodigo = viewChild('inputCodigo');
187
+ pushCtrl;
188
+ constructor() {
189
+ inject(DestroyRef).onDestroy(() => this.cancelarPush());
190
+ effect(() => {
191
+ this.challenge();
192
+ untracked(() => this.iniciar());
193
+ });
194
+ afterRenderEffect(() => {
195
+ if (this.modo() != 'codigo' || this.isEnviando())
196
+ return;
197
+ this.tipoCodigo();
198
+ this.codigoError();
199
+ this.inputCodigo()?.nativeElement.focus();
200
+ });
201
+ }
202
+ iniciar() {
203
+ this.cancelarPush();
204
+ this.pushError.set('');
205
+ if (this.tienePush() && !this.tieneTotp()) {
206
+ this.usarPush();
207
+ return;
208
+ }
209
+ this.usarCodigo('totp');
210
+ }
211
+ onCodigoInput(event) {
212
+ const input = event.target;
213
+ const limpio = limpiarCodigo(input.value, this.tipoCodigo());
214
+ input.value = limpio;
215
+ this.codigo.set(limpio);
216
+ if (this.codigoError())
217
+ this.codigoError.set('');
218
+ }
219
+ usarCodigo(tipo) {
220
+ this.cancelarPush();
221
+ this.modo.set('codigo');
222
+ this.tipoCodigo.set(tipo);
223
+ this.codigo.set('');
224
+ this.codigoError.set('');
225
+ }
226
+ async verificar() {
227
+ if (this.modo() == 'push' || this.isEnviando())
228
+ return;
229
+ const campo = this.campo();
230
+ if (!campo.patron.test(this.codigo())) {
231
+ this.codigoError.set(campo.mensajeInvalido);
232
+ return;
233
+ }
234
+ this.isEnviando.set(true);
235
+ this.codigoError.set('');
236
+ try {
237
+ await this.api.verificarCodigo({ preauthToken: this.challenge().preauthToken, codigo: this.codigo() });
238
+ this.verificado.emit();
239
+ }
240
+ catch (err) {
241
+ this.codigo.set('');
242
+ this.codigoError.set(mensajeDe(err, campo.mensajeIncorrecto));
243
+ }
244
+ finally {
245
+ this.isEnviando.set(false);
246
+ }
247
+ }
248
+ usarPush() {
249
+ this.modo.set('push');
250
+ this.codigoError.set('');
251
+ this.enviarPush();
252
+ }
253
+ async enviarPush() {
254
+ this.cancelarPush();
255
+ const ctrl = new AbortController();
256
+ this.pushCtrl = ctrl;
257
+ this.pushError.set('');
258
+ this.estadoPush.set('enviando');
259
+ const preauthToken = this.challenge().preauthToken;
260
+ try {
261
+ const solicitudId = await this.api.enviarPush(preauthToken);
262
+ if (ctrl.signal.aborted)
263
+ return;
264
+ this.estadoPush.set('esperando');
265
+ const limite = Date.now() + MAXIMO_ESPERA_MS;
266
+ while (Date.now() < limite) {
267
+ const estado = await this.api.estadoPush({ preauthToken, solicitudId });
268
+ if (ctrl.signal.aborted)
269
+ return;
270
+ if (estado != 'waiting') {
271
+ this.resolverPush(estado);
272
+ return;
273
+ }
274
+ await esperar(INTERVALO_ESTADO_MS, ctrl.signal);
275
+ if (ctrl.signal.aborted)
276
+ return;
277
+ }
278
+ this.estadoPush.set('expirado');
279
+ this.pushError.set('No respondiste a tiempo la notificación. Vuelve a enviarla.');
280
+ }
281
+ catch (err) {
282
+ if (ctrl.signal.aborted)
283
+ return;
284
+ this.estadoPush.set('idle');
285
+ this.pushError.set(mensajeDe(err, 'No se pudo enviar la notificación.'));
286
+ }
287
+ }
288
+ cancelar() {
289
+ this.cancelarPush();
290
+ this.cancelado.emit();
291
+ }
292
+ resolverPush(estado) {
293
+ if (estado == 'aprobado') {
294
+ this.estadoPush.set('idle');
295
+ this.verificado.emit();
296
+ return;
297
+ }
298
+ if (estado == 'expired') {
299
+ this.estadoPush.set('expirado');
300
+ this.pushError.set('La solicitud expiró. Vuelve a enviarla.');
301
+ return;
302
+ }
303
+ this.estadoPush.set('rechazado');
304
+ this.pushError.set('Rechazaste la notificación en tu teléfono.');
305
+ }
306
+ cancelarPush() {
307
+ this.pushCtrl?.abort();
308
+ this.pushCtrl = undefined;
309
+ if (this.isPushEnCurso())
310
+ this.estadoPush.set('idle');
311
+ }
312
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: MdVerificarMfaComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
313
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.25", type: MdVerificarMfaComponent, isStandalone: true, selector: "lib-md-verificar-mfa", inputs: { challenge: { classPropertyName: "challenge", publicName: "challenge", isSignal: true, isRequired: true, transformFunction: null }, titulo: { classPropertyName: "titulo", publicName: "titulo", isSignal: true, isRequired: false, transformFunction: null }, showCancelar: { classPropertyName: "showCancelar", publicName: "showCancelar", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { verificado: "verificado", cancelado: "cancelado" }, viewQueries: [{ propertyName: "inputCodigo", first: true, predicate: ["inputCodigo"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"verificar-mfa\">\n <div class=\"auth-card-title mb-3\">{{ titulo() }}</div>\n\n <div class=\"d-flex align-items-center gap-3 mb-3\">\n <span class=\"verificar-mfa__icono\"><i class=\"fas fa-user-shield\"></i></span>\n <div>\n <div class=\"fw-semibold\">{{ challenge().coduser }}</div>\n @if (challenge().empresa) {\n <div class=\"verificar-mfa__muted\">{{ challenge().empresa }}</div>\n }\n </div>\n </div>\n\n @if (modo() == 'push') {\n @switch (estadoPush()) {\n @case ('enviando') {\n <div class=\"duo-push\">\n <span class=\"spinner-border spinner-border-sm text-primary\"></span>\n <div class=\"flex-grow-1\">Enviando notificaci\u00F3n a tu tel\u00E9fono\u2026</div>\n </div>\n }\n @case ('esperando') {\n <div class=\"duo-push duo-push--esperando\">\n <span class=\"duo-push__icono duo-push__icono--pulso\"><i class=\"fas fa-mobile-alt\"></i></span>\n <div class=\"flex-grow-1\">\n <div class=\"fw-semibold\">Revisa tu tel\u00E9fono</div>\n <div class=\"verificar-mfa__muted\">Aprueba la notificaci\u00F3n en TSI Autenticador para ingresar.</div>\n </div>\n </div>\n }\n @default {\n <div class=\"duo-push\">\n <span class=\"duo-push__icono\"><i class=\"fas fa-bell\"></i></span>\n <div class=\"flex-grow-1\">\n <div class=\"fw-semibold\">TSI Autenticador</div>\n <div class=\"verificar-mfa__muted\">Te enviaremos una notificaci\u00F3n para que la apruebes.</div>\n </div>\n </div>\n }\n }\n @if (pushError() && !isPushEnCurso()) {\n <div class=\"codigo-field__error\"><i class=\"fas fa-exclamation-circle\"></i> {{ pushError() }}</div>\n }\n\n <div class=\"verificar-mfa__opciones\">\n @if (tieneTotp()) {\n <button type=\"button\" class=\"verificar-mfa__link\" (click)=\"usarCodigo('totp')\">\n Usar c\u00F3digo de mi app de autenticaci\u00F3n\n </button>\n }\n <button type=\"button\" class=\"verificar-mfa__link verificar-mfa__link--secundario\"\n (click)=\"usarCodigo('respaldo')\">\n \u00BFNo tienes tu tel\u00E9fono? Usa un c\u00F3digo de respaldo\n </button>\n </div>\n } @else {\n <p class=\"verificar-mfa__muted mb-4\">\n @if (tipoCodigo() == 'totp') {\n {{ challenge().mensaje || campo().descri }}\n } @else {\n {{ campo().descri }}\n }\n </p>\n\n <div class=\"codigo-field\" [class.has-error]=\"codigoError()\">\n <span class=\"codigo-field__icon\"><i class=\"fas\" [class]=\"campo().icon\"></i></span>\n <input #inputCodigo id=\"mfa-codigo\" class=\"codigo-field__input\" type=\"text\"\n [placeholder]=\"campo().placeholder\" [value]=\"codigo()\" (input)=\"onCodigoInput($event)\"\n (keydown.enter)=\"verificar()\" [attr.inputmode]=\"campo().inputmode\" autocomplete=\"one-time-code\"\n autocorrect=\"off\" autocapitalize=\"characters\" spellcheck=\"false\" [disabled]=\"isEnviando()\">\n <label for=\"mfa-codigo\" class=\"codigo-field__label\">{{ campo().label }}</label>\n </div>\n @if (codigoError()) {\n <div class=\"codigo-field__error\"><i class=\"fas fa-exclamation-circle\"></i> {{ codigoError() }}</div>\n }\n\n <div class=\"verificar-mfa__opciones\">\n @if (tienePush()) {\n <button type=\"button\" class=\"verificar-mfa__link\" (click)=\"usarPush()\">\n <i class=\"fas fa-bell me-1\"></i>Mejor env\u00EDame una notificaci\u00F3n push\n </button>\n }\n @if (tieneTotp() && tipoCodigo() != 'totp') {\n <button type=\"button\" class=\"verificar-mfa__link\" (click)=\"usarCodigo('totp')\">\n Usar c\u00F3digo de mi app de autenticaci\u00F3n\n </button>\n }\n @if (tipoCodigo() != 'respaldo') {\n <button type=\"button\" class=\"verificar-mfa__link verificar-mfa__link--secundario\"\n (click)=\"usarCodigo('respaldo')\">\n \u00BFNo tienes tu tel\u00E9fono? Usa un c\u00F3digo de respaldo\n </button>\n }\n </div>\n }\n\n <div class=\"verificar-mfa__acciones\">\n @if (modo() == 'push') {\n <button type=\"button\" class=\"auth-btn\" [disabled]=\"isPushEnCurso()\" (click)=\"enviarPush()\">\n <i class=\"fas fa-paper-plane me-1\"></i>\n {{ isPushEnCurso() ? 'Esperando aprobaci\u00F3n\u2026' : 'Reenviar notificaci\u00F3n' }}\n </button>\n } @else {\n <button type=\"button\" class=\"auth-btn\" [disabled]=\"isEnviando()\" (click)=\"verificar()\">\n <i class=\"fas fa-check me-1\"></i>\n {{ isEnviando() ? 'Verificando\u2026' : 'Verificar' }}\n </button>\n }\n @if (showCancelar()) {\n <button type=\"button\" class=\"auth-btn auth-btn--outline\" (click)=\"cancelar()\">Cancelar</button>\n }\n </div>\n</div>\n", styles: [".verificar-mfa{color:var(--text-color)}.verificar-mfa__icono{display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;width:44px;height:44px;border-radius:12px;color:var(--bs-primary);background:rgba(var(--bs-primary-rgb),.1);font-size:20px}.verificar-mfa__muted{font-size:13px;line-height:1.5;color:var(--bs-secondary-color)}.verificar-mfa__link:hover{text-decoration:underline}.verificar-mfa__link{padding:0;border:0;background:none;font-size:13px;font-weight:600;color:var(--bs-primary)}.codigo-field{position:relative}.codigo-field__icon{position:absolute;left:14px;top:50%;transform:translateY(-50%);z-index:2;font-size:15px;color:var(--placeholder-color);pointer-events:none;transition:color .2s}.codigo-field__input{width:100%;height:56px;padding:0 44px;border:1.5px solid var(--font-border-input);border-radius:10px;outline:none;background:var(--background-input);color:var(--color-input);font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:22px;font-weight:600;letter-spacing:.45em;text-align:center;transition:border-color .2s,box-shadow .2s,background .2s}.codigo-field__input::placeholder{color:var(--placeholder-color);opacity:.45}.codigo-field__input:focus{border-color:var(--bs-primary);box-shadow:0 0 0 3.5px rgba(var(--bs-primary-rgb),.15);background:var(--background-focus-input)}.codigo-field__input:disabled{opacity:.7}.codigo-field__label{position:absolute;left:12px;top:0;transform:translateY(-50%);z-index:1;margin:0!important;padding:0 4px;font-size:11px!important;font-weight:500!important;line-height:1.2;color:var(--placeholder-color);background:var(--background-card);pointer-events:none;transition:color .15s ease}.codigo-field:focus-within .codigo-field__label,.codigo-field:focus-within .codigo-field__icon{color:var(--bs-primary)}.codigo-field.has-error .codigo-field__input{border-color:var(--bs-danger);box-shadow:0 0 0 3.5px rgba(var(--bs-danger-rgb),.12)}.codigo-field.has-error .codigo-field__icon,.codigo-field.has-error .codigo-field__label{color:var(--bs-danger)}.codigo-field__error{display:flex;align-items:center;gap:6px;margin-top:8px;font-size:13px;font-weight:500;color:var(--bs-danger)}.duo-push{display:flex;align-items:center;gap:12px;padding:14px;border:1.5px solid var(--font-border-input);border-radius:10px;background:var(--background-input);color:var(--text-color);font-size:14px}.duo-push--esperando{border-color:rgba(var(--bs-primary-rgb),.45);background:rgba(var(--bs-primary-rgb),.06)}.duo-push__icono{display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;width:40px;height:40px;border-radius:50%;color:var(--bs-primary);background:rgba(var(--bs-primary-rgb),.1);font-size:18px}.duo-push__icono--pulso{animation:duo-pulso 1.4s ease-in-out infinite}@keyframes duo-pulso{0%,to{box-shadow:0 0 rgba(var(--bs-primary-rgb),.35)}50%{box-shadow:0 0 0 8px rgba(var(--bs-primary-rgb),0)}}@media(prefers-reduced-motion:reduce){.duo-push__icono--pulso{animation:none}}.verificar-mfa__opciones{display:flex;flex-direction:column;align-items:flex-start;gap:8px;margin-top:16px}.verificar-mfa__link--secundario{font-weight:500;color:var(--bs-secondary-color)}.verificar-mfa__acciones{margin-top:24px}\n", "@charset \"UTF-8\";.red_contrasena,.blue_contrasena{position:relative;display:inline-block;font-size:13px;text-decoration:none;padding-bottom:2px;transition:color .3s ease;cursor:pointer}.red_contrasena:after,.blue_contrasena:after{content:\"\";position:absolute;bottom:0;left:50%;width:0;height:1px;background-color:currentColor;transition:all .3s ease;transform:translate(-50%)}.red_contrasena:hover:after,.blue_contrasena:hover:after{width:60%}.red_contrasena{color:#d1326f}.red_contrasena:hover{color:#a82859}.blue_contrasena{color:#398bf7}.blue_contrasena:hover{color:#1e5fc4}.auth-wrapper-login{position:fixed;inset:0;display:grid;grid-template-columns:1.15fr .85fr;overflow:hidden;background:#060d1f}.auth-panel-left{position:relative;overflow:hidden;background:linear-gradient(145deg,#040a18,#0b1a3d 55%,#040e22);display:flex;align-items:center;justify-content:center;padding:48px 40px}.auth-panel-left:before{content:\"\";position:absolute;inset:0;background-image:radial-gradient(circle,rgba(255,255,255,.055) 1px,transparent 1px);background-size:26px 26px;z-index:1;pointer-events:none}.auth-panel-left:after{content:\"\";position:absolute;top:0;left:-120%;width:60%;height:100%;background:linear-gradient(90deg,transparent,rgba(57,139,247,.04),transparent);animation:panelSweep 7s ease-in-out infinite;z-index:1;pointer-events:none}.auth-blob{position:absolute;border-radius:50%;filter:blur(72px);z-index:0;pointer-events:none}.auth-blob-1{width:340px;height:340px;background:radial-gradient(circle,rgba(57,139,247,.45) 0%,transparent 70%);top:-90px;right:-70px;animation:blobDrift 11s ease-in-out infinite}.auth-blob-2{width:240px;height:240px;background:radial-gradient(circle,rgba(124,58,237,.4) 0%,transparent 70%);bottom:60px;left:-50px;animation:blobDrift 14s ease-in-out infinite reverse}.auth-blob-3{width:180px;height:180px;background:radial-gradient(circle,rgba(14,165,233,.35) 0%,transparent 70%);bottom:-50px;right:40px;animation:blobDrift 9s ease-in-out infinite;animation-delay:-4s}.auth-blob-4{width:120px;height:120px;background:radial-gradient(circle,rgba(209,50,111,.25) 0%,transparent 70%);top:50%;left:50%;transform:translate(-50%,-50%);animation:blobDrift 16s ease-in-out infinite;animation-delay:-8s}@keyframes blobDrift{0%,to{transform:translate(0) scale(1)}33%{transform:translate(14px,-20px) scale(1.05)}66%{transform:translate(-10px,12px) scale(.96)}}@keyframes panelSweep{0%{left:-120%}50%{left:160%}to{left:160%}}.auth-brand-panel{position:relative;z-index:2;text-align:center;color:#fff;max-width:340px}.auth-brand-logo{width:100px;height:100px;border-radius:50%;background:#ffffff0d;border:1px solid rgba(255,255,255,.1);display:flex;align-items:center;justify-content:center;margin:0 auto 28px;box-shadow:0 0 0 14px #398bf70f,0 0 50px #398bf733;backdrop-filter:blur(8px)}.auth-brand-logo img{width:64px;height:64px;object-fit:contain;filter:brightness(1.05) drop-shadow(0 0 8px rgba(57,139,247,.4))}.auth-brand-title{font-size:30px;font-weight:700;letter-spacing:-.5px;margin-bottom:10px;background:linear-gradient(135deg,#fff 20%,#93c5fd 80%);-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text}.auth-brand-subtitle{font-size:14px;color:#ffffff73;line-height:1.65;margin-bottom:40px;letter-spacing:.2px}.auth-brand-features{display:flex;flex-direction:column;gap:14px;text-align:left}.auth-brand-feature{display:flex;align-items:center;gap:12px;font-size:13px;color:#fff9}.auth-brand-feature .feat-dot{flex-shrink:0;width:7px;height:7px;border-radius:50%;background:#398bf7;box-shadow:0 0 10px #398bf7b3}.auth-brand-divider{width:60px;height:2px;background:linear-gradient(90deg,transparent,#398bf7,transparent);margin:28px auto 32px;border-radius:2px}.auth-panel-left--dev{background:linear-gradient(145deg,#18040b,#3d0b1d 55%,#220409)}.auth-panel-left--dev:after{background:linear-gradient(90deg,transparent,rgba(209,50,111,.05),transparent)}.auth-panel-left--dev .auth-blob-1{background:radial-gradient(circle,rgba(220,38,38,.52) 0%,transparent 70%)}.auth-panel-left--dev .auth-blob-2{background:radial-gradient(circle,rgba(219,39,119,.44) 0%,transparent 70%)}.auth-panel-left--dev .auth-blob-3{background:radial-gradient(circle,rgba(239,68,68,.38) 0%,transparent 70%)}.auth-panel-left--dev .auth-blob-4{background:radial-gradient(circle,rgba(249,115,22,.28) 0%,transparent 70%)}.auth-panel-left--dev .auth-brand-logo{box-shadow:0 0 0 14px #d1326f12,0 0 50px #d1326f38}.auth-panel-left--dev .auth-brand-logo img{filter:brightness(1.05) drop-shadow(0 0 8px rgba(209,50,111,.45))}.auth-panel-left--dev .auth-brand-title{background:linear-gradient(135deg,#fff 20%,#fca5a5 80%);-webkit-background-clip:text;background-clip:text}.auth-panel-left--dev .auth-brand-divider{background:linear-gradient(90deg,transparent,rgb(209,50,111),transparent)}.auth-panel-left--dev .feat-dot{background:#d1326f;box-shadow:0 0 10px #d1326fb8}.auth-panel-right{position:relative;overflow:hidden;background:var(--background-login)}.auth-panel-right:before{content:\"\";position:absolute;inset:0;background-image:repeating-linear-gradient(-55deg,transparent 0px,transparent 22px,rgba(57,139,247,.045) 22px,rgba(57,139,247,.045) 23px);animation:authLinesMove 10s linear infinite;pointer-events:none;z-index:0}.auth-panel-right:after{content:\"\";position:absolute;top:0;bottom:0;left:-25%;width:25%;background:linear-gradient(90deg,transparent 0%,rgba(57,139,247,.02) 30%,rgba(57,139,247,.045) 50%,rgba(57,139,247,.02) 70%,transparent 100%);animation:authScanLine 7s ease-in-out infinite;animation-delay:3.5s;pointer-events:none;z-index:0}@keyframes authLinesMove{0%{transform:translate(0)}to{transform:translate(46px,46px)}}@keyframes authScanLine{0%{left:-25%}50%{left:120%}to{left:120%}}.auth-panel-bg{position:absolute;inset:0;pointer-events:none;z-index:0;overflow:hidden}.auth-deco{position:absolute;border-radius:50%;pointer-events:none;filter:blur(70px)}.auth-deco-tl{width:300px;height:300px;top:0;left:-120px;transform:translateY(-40%);background:radial-gradient(circle,rgba(57,139,247,.12) 0%,transparent 70%);animation:authOrbPulse 6s ease-in-out infinite}.auth-deco-br{width:340px;height:340px;bottom:0;right:-120px;transform:translateY(40%);background:radial-gradient(circle,rgba(124,58,237,.1) 0%,transparent 70%);animation:authOrbPulse 8s ease-in-out infinite;animation-delay:-4s}@keyframes authOrbPulse{0%,to{opacity:.7}50%{opacity:1}}.auth-form-wrapper{position:absolute;inset:0;overflow-y:auto;overflow-x:hidden;display:flex;flex-direction:column;align-items:center;z-index:1}.auth-form-wrapper>div{width:100%;max-width:420px;margin:auto;padding:36px 16px;box-sizing:border-box}.auth-panel-right--dev:before{background-image:repeating-linear-gradient(-55deg,transparent 0px,transparent 22px,rgba(209,50,111,.05) 22px,rgba(209,50,111,.05) 23px)}.auth-panel-right--dev:after{background:linear-gradient(90deg,transparent 0%,rgba(209,50,111,.02) 30%,rgba(209,50,111,.045) 50%,rgba(209,50,111,.02) 70%,transparent 100%)}.auth-panel-right--dev .auth-deco-tl{background:radial-gradient(circle,rgba(209,50,111,.12) 0%,transparent 70%)}.auth-panel-right--dev .auth-deco-br{background:radial-gradient(circle,rgba(239,68,68,.1) 0%,transparent 70%)}.auth-test-badge{display:inline-flex;align-items:center;gap:7px;background:#d1326f14;border:1px solid rgba(209,50,111,.25);color:#d1326f;font-size:10.5px;font-weight:700;padding:5px 12px;border-radius:20px;margin-bottom:18px;letter-spacing:.8px}.auth-test-badge .badge-dot{width:6px;height:6px;border-radius:50%;background:#d1326f;animation:badgePulse 1.6s ease-in-out infinite;flex-shrink:0}@keyframes badgePulse{0%,to{opacity:1;transform:scale(1)}50%{opacity:.45;transform:scale(.75)}}.auth-card{background:var(--background-card);border-radius:20px;padding:36px 32px 28px;box-shadow:0 4px 28px #00000014;border:1px solid var(--border-color-modal)}.auth-card-title{font-size:22px;font-weight:700;color:var(--text-color);margin-bottom:4px;letter-spacing:-.3px}.auth-card-subtitle{font-size:13px;color:var(--placeholder-color);margin-bottom:26px}.auth-field{position:relative;margin-bottom:1rem}.auth-field .auth-field-icon{position:absolute;left:13px;top:50%;transform:translateY(-50%);color:var(--placeholder-color);font-size:13px;z-index:2;pointer-events:none;transition:color .2s}.auth-field .auth-input{width:100%;padding:15px 40px 15px 37px;background:var(--background-input);border:1.5px solid var(--font-border-input);border-radius:10px;font-size:14px;color:var(--color-input);outline:none;transition:border-color .2s,box-shadow .2s,background .2s}.auth-field .auth-input::placeholder{color:transparent}.auth-field .auth-input:focus{border-color:#398bf7;box-shadow:0 0 0 3.5px #398bf721;background:var(--background-focus-input)}.auth-field .auth-input:focus~.auth-label{top:0;font-size:11px!important;color:#398bf7!important;background:var(--background-card);padding:0 4px;transform:translateY(-50%)}.auth-field .auth-input:focus~.auth-field-icon{color:#398bf7}.auth-field .auth-input:not(:placeholder-shown)~.auth-label{top:0;font-size:11px!important;background:var(--background-card);padding:0 4px;transform:translateY(-50%)}.auth-field .auth-label{position:absolute;left:35px;top:50%;transform:translateY(-50%);color:var(--placeholder-color)!important;font-size:13px!important;font-weight:400!important;pointer-events:none;transition:top .15s ease,font-size .15s ease,color .15s ease,padding .15s ease,background .15s ease;background:transparent;z-index:1;text-align:left!important}.auth-field .auth-toggle-pw{position:absolute;right:10px;top:50%;transform:translateY(-50%);background:none;border:none;color:var(--placeholder-color);cursor:pointer;padding:4px 6px;font-size:13px;z-index:2;line-height:1;transition:color .2s}.auth-field .auth-toggle-pw:hover{color:#398bf7}.auth-field.has-error .auth-input{border-color:#dc3545;box-shadow:none}.auth-field.has-error .auth-field-icon{color:#dc3545}.auth-select{width:100%;padding:13px 14px;background:var(--background-input);border:1.5px solid var(--font-border-input);border-radius:10px;font-size:14px;color:var(--color-input);outline:none;transition:border-color .2s,box-shadow .2s;margin-bottom:1rem;cursor:pointer}.auth-select:focus{border-color:#398bf7;box-shadow:0 0 0 3.5px #398bf721}.auth-btn{width:100%;padding:13px;border:none;border-radius:10px;font-size:14px;font-weight:600;cursor:pointer;transition:transform .15s ease,box-shadow .2s ease,opacity .2s;background:linear-gradient(135deg,#398bf7,#1e5fc4);color:#fff;letter-spacing:.3px;margin-bottom:10px;display:block}.auth-btn:hover:not(:disabled){transform:translateY(-1px);box-shadow:0 5px 18px #398bf761}.auth-btn:active:not(:disabled){transform:translateY(0)}.auth-btn:disabled{opacity:.55;cursor:not-allowed}.auth-btn.auth-btn--red{background:linear-gradient(135deg,#d1326f,#a82859)}.auth-btn.auth-btn--red:hover:not(:disabled){box-shadow:0 5px 18px #d1326f61}.auth-btn.auth-btn--outline{background:transparent;border:1.5px solid var(--font-border-input);color:var(--text-color)}.auth-btn.auth-btn--outline:hover:not(:disabled){background:var(--background-btn-light-hover);box-shadow:none;transform:none}.auth-links{display:flex;flex-direction:column;align-items:center;gap:10px;margin-top:16px;padding-top:16px;border-top:1px solid var(--border-color-modal)}.auth-version{text-align:right;margin-top:14px;padding-top:12px;border-top:1px solid var(--border-color-modal)}.auth-version span{font-size:11px;color:var(--placeholder-color)}.auth-error{font-size:11.5px;color:#dc3545;margin:-6px 0 10px 2px;padding:0}.auth-hint{display:flex;align-items:flex-start;gap:6px;font-size:11.5px;color:var(--placeholder-color);margin:-6px 0 14px 2px;padding:0;line-height:1.35}.auth-hint i{margin-top:2px;flex-shrink:0}.auth-validation-list{margin:-4px 0 12px;padding:0;list-style:none}.auth-validation-list li{font-size:11.5px;color:#dc3545;padding:2px 0}.auth-validation-list li:before{content:\"\\2715 \";font-size:10px}.auth-desc{font-size:13px;color:var(--placeholder-color);margin-bottom:20px;line-height:1.65}.auth-section-title{font-size:15px;font-weight:600;color:var(--text-color);margin-bottom:20px}.font-12{font-size:12px}.form-control:focus{border-color:#0199ff9a!important;box-shadow:0 0 5px .2px #65befa44!important}@media(max-width:900px){.auth-wrapper-login{grid-template-columns:1fr;grid-template-rows:auto 1fr;overflow-y:auto;overflow-x:hidden}.auth-panel-left{padding:14px 24px;justify-content:center}.auth-panel-left .auth-brand-subtitle,.auth-panel-left .auth-brand-features,.auth-panel-left .auth-brand-divider{display:none!important}.auth-panel-left .auth-brand-panel{display:flex!important;flex-direction:row!important;align-items:center;gap:0;text-align:left;max-width:none;width:100%;justify-content:center}.auth-panel-left .auth-brand-logo{width:52px;height:52px;margin:0;flex-shrink:0}.auth-panel-left .auth-brand-logo img{width:34px;height:34px}.auth-panel-left .auth-brand-title{font-size:20px;margin-bottom:0;margin-left:.5rem;flex-shrink:1}.auth-panel-right:after{inset:-25% 0 auto;width:100%;height:25%;background:linear-gradient(180deg,transparent 0%,rgba(57,139,247,.02) 30%,rgba(57,139,247,.045) 50%,rgba(57,139,247,.02) 70%,transparent 100%);animation:authScanLineV 7s ease-in-out infinite;animation-delay:3.5s}.auth-panel-right--dev:after{background:linear-gradient(180deg,transparent 0%,rgba(209,50,111,.02) 30%,rgba(209,50,111,.045) 50%,rgba(209,50,111,.02) 70%,transparent 100%)}}@keyframes authScanLineV{0%{top:-25%}50%{top:120%}to{top:120%}}@media(max-width:480px){.auth-panel-left{padding:12px 16px}.auth-panel-left .auth-brand-logo{width:44px;height:44px}.auth-panel-left .auth-brand-logo img{width:28px;height:28px}.auth-panel-left .auth-brand-title{font-size:17px}.auth-form-wrapper>div{padding:20px 12px}.auth-card{padding:24px 18px 20px;border-radius:16px}.font-12{font-size:10px!important}}\n"] });
314
+ }
315
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: MdVerificarMfaComponent, decorators: [{
316
+ type: Component,
317
+ args: [{ selector: 'lib-md-verificar-mfa', template: "<div class=\"verificar-mfa\">\n <div class=\"auth-card-title mb-3\">{{ titulo() }}</div>\n\n <div class=\"d-flex align-items-center gap-3 mb-3\">\n <span class=\"verificar-mfa__icono\"><i class=\"fas fa-user-shield\"></i></span>\n <div>\n <div class=\"fw-semibold\">{{ challenge().coduser }}</div>\n @if (challenge().empresa) {\n <div class=\"verificar-mfa__muted\">{{ challenge().empresa }}</div>\n }\n </div>\n </div>\n\n @if (modo() == 'push') {\n @switch (estadoPush()) {\n @case ('enviando') {\n <div class=\"duo-push\">\n <span class=\"spinner-border spinner-border-sm text-primary\"></span>\n <div class=\"flex-grow-1\">Enviando notificaci\u00F3n a tu tel\u00E9fono\u2026</div>\n </div>\n }\n @case ('esperando') {\n <div class=\"duo-push duo-push--esperando\">\n <span class=\"duo-push__icono duo-push__icono--pulso\"><i class=\"fas fa-mobile-alt\"></i></span>\n <div class=\"flex-grow-1\">\n <div class=\"fw-semibold\">Revisa tu tel\u00E9fono</div>\n <div class=\"verificar-mfa__muted\">Aprueba la notificaci\u00F3n en TSI Autenticador para ingresar.</div>\n </div>\n </div>\n }\n @default {\n <div class=\"duo-push\">\n <span class=\"duo-push__icono\"><i class=\"fas fa-bell\"></i></span>\n <div class=\"flex-grow-1\">\n <div class=\"fw-semibold\">TSI Autenticador</div>\n <div class=\"verificar-mfa__muted\">Te enviaremos una notificaci\u00F3n para que la apruebes.</div>\n </div>\n </div>\n }\n }\n @if (pushError() && !isPushEnCurso()) {\n <div class=\"codigo-field__error\"><i class=\"fas fa-exclamation-circle\"></i> {{ pushError() }}</div>\n }\n\n <div class=\"verificar-mfa__opciones\">\n @if (tieneTotp()) {\n <button type=\"button\" class=\"verificar-mfa__link\" (click)=\"usarCodigo('totp')\">\n Usar c\u00F3digo de mi app de autenticaci\u00F3n\n </button>\n }\n <button type=\"button\" class=\"verificar-mfa__link verificar-mfa__link--secundario\"\n (click)=\"usarCodigo('respaldo')\">\n \u00BFNo tienes tu tel\u00E9fono? Usa un c\u00F3digo de respaldo\n </button>\n </div>\n } @else {\n <p class=\"verificar-mfa__muted mb-4\">\n @if (tipoCodigo() == 'totp') {\n {{ challenge().mensaje || campo().descri }}\n } @else {\n {{ campo().descri }}\n }\n </p>\n\n <div class=\"codigo-field\" [class.has-error]=\"codigoError()\">\n <span class=\"codigo-field__icon\"><i class=\"fas\" [class]=\"campo().icon\"></i></span>\n <input #inputCodigo id=\"mfa-codigo\" class=\"codigo-field__input\" type=\"text\"\n [placeholder]=\"campo().placeholder\" [value]=\"codigo()\" (input)=\"onCodigoInput($event)\"\n (keydown.enter)=\"verificar()\" [attr.inputmode]=\"campo().inputmode\" autocomplete=\"one-time-code\"\n autocorrect=\"off\" autocapitalize=\"characters\" spellcheck=\"false\" [disabled]=\"isEnviando()\">\n <label for=\"mfa-codigo\" class=\"codigo-field__label\">{{ campo().label }}</label>\n </div>\n @if (codigoError()) {\n <div class=\"codigo-field__error\"><i class=\"fas fa-exclamation-circle\"></i> {{ codigoError() }}</div>\n }\n\n <div class=\"verificar-mfa__opciones\">\n @if (tienePush()) {\n <button type=\"button\" class=\"verificar-mfa__link\" (click)=\"usarPush()\">\n <i class=\"fas fa-bell me-1\"></i>Mejor env\u00EDame una notificaci\u00F3n push\n </button>\n }\n @if (tieneTotp() && tipoCodigo() != 'totp') {\n <button type=\"button\" class=\"verificar-mfa__link\" (click)=\"usarCodigo('totp')\">\n Usar c\u00F3digo de mi app de autenticaci\u00F3n\n </button>\n }\n @if (tipoCodigo() != 'respaldo') {\n <button type=\"button\" class=\"verificar-mfa__link verificar-mfa__link--secundario\"\n (click)=\"usarCodigo('respaldo')\">\n \u00BFNo tienes tu tel\u00E9fono? Usa un c\u00F3digo de respaldo\n </button>\n }\n </div>\n }\n\n <div class=\"verificar-mfa__acciones\">\n @if (modo() == 'push') {\n <button type=\"button\" class=\"auth-btn\" [disabled]=\"isPushEnCurso()\" (click)=\"enviarPush()\">\n <i class=\"fas fa-paper-plane me-1\"></i>\n {{ isPushEnCurso() ? 'Esperando aprobaci\u00F3n\u2026' : 'Reenviar notificaci\u00F3n' }}\n </button>\n } @else {\n <button type=\"button\" class=\"auth-btn\" [disabled]=\"isEnviando()\" (click)=\"verificar()\">\n <i class=\"fas fa-check me-1\"></i>\n {{ isEnviando() ? 'Verificando\u2026' : 'Verificar' }}\n </button>\n }\n @if (showCancelar()) {\n <button type=\"button\" class=\"auth-btn auth-btn--outline\" (click)=\"cancelar()\">Cancelar</button>\n }\n </div>\n</div>\n", styles: [".verificar-mfa{color:var(--text-color)}.verificar-mfa__icono{display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;width:44px;height:44px;border-radius:12px;color:var(--bs-primary);background:rgba(var(--bs-primary-rgb),.1);font-size:20px}.verificar-mfa__muted{font-size:13px;line-height:1.5;color:var(--bs-secondary-color)}.verificar-mfa__link:hover{text-decoration:underline}.verificar-mfa__link{padding:0;border:0;background:none;font-size:13px;font-weight:600;color:var(--bs-primary)}.codigo-field{position:relative}.codigo-field__icon{position:absolute;left:14px;top:50%;transform:translateY(-50%);z-index:2;font-size:15px;color:var(--placeholder-color);pointer-events:none;transition:color .2s}.codigo-field__input{width:100%;height:56px;padding:0 44px;border:1.5px solid var(--font-border-input);border-radius:10px;outline:none;background:var(--background-input);color:var(--color-input);font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:22px;font-weight:600;letter-spacing:.45em;text-align:center;transition:border-color .2s,box-shadow .2s,background .2s}.codigo-field__input::placeholder{color:var(--placeholder-color);opacity:.45}.codigo-field__input:focus{border-color:var(--bs-primary);box-shadow:0 0 0 3.5px rgba(var(--bs-primary-rgb),.15);background:var(--background-focus-input)}.codigo-field__input:disabled{opacity:.7}.codigo-field__label{position:absolute;left:12px;top:0;transform:translateY(-50%);z-index:1;margin:0!important;padding:0 4px;font-size:11px!important;font-weight:500!important;line-height:1.2;color:var(--placeholder-color);background:var(--background-card);pointer-events:none;transition:color .15s ease}.codigo-field:focus-within .codigo-field__label,.codigo-field:focus-within .codigo-field__icon{color:var(--bs-primary)}.codigo-field.has-error .codigo-field__input{border-color:var(--bs-danger);box-shadow:0 0 0 3.5px rgba(var(--bs-danger-rgb),.12)}.codigo-field.has-error .codigo-field__icon,.codigo-field.has-error .codigo-field__label{color:var(--bs-danger)}.codigo-field__error{display:flex;align-items:center;gap:6px;margin-top:8px;font-size:13px;font-weight:500;color:var(--bs-danger)}.duo-push{display:flex;align-items:center;gap:12px;padding:14px;border:1.5px solid var(--font-border-input);border-radius:10px;background:var(--background-input);color:var(--text-color);font-size:14px}.duo-push--esperando{border-color:rgba(var(--bs-primary-rgb),.45);background:rgba(var(--bs-primary-rgb),.06)}.duo-push__icono{display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;width:40px;height:40px;border-radius:50%;color:var(--bs-primary);background:rgba(var(--bs-primary-rgb),.1);font-size:18px}.duo-push__icono--pulso{animation:duo-pulso 1.4s ease-in-out infinite}@keyframes duo-pulso{0%,to{box-shadow:0 0 rgba(var(--bs-primary-rgb),.35)}50%{box-shadow:0 0 0 8px rgba(var(--bs-primary-rgb),0)}}@media(prefers-reduced-motion:reduce){.duo-push__icono--pulso{animation:none}}.verificar-mfa__opciones{display:flex;flex-direction:column;align-items:flex-start;gap:8px;margin-top:16px}.verificar-mfa__link--secundario{font-weight:500;color:var(--bs-secondary-color)}.verificar-mfa__acciones{margin-top:24px}\n", "@charset \"UTF-8\";.red_contrasena,.blue_contrasena{position:relative;display:inline-block;font-size:13px;text-decoration:none;padding-bottom:2px;transition:color .3s ease;cursor:pointer}.red_contrasena:after,.blue_contrasena:after{content:\"\";position:absolute;bottom:0;left:50%;width:0;height:1px;background-color:currentColor;transition:all .3s ease;transform:translate(-50%)}.red_contrasena:hover:after,.blue_contrasena:hover:after{width:60%}.red_contrasena{color:#d1326f}.red_contrasena:hover{color:#a82859}.blue_contrasena{color:#398bf7}.blue_contrasena:hover{color:#1e5fc4}.auth-wrapper-login{position:fixed;inset:0;display:grid;grid-template-columns:1.15fr .85fr;overflow:hidden;background:#060d1f}.auth-panel-left{position:relative;overflow:hidden;background:linear-gradient(145deg,#040a18,#0b1a3d 55%,#040e22);display:flex;align-items:center;justify-content:center;padding:48px 40px}.auth-panel-left:before{content:\"\";position:absolute;inset:0;background-image:radial-gradient(circle,rgba(255,255,255,.055) 1px,transparent 1px);background-size:26px 26px;z-index:1;pointer-events:none}.auth-panel-left:after{content:\"\";position:absolute;top:0;left:-120%;width:60%;height:100%;background:linear-gradient(90deg,transparent,rgba(57,139,247,.04),transparent);animation:panelSweep 7s ease-in-out infinite;z-index:1;pointer-events:none}.auth-blob{position:absolute;border-radius:50%;filter:blur(72px);z-index:0;pointer-events:none}.auth-blob-1{width:340px;height:340px;background:radial-gradient(circle,rgba(57,139,247,.45) 0%,transparent 70%);top:-90px;right:-70px;animation:blobDrift 11s ease-in-out infinite}.auth-blob-2{width:240px;height:240px;background:radial-gradient(circle,rgba(124,58,237,.4) 0%,transparent 70%);bottom:60px;left:-50px;animation:blobDrift 14s ease-in-out infinite reverse}.auth-blob-3{width:180px;height:180px;background:radial-gradient(circle,rgba(14,165,233,.35) 0%,transparent 70%);bottom:-50px;right:40px;animation:blobDrift 9s ease-in-out infinite;animation-delay:-4s}.auth-blob-4{width:120px;height:120px;background:radial-gradient(circle,rgba(209,50,111,.25) 0%,transparent 70%);top:50%;left:50%;transform:translate(-50%,-50%);animation:blobDrift 16s ease-in-out infinite;animation-delay:-8s}@keyframes blobDrift{0%,to{transform:translate(0) scale(1)}33%{transform:translate(14px,-20px) scale(1.05)}66%{transform:translate(-10px,12px) scale(.96)}}@keyframes panelSweep{0%{left:-120%}50%{left:160%}to{left:160%}}.auth-brand-panel{position:relative;z-index:2;text-align:center;color:#fff;max-width:340px}.auth-brand-logo{width:100px;height:100px;border-radius:50%;background:#ffffff0d;border:1px solid rgba(255,255,255,.1);display:flex;align-items:center;justify-content:center;margin:0 auto 28px;box-shadow:0 0 0 14px #398bf70f,0 0 50px #398bf733;backdrop-filter:blur(8px)}.auth-brand-logo img{width:64px;height:64px;object-fit:contain;filter:brightness(1.05) drop-shadow(0 0 8px rgba(57,139,247,.4))}.auth-brand-title{font-size:30px;font-weight:700;letter-spacing:-.5px;margin-bottom:10px;background:linear-gradient(135deg,#fff 20%,#93c5fd 80%);-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text}.auth-brand-subtitle{font-size:14px;color:#ffffff73;line-height:1.65;margin-bottom:40px;letter-spacing:.2px}.auth-brand-features{display:flex;flex-direction:column;gap:14px;text-align:left}.auth-brand-feature{display:flex;align-items:center;gap:12px;font-size:13px;color:#fff9}.auth-brand-feature .feat-dot{flex-shrink:0;width:7px;height:7px;border-radius:50%;background:#398bf7;box-shadow:0 0 10px #398bf7b3}.auth-brand-divider{width:60px;height:2px;background:linear-gradient(90deg,transparent,#398bf7,transparent);margin:28px auto 32px;border-radius:2px}.auth-panel-left--dev{background:linear-gradient(145deg,#18040b,#3d0b1d 55%,#220409)}.auth-panel-left--dev:after{background:linear-gradient(90deg,transparent,rgba(209,50,111,.05),transparent)}.auth-panel-left--dev .auth-blob-1{background:radial-gradient(circle,rgba(220,38,38,.52) 0%,transparent 70%)}.auth-panel-left--dev .auth-blob-2{background:radial-gradient(circle,rgba(219,39,119,.44) 0%,transparent 70%)}.auth-panel-left--dev .auth-blob-3{background:radial-gradient(circle,rgba(239,68,68,.38) 0%,transparent 70%)}.auth-panel-left--dev .auth-blob-4{background:radial-gradient(circle,rgba(249,115,22,.28) 0%,transparent 70%)}.auth-panel-left--dev .auth-brand-logo{box-shadow:0 0 0 14px #d1326f12,0 0 50px #d1326f38}.auth-panel-left--dev .auth-brand-logo img{filter:brightness(1.05) drop-shadow(0 0 8px rgba(209,50,111,.45))}.auth-panel-left--dev .auth-brand-title{background:linear-gradient(135deg,#fff 20%,#fca5a5 80%);-webkit-background-clip:text;background-clip:text}.auth-panel-left--dev .auth-brand-divider{background:linear-gradient(90deg,transparent,rgb(209,50,111),transparent)}.auth-panel-left--dev .feat-dot{background:#d1326f;box-shadow:0 0 10px #d1326fb8}.auth-panel-right{position:relative;overflow:hidden;background:var(--background-login)}.auth-panel-right:before{content:\"\";position:absolute;inset:0;background-image:repeating-linear-gradient(-55deg,transparent 0px,transparent 22px,rgba(57,139,247,.045) 22px,rgba(57,139,247,.045) 23px);animation:authLinesMove 10s linear infinite;pointer-events:none;z-index:0}.auth-panel-right:after{content:\"\";position:absolute;top:0;bottom:0;left:-25%;width:25%;background:linear-gradient(90deg,transparent 0%,rgba(57,139,247,.02) 30%,rgba(57,139,247,.045) 50%,rgba(57,139,247,.02) 70%,transparent 100%);animation:authScanLine 7s ease-in-out infinite;animation-delay:3.5s;pointer-events:none;z-index:0}@keyframes authLinesMove{0%{transform:translate(0)}to{transform:translate(46px,46px)}}@keyframes authScanLine{0%{left:-25%}50%{left:120%}to{left:120%}}.auth-panel-bg{position:absolute;inset:0;pointer-events:none;z-index:0;overflow:hidden}.auth-deco{position:absolute;border-radius:50%;pointer-events:none;filter:blur(70px)}.auth-deco-tl{width:300px;height:300px;top:0;left:-120px;transform:translateY(-40%);background:radial-gradient(circle,rgba(57,139,247,.12) 0%,transparent 70%);animation:authOrbPulse 6s ease-in-out infinite}.auth-deco-br{width:340px;height:340px;bottom:0;right:-120px;transform:translateY(40%);background:radial-gradient(circle,rgba(124,58,237,.1) 0%,transparent 70%);animation:authOrbPulse 8s ease-in-out infinite;animation-delay:-4s}@keyframes authOrbPulse{0%,to{opacity:.7}50%{opacity:1}}.auth-form-wrapper{position:absolute;inset:0;overflow-y:auto;overflow-x:hidden;display:flex;flex-direction:column;align-items:center;z-index:1}.auth-form-wrapper>div{width:100%;max-width:420px;margin:auto;padding:36px 16px;box-sizing:border-box}.auth-panel-right--dev:before{background-image:repeating-linear-gradient(-55deg,transparent 0px,transparent 22px,rgba(209,50,111,.05) 22px,rgba(209,50,111,.05) 23px)}.auth-panel-right--dev:after{background:linear-gradient(90deg,transparent 0%,rgba(209,50,111,.02) 30%,rgba(209,50,111,.045) 50%,rgba(209,50,111,.02) 70%,transparent 100%)}.auth-panel-right--dev .auth-deco-tl{background:radial-gradient(circle,rgba(209,50,111,.12) 0%,transparent 70%)}.auth-panel-right--dev .auth-deco-br{background:radial-gradient(circle,rgba(239,68,68,.1) 0%,transparent 70%)}.auth-test-badge{display:inline-flex;align-items:center;gap:7px;background:#d1326f14;border:1px solid rgba(209,50,111,.25);color:#d1326f;font-size:10.5px;font-weight:700;padding:5px 12px;border-radius:20px;margin-bottom:18px;letter-spacing:.8px}.auth-test-badge .badge-dot{width:6px;height:6px;border-radius:50%;background:#d1326f;animation:badgePulse 1.6s ease-in-out infinite;flex-shrink:0}@keyframes badgePulse{0%,to{opacity:1;transform:scale(1)}50%{opacity:.45;transform:scale(.75)}}.auth-card{background:var(--background-card);border-radius:20px;padding:36px 32px 28px;box-shadow:0 4px 28px #00000014;border:1px solid var(--border-color-modal)}.auth-card-title{font-size:22px;font-weight:700;color:var(--text-color);margin-bottom:4px;letter-spacing:-.3px}.auth-card-subtitle{font-size:13px;color:var(--placeholder-color);margin-bottom:26px}.auth-field{position:relative;margin-bottom:1rem}.auth-field .auth-field-icon{position:absolute;left:13px;top:50%;transform:translateY(-50%);color:var(--placeholder-color);font-size:13px;z-index:2;pointer-events:none;transition:color .2s}.auth-field .auth-input{width:100%;padding:15px 40px 15px 37px;background:var(--background-input);border:1.5px solid var(--font-border-input);border-radius:10px;font-size:14px;color:var(--color-input);outline:none;transition:border-color .2s,box-shadow .2s,background .2s}.auth-field .auth-input::placeholder{color:transparent}.auth-field .auth-input:focus{border-color:#398bf7;box-shadow:0 0 0 3.5px #398bf721;background:var(--background-focus-input)}.auth-field .auth-input:focus~.auth-label{top:0;font-size:11px!important;color:#398bf7!important;background:var(--background-card);padding:0 4px;transform:translateY(-50%)}.auth-field .auth-input:focus~.auth-field-icon{color:#398bf7}.auth-field .auth-input:not(:placeholder-shown)~.auth-label{top:0;font-size:11px!important;background:var(--background-card);padding:0 4px;transform:translateY(-50%)}.auth-field .auth-label{position:absolute;left:35px;top:50%;transform:translateY(-50%);color:var(--placeholder-color)!important;font-size:13px!important;font-weight:400!important;pointer-events:none;transition:top .15s ease,font-size .15s ease,color .15s ease,padding .15s ease,background .15s ease;background:transparent;z-index:1;text-align:left!important}.auth-field .auth-toggle-pw{position:absolute;right:10px;top:50%;transform:translateY(-50%);background:none;border:none;color:var(--placeholder-color);cursor:pointer;padding:4px 6px;font-size:13px;z-index:2;line-height:1;transition:color .2s}.auth-field .auth-toggle-pw:hover{color:#398bf7}.auth-field.has-error .auth-input{border-color:#dc3545;box-shadow:none}.auth-field.has-error .auth-field-icon{color:#dc3545}.auth-select{width:100%;padding:13px 14px;background:var(--background-input);border:1.5px solid var(--font-border-input);border-radius:10px;font-size:14px;color:var(--color-input);outline:none;transition:border-color .2s,box-shadow .2s;margin-bottom:1rem;cursor:pointer}.auth-select:focus{border-color:#398bf7;box-shadow:0 0 0 3.5px #398bf721}.auth-btn{width:100%;padding:13px;border:none;border-radius:10px;font-size:14px;font-weight:600;cursor:pointer;transition:transform .15s ease,box-shadow .2s ease,opacity .2s;background:linear-gradient(135deg,#398bf7,#1e5fc4);color:#fff;letter-spacing:.3px;margin-bottom:10px;display:block}.auth-btn:hover:not(:disabled){transform:translateY(-1px);box-shadow:0 5px 18px #398bf761}.auth-btn:active:not(:disabled){transform:translateY(0)}.auth-btn:disabled{opacity:.55;cursor:not-allowed}.auth-btn.auth-btn--red{background:linear-gradient(135deg,#d1326f,#a82859)}.auth-btn.auth-btn--red:hover:not(:disabled){box-shadow:0 5px 18px #d1326f61}.auth-btn.auth-btn--outline{background:transparent;border:1.5px solid var(--font-border-input);color:var(--text-color)}.auth-btn.auth-btn--outline:hover:not(:disabled){background:var(--background-btn-light-hover);box-shadow:none;transform:none}.auth-links{display:flex;flex-direction:column;align-items:center;gap:10px;margin-top:16px;padding-top:16px;border-top:1px solid var(--border-color-modal)}.auth-version{text-align:right;margin-top:14px;padding-top:12px;border-top:1px solid var(--border-color-modal)}.auth-version span{font-size:11px;color:var(--placeholder-color)}.auth-error{font-size:11.5px;color:#dc3545;margin:-6px 0 10px 2px;padding:0}.auth-hint{display:flex;align-items:flex-start;gap:6px;font-size:11.5px;color:var(--placeholder-color);margin:-6px 0 14px 2px;padding:0;line-height:1.35}.auth-hint i{margin-top:2px;flex-shrink:0}.auth-validation-list{margin:-4px 0 12px;padding:0;list-style:none}.auth-validation-list li{font-size:11.5px;color:#dc3545;padding:2px 0}.auth-validation-list li:before{content:\"\\2715 \";font-size:10px}.auth-desc{font-size:13px;color:var(--placeholder-color);margin-bottom:20px;line-height:1.65}.auth-section-title{font-size:15px;font-weight:600;color:var(--text-color);margin-bottom:20px}.font-12{font-size:12px}.form-control:focus{border-color:#0199ff9a!important;box-shadow:0 0 5px .2px #65befa44!important}@media(max-width:900px){.auth-wrapper-login{grid-template-columns:1fr;grid-template-rows:auto 1fr;overflow-y:auto;overflow-x:hidden}.auth-panel-left{padding:14px 24px;justify-content:center}.auth-panel-left .auth-brand-subtitle,.auth-panel-left .auth-brand-features,.auth-panel-left .auth-brand-divider{display:none!important}.auth-panel-left .auth-brand-panel{display:flex!important;flex-direction:row!important;align-items:center;gap:0;text-align:left;max-width:none;width:100%;justify-content:center}.auth-panel-left .auth-brand-logo{width:52px;height:52px;margin:0;flex-shrink:0}.auth-panel-left .auth-brand-logo img{width:34px;height:34px}.auth-panel-left .auth-brand-title{font-size:20px;margin-bottom:0;margin-left:.5rem;flex-shrink:1}.auth-panel-right:after{inset:-25% 0 auto;width:100%;height:25%;background:linear-gradient(180deg,transparent 0%,rgba(57,139,247,.02) 30%,rgba(57,139,247,.045) 50%,rgba(57,139,247,.02) 70%,transparent 100%);animation:authScanLineV 7s ease-in-out infinite;animation-delay:3.5s}.auth-panel-right--dev:after{background:linear-gradient(180deg,transparent 0%,rgba(209,50,111,.02) 30%,rgba(209,50,111,.045) 50%,rgba(209,50,111,.02) 70%,transparent 100%)}}@keyframes authScanLineV{0%{top:-25%}50%{top:120%}to{top:120%}}@media(max-width:480px){.auth-panel-left{padding:12px 16px}.auth-panel-left .auth-brand-logo{width:44px;height:44px}.auth-panel-left .auth-brand-logo img{width:28px;height:28px}.auth-panel-left .auth-brand-title{font-size:17px}.auth-form-wrapper>div{padding:20px 12px}.auth-card{padding:24px 18px 20px;border-radius:16px}.font-12{font-size:10px!important}}\n"] }]
318
+ }], ctorParameters: () => [] });
319
+
320
+ const MENSAJE_ERROR_LOGIN = 'No se pudo iniciar sesión.';
321
+ const CLASE_CERRANDO = 'auth-mfa-dialog--cerrando';
322
+ const MAXIMO_SALIDA_MS = 400;
110
323
  class AuthComponent {
324
+ api = inject(AUTH_API, { optional: true });
111
325
  production = input(true);
112
- module = input('ERP'); // DEFECTO ERP
113
- versionApp = input('1.0.0'); // DEFECTO 1.0.0
114
- product = input(); // DEFECTO NULL - ERP
326
+ module = input('ERP');
327
+ versionApp = input('1.0.0');
328
+ product = input();
115
329
  authForm = input.required();
116
330
  aboutList = input([
117
331
  'Gestión de compras y logística',
@@ -119,35 +333,96 @@ class AuthComponent {
119
333
  'Reportes y análisis en tiempo real',
120
334
  'Integración con inteligencia artificial'
121
335
  ]);
122
- /** Muestra el flotante de "instalar app" (app-pwa-floating). Por defecto siempre visible. */
123
336
  showFloatingApp = input(true);
124
- /** Muestra el flotante de "actualización disponible" (app-refresh-floating). Por defecto siempre visible. */
125
337
  showFloatingUpdate = input(true);
126
338
  loginEvent = output();
127
- /** Se dispara antes de instalar la PWA — el RUC/usuario ya están en authForm(), el consumidor decide qué guardar. */
128
339
  beforeInstall = output();
129
340
  showPassword = signal(false);
341
+ isIngresando = signal(false);
342
+ pasoMfa = signal(null);
343
+ dialogMfa = viewChild.required('dialogMfa');
130
344
  onBeforeInstall = () => this.beforeInstall.emit();
131
345
  recover = () => this.loginEvent.emit({ type: "RECOVER" });
132
346
  forget = () => this.loginEvent.emit({ type: "FORGET" });
133
347
  togglePassword = () => this.showPassword.set(!this.showPassword());
134
- login = () => {
135
- if (!this.validacionInit())
348
+ login = async () => {
349
+ if (this.isIngresando() || !this.validacionInit())
350
+ return;
351
+ const data = this.armarSender();
352
+ if (!this.api) {
353
+ this.loginEvent.emit({ type: "LOGIN", data });
136
354
  return;
355
+ }
356
+ this.isIngresando.set(true);
357
+ try {
358
+ const respuesta = await this.api.login(data);
359
+ if (isMfaChallenge(respuesta)) {
360
+ this.abrirMfa({ challenge: respuesta, data });
361
+ return;
362
+ }
363
+ this.loginEvent.emit({ type: "AUTENTICADO", data });
364
+ }
365
+ catch (err) {
366
+ this.returnError(mensajeDe(err, MENSAJE_ERROR_LOGIN));
367
+ }
368
+ finally {
369
+ this.isIngresando.set(false);
370
+ }
371
+ };
372
+ onMfaVerificado = async () => {
373
+ const paso = this.pasoMfa();
374
+ await this.cerrarMfa();
375
+ if (paso)
376
+ this.loginEvent.emit({ type: "AUTENTICADO", data: paso.data });
377
+ };
378
+ onMfaCancelado = async () => {
379
+ await this.cerrarMfa();
380
+ this.authForm().patchValue({ clave: '' });
381
+ };
382
+ abrirMfa(paso) {
383
+ const dialog = this.dialogMfa().nativeElement;
384
+ dialog.classList.remove(CLASE_CERRANDO);
385
+ this.pasoMfa.set(paso);
386
+ if (!dialog.open)
387
+ dialog.showModal();
388
+ }
389
+ cerrarMfa() {
390
+ const dialog = this.dialogMfa().nativeElement;
391
+ if (!dialog.open) {
392
+ this.pasoMfa.set(null);
393
+ return Promise.resolve();
394
+ }
395
+ return new Promise(resolve => {
396
+ let terminado = false;
397
+ const terminar = () => {
398
+ if (terminado)
399
+ return;
400
+ terminado = true;
401
+ clearTimeout(respaldo);
402
+ dialog.removeEventListener('animationend', alTerminarAnimacion);
403
+ dialog.close();
404
+ dialog.classList.remove(CLASE_CERRANDO);
405
+ this.pasoMfa.set(null);
406
+ resolve();
407
+ };
408
+ const alTerminarAnimacion = (event) => {
409
+ if (event.target == dialog)
410
+ terminar();
411
+ };
412
+ const respaldo = setTimeout(terminar, MAXIMO_SALIDA_MS);
413
+ dialog.addEventListener('animationend', alTerminarAnimacion);
414
+ dialog.classList.add(CLASE_CERRANDO);
415
+ });
416
+ }
417
+ armarSender() {
137
418
  const dataForm = this.authForm().value;
138
- const data = {
419
+ return {
139
420
  ruc: dataForm.ruc,
140
421
  coduser: dataForm.nomuser,
141
422
  clave: btoa(dataForm.clave),
142
423
  producto: this.product()
143
424
  };
144
- this.loginEvent.emit({ type: "LOGIN", data });
145
- };
146
- // authForm = this.formBuilder.group({
147
- // ruc: ['', Validators.required],
148
- // nomuser: ['', Validators.required],
149
- // clave: ['', Validators.required],
150
- // })
425
+ }
151
426
  validacion(value) {
152
427
  const authForm = this.authForm();
153
428
  if (authForm.get(value).touched && authForm.get(value).errors) {
@@ -171,11 +446,11 @@ class AuthComponent {
171
446
  return false;
172
447
  };
173
448
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: AuthComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
174
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.25", type: AuthComponent, isStandalone: true, selector: "lib-auth-tsi", inputs: { production: { classPropertyName: "production", publicName: "production", isSignal: true, isRequired: false, transformFunction: null }, module: { classPropertyName: "module", publicName: "module", isSignal: true, isRequired: false, transformFunction: null }, versionApp: { classPropertyName: "versionApp", publicName: "versionApp", isSignal: true, isRequired: false, transformFunction: null }, product: { classPropertyName: "product", publicName: "product", isSignal: true, isRequired: false, transformFunction: null }, authForm: { classPropertyName: "authForm", publicName: "authForm", isSignal: true, isRequired: true, transformFunction: null }, aboutList: { classPropertyName: "aboutList", publicName: "aboutList", isSignal: true, isRequired: false, transformFunction: null }, showFloatingApp: { classPropertyName: "showFloatingApp", publicName: "showFloatingApp", isSignal: true, isRequired: false, transformFunction: null }, showFloatingUpdate: { classPropertyName: "showFloatingUpdate", publicName: "showFloatingUpdate", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { loginEvent: "loginEvent", beforeInstall: "beforeInstall" }, ngImport: i0, template: "<div class=\"auth-wrapper-login\">\r\n @let produccion = production();\r\n <div class=\"auth-panel-left\" [class.auth-panel-left--dev]=\"!produccion\">\r\n <span class=\"auth-blob auth-blob-1\"></span>\r\n <span class=\"auth-blob auth-blob-2\"></span>\r\n <span class=\"auth-blob auth-blob-3\"></span>\r\n <span class=\"auth-blob auth-blob-4\"></span>\r\n\r\n <div class=\"auth-brand-panel\">\r\n <div class=\"auth-brand-logo\">\r\n <img src=\"assets/images/logo-tsi-tres.png\" alt=\"TSI\" />\r\n </div>\r\n <h1 class=\"auth-brand-title\">{{module()}}</h1>\r\n <p class=\"auth-brand-subtitle\">Plataforma integrada de gesti\u00F3n<br>empresarial</p>\r\n\r\n <div class=\"auth-brand-divider\"></div>\r\n\r\n <div class=\"auth-brand-features\">\r\n @for (item of aboutList(); track $index) {\r\n <div class=\"auth-brand-feature\">\r\n <span class=\"feat-dot\"></span> {{item}}\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"auth-panel-right\" [class.auth-panel-right--dev]=\"!produccion\">\r\n <div class=\"auth-panel-bg\">\r\n <span class=\"auth-deco auth-deco-tl\"></span>\r\n <span class=\"auth-deco auth-deco-br\"></span>\r\n </div>\r\n\r\n <div class=\"auth-form-wrapper\">\r\n <div>\r\n @if (!produccion) {\r\n <div>\r\n <span class=\"auth-test-badge\">\r\n <span class=\"badge-dot\"></span> ENTORNO DE PRUEBAS\r\n </span>\r\n </div>\r\n }\r\n\r\n <div class=\"auth-card\">\r\n <h2 class=\"auth-card-title\">Bienvenido de vuelta</h2>\r\n <p class=\"auth-card-subtitle\">Ingresa tus credenciales para continuar</p>\r\n\r\n <form [formGroup]=\"authForm()\" id=\"loginform\">\r\n\r\n <p class=\"auth-hint\">\r\n <i class=\"fas fa-circle-info\"></i>\r\n Si piensas instalar la app, te recomendamos completar el RUC y Usuario antes, estos quedar\u00E1n guardados y siempre aparecer\u00E1n completos al abrirla.\r\n </p>\r\n\r\n <div class=\"auth-field\" [class.has-error]=\"validacion('ruc')\">\r\n <span class=\"auth-field-icon\"><i class=\"fas fa-building\"></i></span>\r\n <input type=\"text\" formControlName=\"ruc\" class=\"auth-input\" placeholder=\" \" maxlength=\"11\"\r\n id=\"f-ruc\" autocomplete=\"off\">\r\n <label for=\"f-ruc\" class=\"auth-label\">RUC</label>\r\n </div>\r\n @if (validacion('ruc')) {\r\n <p class=\"auth-error\" @fadeInOut>Ingresar RUC</p>\r\n }\r\n\r\n <div class=\"auth-field\" [class.has-error]=\"validacion('nomuser')\">\r\n <span class=\"auth-field-icon\"><i class=\"fas fa-user\"></i></span>\r\n <input type=\"text\" formControlName=\"nomuser\" class=\"auth-input\" placeholder=\" \" id=\"f-user\"\r\n autocomplete=\"off\">\r\n <label for=\"f-user\" class=\"auth-label\">Usuario</label>\r\n </div>\r\n @if (validacion('nomuser')) {\r\n <p class=\"auth-error\" @fadeInOut>Ingresar usuario</p>\r\n }\r\n\r\n <div class=\"auth-field\" [class.has-error]=\"validacion('clave')\">\r\n <span class=\"auth-field-icon\"><i class=\"fas fa-lock\"></i></span>\r\n <input [type]=\"showPassword() ? 'text' : 'password'\" formControlName=\"clave\"\r\n class=\"auth-input\" placeholder=\" \" id=\"f-clave\" autocomplete=\"off\" autocorrect=\"off\"\r\n autocapitalize=\"off\" spellcheck=\"false\">\r\n <label for=\"f-clave\" class=\"auth-label\">Contrase\u00F1a</label>\r\n <button type=\"button\" class=\"auth-toggle-pw\" (click)=\"togglePassword()\">\r\n <i [class]=\"showPassword() ? 'fas fa-eye' : 'fas fa-eye-slash'\"></i>\r\n </button>\r\n </div>\r\n @if (validacion('clave')) {\r\n <p class=\"auth-error\" @fadeInOut>Ingresar clave</p>\r\n }\r\n\r\n <button class=\"auth-btn mt-2\" [class.auth-btn--red]=\"!produccion\" (click)=\"login()\">\r\n Ingresar\r\n </button>\r\n\r\n <div class=\"auth-links\">\r\n <a [ngClass]=\"produccion ? 'blue_contrasena' : 'red_contrasena'\"\r\n (click)=\"recover()\">\u00BFOlvidaste tu contrase\u00F1a?</a>\r\n <a [ngClass]=\"produccion ? 'blue_contrasena' : 'red_contrasena'\"\r\n (click)=\"forget()\">\u00BFContrase\u00F1a vencida?</a>\r\n </div>\r\n\r\n </form>\r\n\r\n <div class=\"auth-version\">\r\n <span>v{{versionApp()}}</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n@if (showFloatingApp()) {\r\n<app-pwa-floating [appName]=\"module()\" (beforeInstall)=\"onBeforeInstall()\" />\r\n}\r\n@if (showFloatingUpdate()) {\r\n<app-refresh-floating />\r\n}", styles: ["", "@charset \"UTF-8\";.red_contrasena,.blue_contrasena{position:relative;display:inline-block;font-size:13px;text-decoration:none;padding-bottom:2px;transition:color .3s ease;cursor:pointer}.red_contrasena:after,.blue_contrasena:after{content:\"\";position:absolute;bottom:0;left:50%;width:0;height:1px;background-color:currentColor;transition:all .3s ease;transform:translate(-50%)}.red_contrasena:hover:after,.blue_contrasena:hover:after{width:60%}.red_contrasena{color:#d1326f}.red_contrasena:hover{color:#a82859}.blue_contrasena{color:#398bf7}.blue_contrasena:hover{color:#1e5fc4}.auth-wrapper-login{position:fixed;inset:0;display:grid;grid-template-columns:1.15fr .85fr;overflow:hidden;background:#060d1f}.auth-panel-left{position:relative;overflow:hidden;background:linear-gradient(145deg,#040a18,#0b1a3d 55%,#040e22);display:flex;align-items:center;justify-content:center;padding:48px 40px}.auth-panel-left:before{content:\"\";position:absolute;inset:0;background-image:radial-gradient(circle,rgba(255,255,255,.055) 1px,transparent 1px);background-size:26px 26px;z-index:1;pointer-events:none}.auth-panel-left:after{content:\"\";position:absolute;top:0;left:-120%;width:60%;height:100%;background:linear-gradient(90deg,transparent,rgba(57,139,247,.04),transparent);animation:panelSweep 7s ease-in-out infinite;z-index:1;pointer-events:none}.auth-blob{position:absolute;border-radius:50%;filter:blur(72px);z-index:0;pointer-events:none}.auth-blob-1{width:340px;height:340px;background:radial-gradient(circle,rgba(57,139,247,.45) 0%,transparent 70%);top:-90px;right:-70px;animation:blobDrift 11s ease-in-out infinite}.auth-blob-2{width:240px;height:240px;background:radial-gradient(circle,rgba(124,58,237,.4) 0%,transparent 70%);bottom:60px;left:-50px;animation:blobDrift 14s ease-in-out infinite reverse}.auth-blob-3{width:180px;height:180px;background:radial-gradient(circle,rgba(14,165,233,.35) 0%,transparent 70%);bottom:-50px;right:40px;animation:blobDrift 9s ease-in-out infinite;animation-delay:-4s}.auth-blob-4{width:120px;height:120px;background:radial-gradient(circle,rgba(209,50,111,.25) 0%,transparent 70%);top:50%;left:50%;transform:translate(-50%,-50%);animation:blobDrift 16s ease-in-out infinite;animation-delay:-8s}@keyframes blobDrift{0%,to{transform:translate(0) scale(1)}33%{transform:translate(14px,-20px) scale(1.05)}66%{transform:translate(-10px,12px) scale(.96)}}@keyframes panelSweep{0%{left:-120%}50%{left:160%}to{left:160%}}.auth-brand-panel{position:relative;z-index:2;text-align:center;color:#fff;max-width:340px}.auth-brand-logo{width:100px;height:100px;border-radius:50%;background:#ffffff0d;border:1px solid rgba(255,255,255,.1);display:flex;align-items:center;justify-content:center;margin:0 auto 28px;box-shadow:0 0 0 14px #398bf70f,0 0 50px #398bf733;backdrop-filter:blur(8px)}.auth-brand-logo img{width:64px;height:64px;object-fit:contain;filter:brightness(1.05) drop-shadow(0 0 8px rgba(57,139,247,.4))}.auth-brand-title{font-size:30px;font-weight:700;letter-spacing:-.5px;margin-bottom:10px;background:linear-gradient(135deg,#fff 20%,#93c5fd 80%);-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text}.auth-brand-subtitle{font-size:14px;color:#ffffff73;line-height:1.65;margin-bottom:40px;letter-spacing:.2px}.auth-brand-features{display:flex;flex-direction:column;gap:14px;text-align:left}.auth-brand-feature{display:flex;align-items:center;gap:12px;font-size:13px;color:#fff9}.auth-brand-feature .feat-dot{flex-shrink:0;width:7px;height:7px;border-radius:50%;background:#398bf7;box-shadow:0 0 10px #398bf7b3}.auth-brand-divider{width:60px;height:2px;background:linear-gradient(90deg,transparent,#398bf7,transparent);margin:28px auto 32px;border-radius:2px}.auth-panel-left--dev{background:linear-gradient(145deg,#18040b,#3d0b1d 55%,#220409)}.auth-panel-left--dev:after{background:linear-gradient(90deg,transparent,rgba(209,50,111,.05),transparent)}.auth-panel-left--dev .auth-blob-1{background:radial-gradient(circle,rgba(220,38,38,.52) 0%,transparent 70%)}.auth-panel-left--dev .auth-blob-2{background:radial-gradient(circle,rgba(219,39,119,.44) 0%,transparent 70%)}.auth-panel-left--dev .auth-blob-3{background:radial-gradient(circle,rgba(239,68,68,.38) 0%,transparent 70%)}.auth-panel-left--dev .auth-blob-4{background:radial-gradient(circle,rgba(249,115,22,.28) 0%,transparent 70%)}.auth-panel-left--dev .auth-brand-logo{box-shadow:0 0 0 14px #d1326f12,0 0 50px #d1326f38}.auth-panel-left--dev .auth-brand-logo img{filter:brightness(1.05) drop-shadow(0 0 8px rgba(209,50,111,.45))}.auth-panel-left--dev .auth-brand-title{background:linear-gradient(135deg,#fff 20%,#fca5a5 80%);-webkit-background-clip:text;background-clip:text}.auth-panel-left--dev .auth-brand-divider{background:linear-gradient(90deg,transparent,rgb(209,50,111),transparent)}.auth-panel-left--dev .feat-dot{background:#d1326f;box-shadow:0 0 10px #d1326fb8}.auth-panel-right{position:relative;overflow:hidden;background:var(--background-login)}.auth-panel-right:before{content:\"\";position:absolute;inset:0;background-image:repeating-linear-gradient(-55deg,transparent 0px,transparent 22px,rgba(57,139,247,.045) 22px,rgba(57,139,247,.045) 23px);animation:authLinesMove 10s linear infinite;pointer-events:none;z-index:0}.auth-panel-right:after{content:\"\";position:absolute;top:0;bottom:0;left:-25%;width:25%;background:linear-gradient(90deg,transparent 0%,rgba(57,139,247,.02) 30%,rgba(57,139,247,.045) 50%,rgba(57,139,247,.02) 70%,transparent 100%);animation:authScanLine 7s ease-in-out infinite;animation-delay:3.5s;pointer-events:none;z-index:0}@keyframes authLinesMove{0%{transform:translate(0)}to{transform:translate(46px,46px)}}@keyframes authScanLine{0%{left:-25%}50%{left:120%}to{left:120%}}.auth-panel-bg{position:absolute;inset:0;pointer-events:none;z-index:0;overflow:hidden}.auth-deco{position:absolute;border-radius:50%;pointer-events:none;filter:blur(70px)}.auth-deco-tl{width:300px;height:300px;top:0;left:-120px;transform:translateY(-40%);background:radial-gradient(circle,rgba(57,139,247,.12) 0%,transparent 70%);animation:authOrbPulse 6s ease-in-out infinite}.auth-deco-br{width:340px;height:340px;bottom:0;right:-120px;transform:translateY(40%);background:radial-gradient(circle,rgba(124,58,237,.1) 0%,transparent 70%);animation:authOrbPulse 8s ease-in-out infinite;animation-delay:-4s}@keyframes authOrbPulse{0%,to{opacity:.7}50%{opacity:1}}.auth-form-wrapper{position:absolute;inset:0;overflow-y:auto;overflow-x:hidden;display:flex;flex-direction:column;align-items:center;z-index:1}.auth-form-wrapper>div{width:100%;max-width:420px;margin:auto;padding:36px 16px;box-sizing:border-box}.auth-panel-right--dev:before{background-image:repeating-linear-gradient(-55deg,transparent 0px,transparent 22px,rgba(209,50,111,.05) 22px,rgba(209,50,111,.05) 23px)}.auth-panel-right--dev:after{background:linear-gradient(90deg,transparent 0%,rgba(209,50,111,.02) 30%,rgba(209,50,111,.045) 50%,rgba(209,50,111,.02) 70%,transparent 100%)}.auth-panel-right--dev .auth-deco-tl{background:radial-gradient(circle,rgba(209,50,111,.12) 0%,transparent 70%)}.auth-panel-right--dev .auth-deco-br{background:radial-gradient(circle,rgba(239,68,68,.1) 0%,transparent 70%)}.auth-test-badge{display:inline-flex;align-items:center;gap:7px;background:#d1326f14;border:1px solid rgba(209,50,111,.25);color:#d1326f;font-size:10.5px;font-weight:700;padding:5px 12px;border-radius:20px;margin-bottom:18px;letter-spacing:.8px}.auth-test-badge .badge-dot{width:6px;height:6px;border-radius:50%;background:#d1326f;animation:badgePulse 1.6s ease-in-out infinite;flex-shrink:0}@keyframes badgePulse{0%,to{opacity:1;transform:scale(1)}50%{opacity:.45;transform:scale(.75)}}.auth-card{background:var(--background-card);border-radius:20px;padding:36px 32px 28px;box-shadow:0 4px 28px #00000014;border:1px solid var(--border-color-modal)}.auth-card-title{font-size:22px;font-weight:700;color:var(--text-color);margin-bottom:4px;letter-spacing:-.3px}.auth-card-subtitle{font-size:13px;color:var(--placeholder-color);margin-bottom:26px}.auth-field{position:relative;margin-bottom:1rem}.auth-field .auth-field-icon{position:absolute;left:13px;top:50%;transform:translateY(-50%);color:var(--placeholder-color);font-size:13px;z-index:2;pointer-events:none;transition:color .2s}.auth-field .auth-input{width:100%;padding:15px 40px 15px 37px;background:var(--background-input);border:1.5px solid var(--font-border-input);border-radius:10px;font-size:14px;color:var(--color-input);outline:none;transition:border-color .2s,box-shadow .2s,background .2s}.auth-field .auth-input::placeholder{color:transparent}.auth-field .auth-input:focus{border-color:#398bf7;box-shadow:0 0 0 3.5px #398bf721;background:var(--background-focus-input)}.auth-field .auth-input:focus~.auth-label{top:0;font-size:11px!important;color:#398bf7!important;background:var(--background-card);padding:0 4px;transform:translateY(-50%)}.auth-field .auth-input:focus~.auth-field-icon{color:#398bf7}.auth-field .auth-input:not(:placeholder-shown)~.auth-label{top:0;font-size:11px!important;background:var(--background-card);padding:0 4px;transform:translateY(-50%)}.auth-field .auth-label{position:absolute;left:35px;top:50%;transform:translateY(-50%);color:var(--placeholder-color)!important;font-size:13px!important;font-weight:400!important;pointer-events:none;transition:top .15s ease,font-size .15s ease,color .15s ease,padding .15s ease,background .15s ease;background:transparent;z-index:1;text-align:left!important}.auth-field .auth-toggle-pw{position:absolute;right:10px;top:50%;transform:translateY(-50%);background:none;border:none;color:var(--placeholder-color);cursor:pointer;padding:4px 6px;font-size:13px;z-index:2;line-height:1;transition:color .2s}.auth-field .auth-toggle-pw:hover{color:#398bf7}.auth-field.has-error .auth-input{border-color:#dc3545;box-shadow:none}.auth-field.has-error .auth-field-icon{color:#dc3545}.auth-select{width:100%;padding:13px 14px;background:var(--background-input);border:1.5px solid var(--font-border-input);border-radius:10px;font-size:14px;color:var(--color-input);outline:none;transition:border-color .2s,box-shadow .2s;margin-bottom:1rem;cursor:pointer}.auth-select:focus{border-color:#398bf7;box-shadow:0 0 0 3.5px #398bf721}.auth-btn{width:100%;padding:13px;border:none;border-radius:10px;font-size:14px;font-weight:600;cursor:pointer;transition:transform .15s ease,box-shadow .2s ease,opacity .2s;background:linear-gradient(135deg,#398bf7,#1e5fc4);color:#fff;letter-spacing:.3px;margin-bottom:10px;display:block}.auth-btn:hover:not(:disabled){transform:translateY(-1px);box-shadow:0 5px 18px #398bf761}.auth-btn:active:not(:disabled){transform:translateY(0)}.auth-btn:disabled{opacity:.55;cursor:not-allowed}.auth-btn.auth-btn--red{background:linear-gradient(135deg,#d1326f,#a82859)}.auth-btn.auth-btn--red:hover:not(:disabled){box-shadow:0 5px 18px #d1326f61}.auth-btn.auth-btn--outline{background:transparent;border:1.5px solid var(--font-border-input);color:var(--text-color)}.auth-btn.auth-btn--outline:hover:not(:disabled){background:var(--background-btn-light-hover);box-shadow:none;transform:none}.auth-links{display:flex;flex-direction:column;align-items:center;gap:10px;margin-top:16px;padding-top:16px;border-top:1px solid var(--border-color-modal)}.auth-version{text-align:right;margin-top:14px;padding-top:12px;border-top:1px solid var(--border-color-modal)}.auth-version span{font-size:11px;color:var(--placeholder-color)}.auth-error{font-size:11.5px;color:#dc3545;margin:-6px 0 10px 2px;padding:0}.auth-hint{display:flex;align-items:flex-start;gap:6px;font-size:11.5px;color:var(--placeholder-color);margin:-6px 0 14px 2px;padding:0;line-height:1.35}.auth-hint i{margin-top:2px;flex-shrink:0}.auth-validation-list{margin:-4px 0 12px;padding:0;list-style:none}.auth-validation-list li{font-size:11.5px;color:#dc3545;padding:2px 0}.auth-validation-list li:before{content:\"\\2715 \";font-size:10px}.auth-desc{font-size:13px;color:var(--placeholder-color);margin-bottom:20px;line-height:1.65}.auth-section-title{font-size:15px;font-weight:600;color:var(--text-color);margin-bottom:20px}.font-12{font-size:12px}.form-control:focus{border-color:#0199ff9a!important;box-shadow:0 0 5px .2px #65befa44!important}@media(max-width:900px){.auth-wrapper-login{grid-template-columns:1fr;grid-template-rows:auto 1fr;overflow-y:auto;overflow-x:hidden}.auth-panel-left{padding:14px 24px;justify-content:center}.auth-panel-left .auth-brand-subtitle,.auth-panel-left .auth-brand-features,.auth-panel-left .auth-brand-divider{display:none!important}.auth-panel-left .auth-brand-panel{display:flex!important;flex-direction:row!important;align-items:center;gap:0;text-align:left;max-width:none;width:100%;justify-content:center}.auth-panel-left .auth-brand-logo{width:52px;height:52px;margin:0;flex-shrink:0}.auth-panel-left .auth-brand-logo img{width:34px;height:34px}.auth-panel-left .auth-brand-title{font-size:20px;margin-bottom:0;margin-left:.5rem;flex-shrink:1}.auth-panel-right:after{inset:-25% 0 auto;width:100%;height:25%;background:linear-gradient(180deg,transparent 0%,rgba(57,139,247,.02) 30%,rgba(57,139,247,.045) 50%,rgba(57,139,247,.02) 70%,transparent 100%);animation:authScanLineV 7s ease-in-out infinite;animation-delay:3.5s}.auth-panel-right--dev:after{background:linear-gradient(180deg,transparent 0%,rgba(209,50,111,.02) 30%,rgba(209,50,111,.045) 50%,rgba(209,50,111,.02) 70%,transparent 100%)}}@keyframes authScanLineV{0%{top:-25%}50%{top:120%}to{top:120%}}@media(max-width:480px){.auth-panel-left{padding:12px 16px}.auth-panel-left .auth-brand-logo{width:44px;height:44px}.auth-panel-left .auth-brand-logo img{width:28px;height:28px}.auth-panel-left .auth-brand-title{font-size:17px}.auth-form-wrapper>div{padding:20px 12px}.auth-card{padding:24px 18px 20px;border-radius:16px}.font-12{font-size:10px!important}}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: PwaFloatingComponent, selector: "app-pwa-floating", inputs: ["appName", "logo", "chipLabel"], outputs: ["beforeInstall", "guideClosed"] }, { kind: "component", type: RefreshFloatingComponent, selector: "app-refresh-floating" }], animations: [fadeInOut] });
449
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.25", type: AuthComponent, isStandalone: true, selector: "lib-auth-tsi", inputs: { production: { classPropertyName: "production", publicName: "production", isSignal: true, isRequired: false, transformFunction: null }, module: { classPropertyName: "module", publicName: "module", isSignal: true, isRequired: false, transformFunction: null }, versionApp: { classPropertyName: "versionApp", publicName: "versionApp", isSignal: true, isRequired: false, transformFunction: null }, product: { classPropertyName: "product", publicName: "product", isSignal: true, isRequired: false, transformFunction: null }, authForm: { classPropertyName: "authForm", publicName: "authForm", isSignal: true, isRequired: true, transformFunction: null }, aboutList: { classPropertyName: "aboutList", publicName: "aboutList", isSignal: true, isRequired: false, transformFunction: null }, showFloatingApp: { classPropertyName: "showFloatingApp", publicName: "showFloatingApp", isSignal: true, isRequired: false, transformFunction: null }, showFloatingUpdate: { classPropertyName: "showFloatingUpdate", publicName: "showFloatingUpdate", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { loginEvent: "loginEvent", beforeInstall: "beforeInstall" }, viewQueries: [{ propertyName: "dialogMfa", first: true, predicate: ["dialogMfa"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"auth-wrapper-login\">\r\n @let produccion = production();\r\n <div class=\"auth-panel-left\" [class.auth-panel-left--dev]=\"!produccion\">\r\n <span class=\"auth-blob auth-blob-1\"></span>\r\n <span class=\"auth-blob auth-blob-2\"></span>\r\n <span class=\"auth-blob auth-blob-3\"></span>\r\n <span class=\"auth-blob auth-blob-4\"></span>\r\n\r\n <div class=\"auth-brand-panel\">\r\n <div class=\"auth-brand-logo\">\r\n <img src=\"assets/images/logo-tsi-tres.png\" alt=\"TSI\" />\r\n </div>\r\n <h1 class=\"auth-brand-title\">{{module()}}</h1>\r\n <p class=\"auth-brand-subtitle\">Plataforma integrada de gesti\u00F3n<br>empresarial</p>\r\n\r\n <div class=\"auth-brand-divider\"></div>\r\n\r\n <div class=\"auth-brand-features\">\r\n @for (item of aboutList(); track $index) {\r\n <div class=\"auth-brand-feature\">\r\n <span class=\"feat-dot\"></span> {{item}}\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"auth-panel-right\" [class.auth-panel-right--dev]=\"!produccion\">\r\n <div class=\"auth-panel-bg\">\r\n <span class=\"auth-deco auth-deco-tl\"></span>\r\n <span class=\"auth-deco auth-deco-br\"></span>\r\n </div>\r\n\r\n <div class=\"auth-form-wrapper\">\r\n <div>\r\n @if (!produccion) {\r\n <div>\r\n <span class=\"auth-test-badge\">\r\n <span class=\"badge-dot\"></span> ENTORNO DE PRUEBAS\r\n </span>\r\n </div>\r\n }\r\n\r\n <div class=\"auth-card\">\r\n <h2 class=\"auth-card-title\">Bienvenido de vuelta</h2>\r\n <p class=\"auth-card-subtitle\">Ingresa tus credenciales para continuar</p>\r\n\r\n <form [formGroup]=\"authForm()\" id=\"loginform\">\r\n\r\n <p class=\"auth-hint\">\r\n <i class=\"fas fa-circle-info\"></i>\r\n Si piensas instalar la app, te recomendamos completar el RUC y Usuario antes, estos quedar\u00E1n guardados y siempre aparecer\u00E1n completos al abrirla.\r\n </p>\r\n\r\n <div class=\"auth-field\" [class.has-error]=\"validacion('ruc')\">\r\n <span class=\"auth-field-icon\"><i class=\"fas fa-building\"></i></span>\r\n <input type=\"text\" formControlName=\"ruc\" class=\"auth-input\" placeholder=\" \" maxlength=\"11\"\r\n id=\"f-ruc\" autocomplete=\"off\">\r\n <label for=\"f-ruc\" class=\"auth-label\">RUC</label>\r\n </div>\r\n @if (validacion('ruc')) {\r\n <p class=\"auth-error\" @fadeInOut>Ingresar RUC</p>\r\n }\r\n\r\n <div class=\"auth-field\" [class.has-error]=\"validacion('nomuser')\">\r\n <span class=\"auth-field-icon\"><i class=\"fas fa-user\"></i></span>\r\n <input type=\"text\" formControlName=\"nomuser\" class=\"auth-input\" placeholder=\" \" id=\"f-user\"\r\n autocomplete=\"off\">\r\n <label for=\"f-user\" class=\"auth-label\">Usuario</label>\r\n </div>\r\n @if (validacion('nomuser')) {\r\n <p class=\"auth-error\" @fadeInOut>Ingresar usuario</p>\r\n }\r\n\r\n <div class=\"auth-field\" [class.has-error]=\"validacion('clave')\">\r\n <span class=\"auth-field-icon\"><i class=\"fas fa-lock\"></i></span>\r\n <input [type]=\"showPassword() ? 'text' : 'password'\" formControlName=\"clave\"\r\n class=\"auth-input\" placeholder=\" \" id=\"f-clave\" autocomplete=\"off\" autocorrect=\"off\"\r\n autocapitalize=\"off\" spellcheck=\"false\">\r\n <label for=\"f-clave\" class=\"auth-label\">Contrase\u00F1a</label>\r\n <button type=\"button\" class=\"auth-toggle-pw\" (click)=\"togglePassword()\">\r\n <i [class]=\"showPassword() ? 'fas fa-eye' : 'fas fa-eye-slash'\"></i>\r\n </button>\r\n </div>\r\n @if (validacion('clave')) {\r\n <p class=\"auth-error\" @fadeInOut>Ingresar clave</p>\r\n }\r\n\r\n <button class=\"auth-btn mt-2\" [class.auth-btn--red]=\"!produccion\" [disabled]=\"isIngresando()\"\r\n (click)=\"login()\">\r\n {{ isIngresando() ? 'Ingresando\u2026' : 'Ingresar' }}\r\n </button>\r\n\r\n <div class=\"auth-links\">\r\n <a [ngClass]=\"produccion ? 'blue_contrasena' : 'red_contrasena'\"\r\n (click)=\"recover()\">\u00BFOlvidaste tu contrase\u00F1a?</a>\r\n <a [ngClass]=\"produccion ? 'blue_contrasena' : 'red_contrasena'\"\r\n (click)=\"forget()\">\u00BFContrase\u00F1a vencida?</a>\r\n </div>\r\n\r\n </form>\r\n\r\n <div class=\"auth-version\">\r\n <span>v{{versionApp()}}</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<dialog #dialogMfa class=\"auth-mfa-dialog\" (cancel)=\"$event.preventDefault()\">\r\n @if (pasoMfa(); as paso) {\r\n <lib-md-verificar-mfa [challenge]=\"paso.challenge\" (verificado)=\"onMfaVerificado()\"\r\n (cancelado)=\"onMfaCancelado()\" />\r\n }\r\n</dialog>\r\n\r\n@if (showFloatingApp()) {\r\n<app-pwa-floating [appName]=\"module()\" (beforeInstall)=\"onBeforeInstall()\" />\r\n}\r\n@if (showFloatingUpdate()) {\r\n<app-refresh-floating />\r\n}", styles: [".auth-mfa-dialog{width:min(440px,100vw - 32px);max-height:calc(100vh - 32px);padding:28px 28px 24px;border:1px solid var(--border-color-modal);border-radius:20px;background:var(--background-card);color:var(--text-color);box-shadow:0 20px 60px #0000004d}.auth-mfa-dialog::backdrop{background:#0f172a8c;backdrop-filter:blur(2px)}.auth-mfa-dialog[open]{animation:auth-mfa-entrar .26s cubic-bezier(.16,1,.3,1) both}.auth-mfa-dialog[open]::backdrop{animation:auth-mfa-fondo-entrar .26s ease-out both}.auth-mfa-dialog--cerrando[open]{animation:auth-mfa-salir .18s cubic-bezier(.4,0,1,1) both}.auth-mfa-dialog--cerrando[open]::backdrop{animation:auth-mfa-fondo-salir .18s ease-in both}@keyframes auth-mfa-entrar{0%{opacity:0;transform:translateY(16px) scale(.96)}to{opacity:1;transform:none}}@keyframes auth-mfa-salir{0%{opacity:1;transform:none}to{opacity:0;transform:translateY(8px) scale(.97)}}@keyframes auth-mfa-fondo-entrar{0%{opacity:0}to{opacity:1}}@keyframes auth-mfa-fondo-salir{0%{opacity:1}to{opacity:0}}@keyframes auth-mfa-fundido-entrar{0%{opacity:0}to{opacity:1}}@keyframes auth-mfa-fundido-salir{0%{opacity:1}to{opacity:0}}@media(prefers-reduced-motion:reduce){.auth-mfa-dialog[open]{animation:auth-mfa-fundido-entrar .12s linear both}.auth-mfa-dialog--cerrando[open]{animation:auth-mfa-fundido-salir .12s linear both}}\n", "@charset \"UTF-8\";.red_contrasena,.blue_contrasena{position:relative;display:inline-block;font-size:13px;text-decoration:none;padding-bottom:2px;transition:color .3s ease;cursor:pointer}.red_contrasena:after,.blue_contrasena:after{content:\"\";position:absolute;bottom:0;left:50%;width:0;height:1px;background-color:currentColor;transition:all .3s ease;transform:translate(-50%)}.red_contrasena:hover:after,.blue_contrasena:hover:after{width:60%}.red_contrasena{color:#d1326f}.red_contrasena:hover{color:#a82859}.blue_contrasena{color:#398bf7}.blue_contrasena:hover{color:#1e5fc4}.auth-wrapper-login{position:fixed;inset:0;display:grid;grid-template-columns:1.15fr .85fr;overflow:hidden;background:#060d1f}.auth-panel-left{position:relative;overflow:hidden;background:linear-gradient(145deg,#040a18,#0b1a3d 55%,#040e22);display:flex;align-items:center;justify-content:center;padding:48px 40px}.auth-panel-left:before{content:\"\";position:absolute;inset:0;background-image:radial-gradient(circle,rgba(255,255,255,.055) 1px,transparent 1px);background-size:26px 26px;z-index:1;pointer-events:none}.auth-panel-left:after{content:\"\";position:absolute;top:0;left:-120%;width:60%;height:100%;background:linear-gradient(90deg,transparent,rgba(57,139,247,.04),transparent);animation:panelSweep 7s ease-in-out infinite;z-index:1;pointer-events:none}.auth-blob{position:absolute;border-radius:50%;filter:blur(72px);z-index:0;pointer-events:none}.auth-blob-1{width:340px;height:340px;background:radial-gradient(circle,rgba(57,139,247,.45) 0%,transparent 70%);top:-90px;right:-70px;animation:blobDrift 11s ease-in-out infinite}.auth-blob-2{width:240px;height:240px;background:radial-gradient(circle,rgba(124,58,237,.4) 0%,transparent 70%);bottom:60px;left:-50px;animation:blobDrift 14s ease-in-out infinite reverse}.auth-blob-3{width:180px;height:180px;background:radial-gradient(circle,rgba(14,165,233,.35) 0%,transparent 70%);bottom:-50px;right:40px;animation:blobDrift 9s ease-in-out infinite;animation-delay:-4s}.auth-blob-4{width:120px;height:120px;background:radial-gradient(circle,rgba(209,50,111,.25) 0%,transparent 70%);top:50%;left:50%;transform:translate(-50%,-50%);animation:blobDrift 16s ease-in-out infinite;animation-delay:-8s}@keyframes blobDrift{0%,to{transform:translate(0) scale(1)}33%{transform:translate(14px,-20px) scale(1.05)}66%{transform:translate(-10px,12px) scale(.96)}}@keyframes panelSweep{0%{left:-120%}50%{left:160%}to{left:160%}}.auth-brand-panel{position:relative;z-index:2;text-align:center;color:#fff;max-width:340px}.auth-brand-logo{width:100px;height:100px;border-radius:50%;background:#ffffff0d;border:1px solid rgba(255,255,255,.1);display:flex;align-items:center;justify-content:center;margin:0 auto 28px;box-shadow:0 0 0 14px #398bf70f,0 0 50px #398bf733;backdrop-filter:blur(8px)}.auth-brand-logo img{width:64px;height:64px;object-fit:contain;filter:brightness(1.05) drop-shadow(0 0 8px rgba(57,139,247,.4))}.auth-brand-title{font-size:30px;font-weight:700;letter-spacing:-.5px;margin-bottom:10px;background:linear-gradient(135deg,#fff 20%,#93c5fd 80%);-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text}.auth-brand-subtitle{font-size:14px;color:#ffffff73;line-height:1.65;margin-bottom:40px;letter-spacing:.2px}.auth-brand-features{display:flex;flex-direction:column;gap:14px;text-align:left}.auth-brand-feature{display:flex;align-items:center;gap:12px;font-size:13px;color:#fff9}.auth-brand-feature .feat-dot{flex-shrink:0;width:7px;height:7px;border-radius:50%;background:#398bf7;box-shadow:0 0 10px #398bf7b3}.auth-brand-divider{width:60px;height:2px;background:linear-gradient(90deg,transparent,#398bf7,transparent);margin:28px auto 32px;border-radius:2px}.auth-panel-left--dev{background:linear-gradient(145deg,#18040b,#3d0b1d 55%,#220409)}.auth-panel-left--dev:after{background:linear-gradient(90deg,transparent,rgba(209,50,111,.05),transparent)}.auth-panel-left--dev .auth-blob-1{background:radial-gradient(circle,rgba(220,38,38,.52) 0%,transparent 70%)}.auth-panel-left--dev .auth-blob-2{background:radial-gradient(circle,rgba(219,39,119,.44) 0%,transparent 70%)}.auth-panel-left--dev .auth-blob-3{background:radial-gradient(circle,rgba(239,68,68,.38) 0%,transparent 70%)}.auth-panel-left--dev .auth-blob-4{background:radial-gradient(circle,rgba(249,115,22,.28) 0%,transparent 70%)}.auth-panel-left--dev .auth-brand-logo{box-shadow:0 0 0 14px #d1326f12,0 0 50px #d1326f38}.auth-panel-left--dev .auth-brand-logo img{filter:brightness(1.05) drop-shadow(0 0 8px rgba(209,50,111,.45))}.auth-panel-left--dev .auth-brand-title{background:linear-gradient(135deg,#fff 20%,#fca5a5 80%);-webkit-background-clip:text;background-clip:text}.auth-panel-left--dev .auth-brand-divider{background:linear-gradient(90deg,transparent,rgb(209,50,111),transparent)}.auth-panel-left--dev .feat-dot{background:#d1326f;box-shadow:0 0 10px #d1326fb8}.auth-panel-right{position:relative;overflow:hidden;background:var(--background-login)}.auth-panel-right:before{content:\"\";position:absolute;inset:0;background-image:repeating-linear-gradient(-55deg,transparent 0px,transparent 22px,rgba(57,139,247,.045) 22px,rgba(57,139,247,.045) 23px);animation:authLinesMove 10s linear infinite;pointer-events:none;z-index:0}.auth-panel-right:after{content:\"\";position:absolute;top:0;bottom:0;left:-25%;width:25%;background:linear-gradient(90deg,transparent 0%,rgba(57,139,247,.02) 30%,rgba(57,139,247,.045) 50%,rgba(57,139,247,.02) 70%,transparent 100%);animation:authScanLine 7s ease-in-out infinite;animation-delay:3.5s;pointer-events:none;z-index:0}@keyframes authLinesMove{0%{transform:translate(0)}to{transform:translate(46px,46px)}}@keyframes authScanLine{0%{left:-25%}50%{left:120%}to{left:120%}}.auth-panel-bg{position:absolute;inset:0;pointer-events:none;z-index:0;overflow:hidden}.auth-deco{position:absolute;border-radius:50%;pointer-events:none;filter:blur(70px)}.auth-deco-tl{width:300px;height:300px;top:0;left:-120px;transform:translateY(-40%);background:radial-gradient(circle,rgba(57,139,247,.12) 0%,transparent 70%);animation:authOrbPulse 6s ease-in-out infinite}.auth-deco-br{width:340px;height:340px;bottom:0;right:-120px;transform:translateY(40%);background:radial-gradient(circle,rgba(124,58,237,.1) 0%,transparent 70%);animation:authOrbPulse 8s ease-in-out infinite;animation-delay:-4s}@keyframes authOrbPulse{0%,to{opacity:.7}50%{opacity:1}}.auth-form-wrapper{position:absolute;inset:0;overflow-y:auto;overflow-x:hidden;display:flex;flex-direction:column;align-items:center;z-index:1}.auth-form-wrapper>div{width:100%;max-width:420px;margin:auto;padding:36px 16px;box-sizing:border-box}.auth-panel-right--dev:before{background-image:repeating-linear-gradient(-55deg,transparent 0px,transparent 22px,rgba(209,50,111,.05) 22px,rgba(209,50,111,.05) 23px)}.auth-panel-right--dev:after{background:linear-gradient(90deg,transparent 0%,rgba(209,50,111,.02) 30%,rgba(209,50,111,.045) 50%,rgba(209,50,111,.02) 70%,transparent 100%)}.auth-panel-right--dev .auth-deco-tl{background:radial-gradient(circle,rgba(209,50,111,.12) 0%,transparent 70%)}.auth-panel-right--dev .auth-deco-br{background:radial-gradient(circle,rgba(239,68,68,.1) 0%,transparent 70%)}.auth-test-badge{display:inline-flex;align-items:center;gap:7px;background:#d1326f14;border:1px solid rgba(209,50,111,.25);color:#d1326f;font-size:10.5px;font-weight:700;padding:5px 12px;border-radius:20px;margin-bottom:18px;letter-spacing:.8px}.auth-test-badge .badge-dot{width:6px;height:6px;border-radius:50%;background:#d1326f;animation:badgePulse 1.6s ease-in-out infinite;flex-shrink:0}@keyframes badgePulse{0%,to{opacity:1;transform:scale(1)}50%{opacity:.45;transform:scale(.75)}}.auth-card{background:var(--background-card);border-radius:20px;padding:36px 32px 28px;box-shadow:0 4px 28px #00000014;border:1px solid var(--border-color-modal)}.auth-card-title{font-size:22px;font-weight:700;color:var(--text-color);margin-bottom:4px;letter-spacing:-.3px}.auth-card-subtitle{font-size:13px;color:var(--placeholder-color);margin-bottom:26px}.auth-field{position:relative;margin-bottom:1rem}.auth-field .auth-field-icon{position:absolute;left:13px;top:50%;transform:translateY(-50%);color:var(--placeholder-color);font-size:13px;z-index:2;pointer-events:none;transition:color .2s}.auth-field .auth-input{width:100%;padding:15px 40px 15px 37px;background:var(--background-input);border:1.5px solid var(--font-border-input);border-radius:10px;font-size:14px;color:var(--color-input);outline:none;transition:border-color .2s,box-shadow .2s,background .2s}.auth-field .auth-input::placeholder{color:transparent}.auth-field .auth-input:focus{border-color:#398bf7;box-shadow:0 0 0 3.5px #398bf721;background:var(--background-focus-input)}.auth-field .auth-input:focus~.auth-label{top:0;font-size:11px!important;color:#398bf7!important;background:var(--background-card);padding:0 4px;transform:translateY(-50%)}.auth-field .auth-input:focus~.auth-field-icon{color:#398bf7}.auth-field .auth-input:not(:placeholder-shown)~.auth-label{top:0;font-size:11px!important;background:var(--background-card);padding:0 4px;transform:translateY(-50%)}.auth-field .auth-label{position:absolute;left:35px;top:50%;transform:translateY(-50%);color:var(--placeholder-color)!important;font-size:13px!important;font-weight:400!important;pointer-events:none;transition:top .15s ease,font-size .15s ease,color .15s ease,padding .15s ease,background .15s ease;background:transparent;z-index:1;text-align:left!important}.auth-field .auth-toggle-pw{position:absolute;right:10px;top:50%;transform:translateY(-50%);background:none;border:none;color:var(--placeholder-color);cursor:pointer;padding:4px 6px;font-size:13px;z-index:2;line-height:1;transition:color .2s}.auth-field .auth-toggle-pw:hover{color:#398bf7}.auth-field.has-error .auth-input{border-color:#dc3545;box-shadow:none}.auth-field.has-error .auth-field-icon{color:#dc3545}.auth-select{width:100%;padding:13px 14px;background:var(--background-input);border:1.5px solid var(--font-border-input);border-radius:10px;font-size:14px;color:var(--color-input);outline:none;transition:border-color .2s,box-shadow .2s;margin-bottom:1rem;cursor:pointer}.auth-select:focus{border-color:#398bf7;box-shadow:0 0 0 3.5px #398bf721}.auth-btn{width:100%;padding:13px;border:none;border-radius:10px;font-size:14px;font-weight:600;cursor:pointer;transition:transform .15s ease,box-shadow .2s ease,opacity .2s;background:linear-gradient(135deg,#398bf7,#1e5fc4);color:#fff;letter-spacing:.3px;margin-bottom:10px;display:block}.auth-btn:hover:not(:disabled){transform:translateY(-1px);box-shadow:0 5px 18px #398bf761}.auth-btn:active:not(:disabled){transform:translateY(0)}.auth-btn:disabled{opacity:.55;cursor:not-allowed}.auth-btn.auth-btn--red{background:linear-gradient(135deg,#d1326f,#a82859)}.auth-btn.auth-btn--red:hover:not(:disabled){box-shadow:0 5px 18px #d1326f61}.auth-btn.auth-btn--outline{background:transparent;border:1.5px solid var(--font-border-input);color:var(--text-color)}.auth-btn.auth-btn--outline:hover:not(:disabled){background:var(--background-btn-light-hover);box-shadow:none;transform:none}.auth-links{display:flex;flex-direction:column;align-items:center;gap:10px;margin-top:16px;padding-top:16px;border-top:1px solid var(--border-color-modal)}.auth-version{text-align:right;margin-top:14px;padding-top:12px;border-top:1px solid var(--border-color-modal)}.auth-version span{font-size:11px;color:var(--placeholder-color)}.auth-error{font-size:11.5px;color:#dc3545;margin:-6px 0 10px 2px;padding:0}.auth-hint{display:flex;align-items:flex-start;gap:6px;font-size:11.5px;color:var(--placeholder-color);margin:-6px 0 14px 2px;padding:0;line-height:1.35}.auth-hint i{margin-top:2px;flex-shrink:0}.auth-validation-list{margin:-4px 0 12px;padding:0;list-style:none}.auth-validation-list li{font-size:11.5px;color:#dc3545;padding:2px 0}.auth-validation-list li:before{content:\"\\2715 \";font-size:10px}.auth-desc{font-size:13px;color:var(--placeholder-color);margin-bottom:20px;line-height:1.65}.auth-section-title{font-size:15px;font-weight:600;color:var(--text-color);margin-bottom:20px}.font-12{font-size:12px}.form-control:focus{border-color:#0199ff9a!important;box-shadow:0 0 5px .2px #65befa44!important}@media(max-width:900px){.auth-wrapper-login{grid-template-columns:1fr;grid-template-rows:auto 1fr;overflow-y:auto;overflow-x:hidden}.auth-panel-left{padding:14px 24px;justify-content:center}.auth-panel-left .auth-brand-subtitle,.auth-panel-left .auth-brand-features,.auth-panel-left .auth-brand-divider{display:none!important}.auth-panel-left .auth-brand-panel{display:flex!important;flex-direction:row!important;align-items:center;gap:0;text-align:left;max-width:none;width:100%;justify-content:center}.auth-panel-left .auth-brand-logo{width:52px;height:52px;margin:0;flex-shrink:0}.auth-panel-left .auth-brand-logo img{width:34px;height:34px}.auth-panel-left .auth-brand-title{font-size:20px;margin-bottom:0;margin-left:.5rem;flex-shrink:1}.auth-panel-right:after{inset:-25% 0 auto;width:100%;height:25%;background:linear-gradient(180deg,transparent 0%,rgba(57,139,247,.02) 30%,rgba(57,139,247,.045) 50%,rgba(57,139,247,.02) 70%,transparent 100%);animation:authScanLineV 7s ease-in-out infinite;animation-delay:3.5s}.auth-panel-right--dev:after{background:linear-gradient(180deg,transparent 0%,rgba(209,50,111,.02) 30%,rgba(209,50,111,.045) 50%,rgba(209,50,111,.02) 70%,transparent 100%)}}@keyframes authScanLineV{0%{top:-25%}50%{top:120%}to{top:120%}}@media(max-width:480px){.auth-panel-left{padding:12px 16px}.auth-panel-left .auth-brand-logo{width:44px;height:44px}.auth-panel-left .auth-brand-logo img{width:28px;height:28px}.auth-panel-left .auth-brand-title{font-size:17px}.auth-form-wrapper>div{padding:20px 12px}.auth-card{padding:24px 18px 20px;border-radius:16px}.font-12{font-size:10px!important}}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: PwaFloatingComponent, selector: "app-pwa-floating", inputs: ["appName", "logo", "chipLabel"], outputs: ["beforeInstall", "guideClosed"] }, { kind: "component", type: RefreshFloatingComponent, selector: "app-refresh-floating" }, { kind: "component", type: MdVerificarMfaComponent, selector: "lib-md-verificar-mfa", inputs: ["challenge", "titulo", "showCancelar"], outputs: ["verificado", "cancelado"] }], animations: [fadeInOut] });
175
450
  }
176
451
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: AuthComponent, decorators: [{
177
452
  type: Component,
178
- args: [{ selector: 'lib-auth-tsi', imports: [NgClass, ReactiveFormsModule, PwaFloatingComponent, RefreshFloatingComponent], animations: [fadeInOut], template: "<div class=\"auth-wrapper-login\">\r\n @let produccion = production();\r\n <div class=\"auth-panel-left\" [class.auth-panel-left--dev]=\"!produccion\">\r\n <span class=\"auth-blob auth-blob-1\"></span>\r\n <span class=\"auth-blob auth-blob-2\"></span>\r\n <span class=\"auth-blob auth-blob-3\"></span>\r\n <span class=\"auth-blob auth-blob-4\"></span>\r\n\r\n <div class=\"auth-brand-panel\">\r\n <div class=\"auth-brand-logo\">\r\n <img src=\"assets/images/logo-tsi-tres.png\" alt=\"TSI\" />\r\n </div>\r\n <h1 class=\"auth-brand-title\">{{module()}}</h1>\r\n <p class=\"auth-brand-subtitle\">Plataforma integrada de gesti\u00F3n<br>empresarial</p>\r\n\r\n <div class=\"auth-brand-divider\"></div>\r\n\r\n <div class=\"auth-brand-features\">\r\n @for (item of aboutList(); track $index) {\r\n <div class=\"auth-brand-feature\">\r\n <span class=\"feat-dot\"></span> {{item}}\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"auth-panel-right\" [class.auth-panel-right--dev]=\"!produccion\">\r\n <div class=\"auth-panel-bg\">\r\n <span class=\"auth-deco auth-deco-tl\"></span>\r\n <span class=\"auth-deco auth-deco-br\"></span>\r\n </div>\r\n\r\n <div class=\"auth-form-wrapper\">\r\n <div>\r\n @if (!produccion) {\r\n <div>\r\n <span class=\"auth-test-badge\">\r\n <span class=\"badge-dot\"></span> ENTORNO DE PRUEBAS\r\n </span>\r\n </div>\r\n }\r\n\r\n <div class=\"auth-card\">\r\n <h2 class=\"auth-card-title\">Bienvenido de vuelta</h2>\r\n <p class=\"auth-card-subtitle\">Ingresa tus credenciales para continuar</p>\r\n\r\n <form [formGroup]=\"authForm()\" id=\"loginform\">\r\n\r\n <p class=\"auth-hint\">\r\n <i class=\"fas fa-circle-info\"></i>\r\n Si piensas instalar la app, te recomendamos completar el RUC y Usuario antes, estos quedar\u00E1n guardados y siempre aparecer\u00E1n completos al abrirla.\r\n </p>\r\n\r\n <div class=\"auth-field\" [class.has-error]=\"validacion('ruc')\">\r\n <span class=\"auth-field-icon\"><i class=\"fas fa-building\"></i></span>\r\n <input type=\"text\" formControlName=\"ruc\" class=\"auth-input\" placeholder=\" \" maxlength=\"11\"\r\n id=\"f-ruc\" autocomplete=\"off\">\r\n <label for=\"f-ruc\" class=\"auth-label\">RUC</label>\r\n </div>\r\n @if (validacion('ruc')) {\r\n <p class=\"auth-error\" @fadeInOut>Ingresar RUC</p>\r\n }\r\n\r\n <div class=\"auth-field\" [class.has-error]=\"validacion('nomuser')\">\r\n <span class=\"auth-field-icon\"><i class=\"fas fa-user\"></i></span>\r\n <input type=\"text\" formControlName=\"nomuser\" class=\"auth-input\" placeholder=\" \" id=\"f-user\"\r\n autocomplete=\"off\">\r\n <label for=\"f-user\" class=\"auth-label\">Usuario</label>\r\n </div>\r\n @if (validacion('nomuser')) {\r\n <p class=\"auth-error\" @fadeInOut>Ingresar usuario</p>\r\n }\r\n\r\n <div class=\"auth-field\" [class.has-error]=\"validacion('clave')\">\r\n <span class=\"auth-field-icon\"><i class=\"fas fa-lock\"></i></span>\r\n <input [type]=\"showPassword() ? 'text' : 'password'\" formControlName=\"clave\"\r\n class=\"auth-input\" placeholder=\" \" id=\"f-clave\" autocomplete=\"off\" autocorrect=\"off\"\r\n autocapitalize=\"off\" spellcheck=\"false\">\r\n <label for=\"f-clave\" class=\"auth-label\">Contrase\u00F1a</label>\r\n <button type=\"button\" class=\"auth-toggle-pw\" (click)=\"togglePassword()\">\r\n <i [class]=\"showPassword() ? 'fas fa-eye' : 'fas fa-eye-slash'\"></i>\r\n </button>\r\n </div>\r\n @if (validacion('clave')) {\r\n <p class=\"auth-error\" @fadeInOut>Ingresar clave</p>\r\n }\r\n\r\n <button class=\"auth-btn mt-2\" [class.auth-btn--red]=\"!produccion\" (click)=\"login()\">\r\n Ingresar\r\n </button>\r\n\r\n <div class=\"auth-links\">\r\n <a [ngClass]=\"produccion ? 'blue_contrasena' : 'red_contrasena'\"\r\n (click)=\"recover()\">\u00BFOlvidaste tu contrase\u00F1a?</a>\r\n <a [ngClass]=\"produccion ? 'blue_contrasena' : 'red_contrasena'\"\r\n (click)=\"forget()\">\u00BFContrase\u00F1a vencida?</a>\r\n </div>\r\n\r\n </form>\r\n\r\n <div class=\"auth-version\">\r\n <span>v{{versionApp()}}</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n@if (showFloatingApp()) {\r\n<app-pwa-floating [appName]=\"module()\" (beforeInstall)=\"onBeforeInstall()\" />\r\n}\r\n@if (showFloatingUpdate()) {\r\n<app-refresh-floating />\r\n}", styles: ["@charset \"UTF-8\";.red_contrasena,.blue_contrasena{position:relative;display:inline-block;font-size:13px;text-decoration:none;padding-bottom:2px;transition:color .3s ease;cursor:pointer}.red_contrasena:after,.blue_contrasena:after{content:\"\";position:absolute;bottom:0;left:50%;width:0;height:1px;background-color:currentColor;transition:all .3s ease;transform:translate(-50%)}.red_contrasena:hover:after,.blue_contrasena:hover:after{width:60%}.red_contrasena{color:#d1326f}.red_contrasena:hover{color:#a82859}.blue_contrasena{color:#398bf7}.blue_contrasena:hover{color:#1e5fc4}.auth-wrapper-login{position:fixed;inset:0;display:grid;grid-template-columns:1.15fr .85fr;overflow:hidden;background:#060d1f}.auth-panel-left{position:relative;overflow:hidden;background:linear-gradient(145deg,#040a18,#0b1a3d 55%,#040e22);display:flex;align-items:center;justify-content:center;padding:48px 40px}.auth-panel-left:before{content:\"\";position:absolute;inset:0;background-image:radial-gradient(circle,rgba(255,255,255,.055) 1px,transparent 1px);background-size:26px 26px;z-index:1;pointer-events:none}.auth-panel-left:after{content:\"\";position:absolute;top:0;left:-120%;width:60%;height:100%;background:linear-gradient(90deg,transparent,rgba(57,139,247,.04),transparent);animation:panelSweep 7s ease-in-out infinite;z-index:1;pointer-events:none}.auth-blob{position:absolute;border-radius:50%;filter:blur(72px);z-index:0;pointer-events:none}.auth-blob-1{width:340px;height:340px;background:radial-gradient(circle,rgba(57,139,247,.45) 0%,transparent 70%);top:-90px;right:-70px;animation:blobDrift 11s ease-in-out infinite}.auth-blob-2{width:240px;height:240px;background:radial-gradient(circle,rgba(124,58,237,.4) 0%,transparent 70%);bottom:60px;left:-50px;animation:blobDrift 14s ease-in-out infinite reverse}.auth-blob-3{width:180px;height:180px;background:radial-gradient(circle,rgba(14,165,233,.35) 0%,transparent 70%);bottom:-50px;right:40px;animation:blobDrift 9s ease-in-out infinite;animation-delay:-4s}.auth-blob-4{width:120px;height:120px;background:radial-gradient(circle,rgba(209,50,111,.25) 0%,transparent 70%);top:50%;left:50%;transform:translate(-50%,-50%);animation:blobDrift 16s ease-in-out infinite;animation-delay:-8s}@keyframes blobDrift{0%,to{transform:translate(0) scale(1)}33%{transform:translate(14px,-20px) scale(1.05)}66%{transform:translate(-10px,12px) scale(.96)}}@keyframes panelSweep{0%{left:-120%}50%{left:160%}to{left:160%}}.auth-brand-panel{position:relative;z-index:2;text-align:center;color:#fff;max-width:340px}.auth-brand-logo{width:100px;height:100px;border-radius:50%;background:#ffffff0d;border:1px solid rgba(255,255,255,.1);display:flex;align-items:center;justify-content:center;margin:0 auto 28px;box-shadow:0 0 0 14px #398bf70f,0 0 50px #398bf733;backdrop-filter:blur(8px)}.auth-brand-logo img{width:64px;height:64px;object-fit:contain;filter:brightness(1.05) drop-shadow(0 0 8px rgba(57,139,247,.4))}.auth-brand-title{font-size:30px;font-weight:700;letter-spacing:-.5px;margin-bottom:10px;background:linear-gradient(135deg,#fff 20%,#93c5fd 80%);-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text}.auth-brand-subtitle{font-size:14px;color:#ffffff73;line-height:1.65;margin-bottom:40px;letter-spacing:.2px}.auth-brand-features{display:flex;flex-direction:column;gap:14px;text-align:left}.auth-brand-feature{display:flex;align-items:center;gap:12px;font-size:13px;color:#fff9}.auth-brand-feature .feat-dot{flex-shrink:0;width:7px;height:7px;border-radius:50%;background:#398bf7;box-shadow:0 0 10px #398bf7b3}.auth-brand-divider{width:60px;height:2px;background:linear-gradient(90deg,transparent,#398bf7,transparent);margin:28px auto 32px;border-radius:2px}.auth-panel-left--dev{background:linear-gradient(145deg,#18040b,#3d0b1d 55%,#220409)}.auth-panel-left--dev:after{background:linear-gradient(90deg,transparent,rgba(209,50,111,.05),transparent)}.auth-panel-left--dev .auth-blob-1{background:radial-gradient(circle,rgba(220,38,38,.52) 0%,transparent 70%)}.auth-panel-left--dev .auth-blob-2{background:radial-gradient(circle,rgba(219,39,119,.44) 0%,transparent 70%)}.auth-panel-left--dev .auth-blob-3{background:radial-gradient(circle,rgba(239,68,68,.38) 0%,transparent 70%)}.auth-panel-left--dev .auth-blob-4{background:radial-gradient(circle,rgba(249,115,22,.28) 0%,transparent 70%)}.auth-panel-left--dev .auth-brand-logo{box-shadow:0 0 0 14px #d1326f12,0 0 50px #d1326f38}.auth-panel-left--dev .auth-brand-logo img{filter:brightness(1.05) drop-shadow(0 0 8px rgba(209,50,111,.45))}.auth-panel-left--dev .auth-brand-title{background:linear-gradient(135deg,#fff 20%,#fca5a5 80%);-webkit-background-clip:text;background-clip:text}.auth-panel-left--dev .auth-brand-divider{background:linear-gradient(90deg,transparent,rgb(209,50,111),transparent)}.auth-panel-left--dev .feat-dot{background:#d1326f;box-shadow:0 0 10px #d1326fb8}.auth-panel-right{position:relative;overflow:hidden;background:var(--background-login)}.auth-panel-right:before{content:\"\";position:absolute;inset:0;background-image:repeating-linear-gradient(-55deg,transparent 0px,transparent 22px,rgba(57,139,247,.045) 22px,rgba(57,139,247,.045) 23px);animation:authLinesMove 10s linear infinite;pointer-events:none;z-index:0}.auth-panel-right:after{content:\"\";position:absolute;top:0;bottom:0;left:-25%;width:25%;background:linear-gradient(90deg,transparent 0%,rgba(57,139,247,.02) 30%,rgba(57,139,247,.045) 50%,rgba(57,139,247,.02) 70%,transparent 100%);animation:authScanLine 7s ease-in-out infinite;animation-delay:3.5s;pointer-events:none;z-index:0}@keyframes authLinesMove{0%{transform:translate(0)}to{transform:translate(46px,46px)}}@keyframes authScanLine{0%{left:-25%}50%{left:120%}to{left:120%}}.auth-panel-bg{position:absolute;inset:0;pointer-events:none;z-index:0;overflow:hidden}.auth-deco{position:absolute;border-radius:50%;pointer-events:none;filter:blur(70px)}.auth-deco-tl{width:300px;height:300px;top:0;left:-120px;transform:translateY(-40%);background:radial-gradient(circle,rgba(57,139,247,.12) 0%,transparent 70%);animation:authOrbPulse 6s ease-in-out infinite}.auth-deco-br{width:340px;height:340px;bottom:0;right:-120px;transform:translateY(40%);background:radial-gradient(circle,rgba(124,58,237,.1) 0%,transparent 70%);animation:authOrbPulse 8s ease-in-out infinite;animation-delay:-4s}@keyframes authOrbPulse{0%,to{opacity:.7}50%{opacity:1}}.auth-form-wrapper{position:absolute;inset:0;overflow-y:auto;overflow-x:hidden;display:flex;flex-direction:column;align-items:center;z-index:1}.auth-form-wrapper>div{width:100%;max-width:420px;margin:auto;padding:36px 16px;box-sizing:border-box}.auth-panel-right--dev:before{background-image:repeating-linear-gradient(-55deg,transparent 0px,transparent 22px,rgba(209,50,111,.05) 22px,rgba(209,50,111,.05) 23px)}.auth-panel-right--dev:after{background:linear-gradient(90deg,transparent 0%,rgba(209,50,111,.02) 30%,rgba(209,50,111,.045) 50%,rgba(209,50,111,.02) 70%,transparent 100%)}.auth-panel-right--dev .auth-deco-tl{background:radial-gradient(circle,rgba(209,50,111,.12) 0%,transparent 70%)}.auth-panel-right--dev .auth-deco-br{background:radial-gradient(circle,rgba(239,68,68,.1) 0%,transparent 70%)}.auth-test-badge{display:inline-flex;align-items:center;gap:7px;background:#d1326f14;border:1px solid rgba(209,50,111,.25);color:#d1326f;font-size:10.5px;font-weight:700;padding:5px 12px;border-radius:20px;margin-bottom:18px;letter-spacing:.8px}.auth-test-badge .badge-dot{width:6px;height:6px;border-radius:50%;background:#d1326f;animation:badgePulse 1.6s ease-in-out infinite;flex-shrink:0}@keyframes badgePulse{0%,to{opacity:1;transform:scale(1)}50%{opacity:.45;transform:scale(.75)}}.auth-card{background:var(--background-card);border-radius:20px;padding:36px 32px 28px;box-shadow:0 4px 28px #00000014;border:1px solid var(--border-color-modal)}.auth-card-title{font-size:22px;font-weight:700;color:var(--text-color);margin-bottom:4px;letter-spacing:-.3px}.auth-card-subtitle{font-size:13px;color:var(--placeholder-color);margin-bottom:26px}.auth-field{position:relative;margin-bottom:1rem}.auth-field .auth-field-icon{position:absolute;left:13px;top:50%;transform:translateY(-50%);color:var(--placeholder-color);font-size:13px;z-index:2;pointer-events:none;transition:color .2s}.auth-field .auth-input{width:100%;padding:15px 40px 15px 37px;background:var(--background-input);border:1.5px solid var(--font-border-input);border-radius:10px;font-size:14px;color:var(--color-input);outline:none;transition:border-color .2s,box-shadow .2s,background .2s}.auth-field .auth-input::placeholder{color:transparent}.auth-field .auth-input:focus{border-color:#398bf7;box-shadow:0 0 0 3.5px #398bf721;background:var(--background-focus-input)}.auth-field .auth-input:focus~.auth-label{top:0;font-size:11px!important;color:#398bf7!important;background:var(--background-card);padding:0 4px;transform:translateY(-50%)}.auth-field .auth-input:focus~.auth-field-icon{color:#398bf7}.auth-field .auth-input:not(:placeholder-shown)~.auth-label{top:0;font-size:11px!important;background:var(--background-card);padding:0 4px;transform:translateY(-50%)}.auth-field .auth-label{position:absolute;left:35px;top:50%;transform:translateY(-50%);color:var(--placeholder-color)!important;font-size:13px!important;font-weight:400!important;pointer-events:none;transition:top .15s ease,font-size .15s ease,color .15s ease,padding .15s ease,background .15s ease;background:transparent;z-index:1;text-align:left!important}.auth-field .auth-toggle-pw{position:absolute;right:10px;top:50%;transform:translateY(-50%);background:none;border:none;color:var(--placeholder-color);cursor:pointer;padding:4px 6px;font-size:13px;z-index:2;line-height:1;transition:color .2s}.auth-field .auth-toggle-pw:hover{color:#398bf7}.auth-field.has-error .auth-input{border-color:#dc3545;box-shadow:none}.auth-field.has-error .auth-field-icon{color:#dc3545}.auth-select{width:100%;padding:13px 14px;background:var(--background-input);border:1.5px solid var(--font-border-input);border-radius:10px;font-size:14px;color:var(--color-input);outline:none;transition:border-color .2s,box-shadow .2s;margin-bottom:1rem;cursor:pointer}.auth-select:focus{border-color:#398bf7;box-shadow:0 0 0 3.5px #398bf721}.auth-btn{width:100%;padding:13px;border:none;border-radius:10px;font-size:14px;font-weight:600;cursor:pointer;transition:transform .15s ease,box-shadow .2s ease,opacity .2s;background:linear-gradient(135deg,#398bf7,#1e5fc4);color:#fff;letter-spacing:.3px;margin-bottom:10px;display:block}.auth-btn:hover:not(:disabled){transform:translateY(-1px);box-shadow:0 5px 18px #398bf761}.auth-btn:active:not(:disabled){transform:translateY(0)}.auth-btn:disabled{opacity:.55;cursor:not-allowed}.auth-btn.auth-btn--red{background:linear-gradient(135deg,#d1326f,#a82859)}.auth-btn.auth-btn--red:hover:not(:disabled){box-shadow:0 5px 18px #d1326f61}.auth-btn.auth-btn--outline{background:transparent;border:1.5px solid var(--font-border-input);color:var(--text-color)}.auth-btn.auth-btn--outline:hover:not(:disabled){background:var(--background-btn-light-hover);box-shadow:none;transform:none}.auth-links{display:flex;flex-direction:column;align-items:center;gap:10px;margin-top:16px;padding-top:16px;border-top:1px solid var(--border-color-modal)}.auth-version{text-align:right;margin-top:14px;padding-top:12px;border-top:1px solid var(--border-color-modal)}.auth-version span{font-size:11px;color:var(--placeholder-color)}.auth-error{font-size:11.5px;color:#dc3545;margin:-6px 0 10px 2px;padding:0}.auth-hint{display:flex;align-items:flex-start;gap:6px;font-size:11.5px;color:var(--placeholder-color);margin:-6px 0 14px 2px;padding:0;line-height:1.35}.auth-hint i{margin-top:2px;flex-shrink:0}.auth-validation-list{margin:-4px 0 12px;padding:0;list-style:none}.auth-validation-list li{font-size:11.5px;color:#dc3545;padding:2px 0}.auth-validation-list li:before{content:\"\\2715 \";font-size:10px}.auth-desc{font-size:13px;color:var(--placeholder-color);margin-bottom:20px;line-height:1.65}.auth-section-title{font-size:15px;font-weight:600;color:var(--text-color);margin-bottom:20px}.font-12{font-size:12px}.form-control:focus{border-color:#0199ff9a!important;box-shadow:0 0 5px .2px #65befa44!important}@media(max-width:900px){.auth-wrapper-login{grid-template-columns:1fr;grid-template-rows:auto 1fr;overflow-y:auto;overflow-x:hidden}.auth-panel-left{padding:14px 24px;justify-content:center}.auth-panel-left .auth-brand-subtitle,.auth-panel-left .auth-brand-features,.auth-panel-left .auth-brand-divider{display:none!important}.auth-panel-left .auth-brand-panel{display:flex!important;flex-direction:row!important;align-items:center;gap:0;text-align:left;max-width:none;width:100%;justify-content:center}.auth-panel-left .auth-brand-logo{width:52px;height:52px;margin:0;flex-shrink:0}.auth-panel-left .auth-brand-logo img{width:34px;height:34px}.auth-panel-left .auth-brand-title{font-size:20px;margin-bottom:0;margin-left:.5rem;flex-shrink:1}.auth-panel-right:after{inset:-25% 0 auto;width:100%;height:25%;background:linear-gradient(180deg,transparent 0%,rgba(57,139,247,.02) 30%,rgba(57,139,247,.045) 50%,rgba(57,139,247,.02) 70%,transparent 100%);animation:authScanLineV 7s ease-in-out infinite;animation-delay:3.5s}.auth-panel-right--dev:after{background:linear-gradient(180deg,transparent 0%,rgba(209,50,111,.02) 30%,rgba(209,50,111,.045) 50%,rgba(209,50,111,.02) 70%,transparent 100%)}}@keyframes authScanLineV{0%{top:-25%}50%{top:120%}to{top:120%}}@media(max-width:480px){.auth-panel-left{padding:12px 16px}.auth-panel-left .auth-brand-logo{width:44px;height:44px}.auth-panel-left .auth-brand-logo img{width:28px;height:28px}.auth-panel-left .auth-brand-title{font-size:17px}.auth-form-wrapper>div{padding:20px 12px}.auth-card{padding:24px 18px 20px;border-radius:16px}.font-12{font-size:10px!important}}\n"] }]
453
+ args: [{ selector: 'lib-auth-tsi', imports: [NgClass, ReactiveFormsModule, PwaFloatingComponent, RefreshFloatingComponent, MdVerificarMfaComponent], animations: [fadeInOut], template: "<div class=\"auth-wrapper-login\">\r\n @let produccion = production();\r\n <div class=\"auth-panel-left\" [class.auth-panel-left--dev]=\"!produccion\">\r\n <span class=\"auth-blob auth-blob-1\"></span>\r\n <span class=\"auth-blob auth-blob-2\"></span>\r\n <span class=\"auth-blob auth-blob-3\"></span>\r\n <span class=\"auth-blob auth-blob-4\"></span>\r\n\r\n <div class=\"auth-brand-panel\">\r\n <div class=\"auth-brand-logo\">\r\n <img src=\"assets/images/logo-tsi-tres.png\" alt=\"TSI\" />\r\n </div>\r\n <h1 class=\"auth-brand-title\">{{module()}}</h1>\r\n <p class=\"auth-brand-subtitle\">Plataforma integrada de gesti\u00F3n<br>empresarial</p>\r\n\r\n <div class=\"auth-brand-divider\"></div>\r\n\r\n <div class=\"auth-brand-features\">\r\n @for (item of aboutList(); track $index) {\r\n <div class=\"auth-brand-feature\">\r\n <span class=\"feat-dot\"></span> {{item}}\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"auth-panel-right\" [class.auth-panel-right--dev]=\"!produccion\">\r\n <div class=\"auth-panel-bg\">\r\n <span class=\"auth-deco auth-deco-tl\"></span>\r\n <span class=\"auth-deco auth-deco-br\"></span>\r\n </div>\r\n\r\n <div class=\"auth-form-wrapper\">\r\n <div>\r\n @if (!produccion) {\r\n <div>\r\n <span class=\"auth-test-badge\">\r\n <span class=\"badge-dot\"></span> ENTORNO DE PRUEBAS\r\n </span>\r\n </div>\r\n }\r\n\r\n <div class=\"auth-card\">\r\n <h2 class=\"auth-card-title\">Bienvenido de vuelta</h2>\r\n <p class=\"auth-card-subtitle\">Ingresa tus credenciales para continuar</p>\r\n\r\n <form [formGroup]=\"authForm()\" id=\"loginform\">\r\n\r\n <p class=\"auth-hint\">\r\n <i class=\"fas fa-circle-info\"></i>\r\n Si piensas instalar la app, te recomendamos completar el RUC y Usuario antes, estos quedar\u00E1n guardados y siempre aparecer\u00E1n completos al abrirla.\r\n </p>\r\n\r\n <div class=\"auth-field\" [class.has-error]=\"validacion('ruc')\">\r\n <span class=\"auth-field-icon\"><i class=\"fas fa-building\"></i></span>\r\n <input type=\"text\" formControlName=\"ruc\" class=\"auth-input\" placeholder=\" \" maxlength=\"11\"\r\n id=\"f-ruc\" autocomplete=\"off\">\r\n <label for=\"f-ruc\" class=\"auth-label\">RUC</label>\r\n </div>\r\n @if (validacion('ruc')) {\r\n <p class=\"auth-error\" @fadeInOut>Ingresar RUC</p>\r\n }\r\n\r\n <div class=\"auth-field\" [class.has-error]=\"validacion('nomuser')\">\r\n <span class=\"auth-field-icon\"><i class=\"fas fa-user\"></i></span>\r\n <input type=\"text\" formControlName=\"nomuser\" class=\"auth-input\" placeholder=\" \" id=\"f-user\"\r\n autocomplete=\"off\">\r\n <label for=\"f-user\" class=\"auth-label\">Usuario</label>\r\n </div>\r\n @if (validacion('nomuser')) {\r\n <p class=\"auth-error\" @fadeInOut>Ingresar usuario</p>\r\n }\r\n\r\n <div class=\"auth-field\" [class.has-error]=\"validacion('clave')\">\r\n <span class=\"auth-field-icon\"><i class=\"fas fa-lock\"></i></span>\r\n <input [type]=\"showPassword() ? 'text' : 'password'\" formControlName=\"clave\"\r\n class=\"auth-input\" placeholder=\" \" id=\"f-clave\" autocomplete=\"off\" autocorrect=\"off\"\r\n autocapitalize=\"off\" spellcheck=\"false\">\r\n <label for=\"f-clave\" class=\"auth-label\">Contrase\u00F1a</label>\r\n <button type=\"button\" class=\"auth-toggle-pw\" (click)=\"togglePassword()\">\r\n <i [class]=\"showPassword() ? 'fas fa-eye' : 'fas fa-eye-slash'\"></i>\r\n </button>\r\n </div>\r\n @if (validacion('clave')) {\r\n <p class=\"auth-error\" @fadeInOut>Ingresar clave</p>\r\n }\r\n\r\n <button class=\"auth-btn mt-2\" [class.auth-btn--red]=\"!produccion\" [disabled]=\"isIngresando()\"\r\n (click)=\"login()\">\r\n {{ isIngresando() ? 'Ingresando\u2026' : 'Ingresar' }}\r\n </button>\r\n\r\n <div class=\"auth-links\">\r\n <a [ngClass]=\"produccion ? 'blue_contrasena' : 'red_contrasena'\"\r\n (click)=\"recover()\">\u00BFOlvidaste tu contrase\u00F1a?</a>\r\n <a [ngClass]=\"produccion ? 'blue_contrasena' : 'red_contrasena'\"\r\n (click)=\"forget()\">\u00BFContrase\u00F1a vencida?</a>\r\n </div>\r\n\r\n </form>\r\n\r\n <div class=\"auth-version\">\r\n <span>v{{versionApp()}}</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<dialog #dialogMfa class=\"auth-mfa-dialog\" (cancel)=\"$event.preventDefault()\">\r\n @if (pasoMfa(); as paso) {\r\n <lib-md-verificar-mfa [challenge]=\"paso.challenge\" (verificado)=\"onMfaVerificado()\"\r\n (cancelado)=\"onMfaCancelado()\" />\r\n }\r\n</dialog>\r\n\r\n@if (showFloatingApp()) {\r\n<app-pwa-floating [appName]=\"module()\" (beforeInstall)=\"onBeforeInstall()\" />\r\n}\r\n@if (showFloatingUpdate()) {\r\n<app-refresh-floating />\r\n}", styles: [".auth-mfa-dialog{width:min(440px,100vw - 32px);max-height:calc(100vh - 32px);padding:28px 28px 24px;border:1px solid var(--border-color-modal);border-radius:20px;background:var(--background-card);color:var(--text-color);box-shadow:0 20px 60px #0000004d}.auth-mfa-dialog::backdrop{background:#0f172a8c;backdrop-filter:blur(2px)}.auth-mfa-dialog[open]{animation:auth-mfa-entrar .26s cubic-bezier(.16,1,.3,1) both}.auth-mfa-dialog[open]::backdrop{animation:auth-mfa-fondo-entrar .26s ease-out both}.auth-mfa-dialog--cerrando[open]{animation:auth-mfa-salir .18s cubic-bezier(.4,0,1,1) both}.auth-mfa-dialog--cerrando[open]::backdrop{animation:auth-mfa-fondo-salir .18s ease-in both}@keyframes auth-mfa-entrar{0%{opacity:0;transform:translateY(16px) scale(.96)}to{opacity:1;transform:none}}@keyframes auth-mfa-salir{0%{opacity:1;transform:none}to{opacity:0;transform:translateY(8px) scale(.97)}}@keyframes auth-mfa-fondo-entrar{0%{opacity:0}to{opacity:1}}@keyframes auth-mfa-fondo-salir{0%{opacity:1}to{opacity:0}}@keyframes auth-mfa-fundido-entrar{0%{opacity:0}to{opacity:1}}@keyframes auth-mfa-fundido-salir{0%{opacity:1}to{opacity:0}}@media(prefers-reduced-motion:reduce){.auth-mfa-dialog[open]{animation:auth-mfa-fundido-entrar .12s linear both}.auth-mfa-dialog--cerrando[open]{animation:auth-mfa-fundido-salir .12s linear both}}\n", "@charset \"UTF-8\";.red_contrasena,.blue_contrasena{position:relative;display:inline-block;font-size:13px;text-decoration:none;padding-bottom:2px;transition:color .3s ease;cursor:pointer}.red_contrasena:after,.blue_contrasena:after{content:\"\";position:absolute;bottom:0;left:50%;width:0;height:1px;background-color:currentColor;transition:all .3s ease;transform:translate(-50%)}.red_contrasena:hover:after,.blue_contrasena:hover:after{width:60%}.red_contrasena{color:#d1326f}.red_contrasena:hover{color:#a82859}.blue_contrasena{color:#398bf7}.blue_contrasena:hover{color:#1e5fc4}.auth-wrapper-login{position:fixed;inset:0;display:grid;grid-template-columns:1.15fr .85fr;overflow:hidden;background:#060d1f}.auth-panel-left{position:relative;overflow:hidden;background:linear-gradient(145deg,#040a18,#0b1a3d 55%,#040e22);display:flex;align-items:center;justify-content:center;padding:48px 40px}.auth-panel-left:before{content:\"\";position:absolute;inset:0;background-image:radial-gradient(circle,rgba(255,255,255,.055) 1px,transparent 1px);background-size:26px 26px;z-index:1;pointer-events:none}.auth-panel-left:after{content:\"\";position:absolute;top:0;left:-120%;width:60%;height:100%;background:linear-gradient(90deg,transparent,rgba(57,139,247,.04),transparent);animation:panelSweep 7s ease-in-out infinite;z-index:1;pointer-events:none}.auth-blob{position:absolute;border-radius:50%;filter:blur(72px);z-index:0;pointer-events:none}.auth-blob-1{width:340px;height:340px;background:radial-gradient(circle,rgba(57,139,247,.45) 0%,transparent 70%);top:-90px;right:-70px;animation:blobDrift 11s ease-in-out infinite}.auth-blob-2{width:240px;height:240px;background:radial-gradient(circle,rgba(124,58,237,.4) 0%,transparent 70%);bottom:60px;left:-50px;animation:blobDrift 14s ease-in-out infinite reverse}.auth-blob-3{width:180px;height:180px;background:radial-gradient(circle,rgba(14,165,233,.35) 0%,transparent 70%);bottom:-50px;right:40px;animation:blobDrift 9s ease-in-out infinite;animation-delay:-4s}.auth-blob-4{width:120px;height:120px;background:radial-gradient(circle,rgba(209,50,111,.25) 0%,transparent 70%);top:50%;left:50%;transform:translate(-50%,-50%);animation:blobDrift 16s ease-in-out infinite;animation-delay:-8s}@keyframes blobDrift{0%,to{transform:translate(0) scale(1)}33%{transform:translate(14px,-20px) scale(1.05)}66%{transform:translate(-10px,12px) scale(.96)}}@keyframes panelSweep{0%{left:-120%}50%{left:160%}to{left:160%}}.auth-brand-panel{position:relative;z-index:2;text-align:center;color:#fff;max-width:340px}.auth-brand-logo{width:100px;height:100px;border-radius:50%;background:#ffffff0d;border:1px solid rgba(255,255,255,.1);display:flex;align-items:center;justify-content:center;margin:0 auto 28px;box-shadow:0 0 0 14px #398bf70f,0 0 50px #398bf733;backdrop-filter:blur(8px)}.auth-brand-logo img{width:64px;height:64px;object-fit:contain;filter:brightness(1.05) drop-shadow(0 0 8px rgba(57,139,247,.4))}.auth-brand-title{font-size:30px;font-weight:700;letter-spacing:-.5px;margin-bottom:10px;background:linear-gradient(135deg,#fff 20%,#93c5fd 80%);-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text}.auth-brand-subtitle{font-size:14px;color:#ffffff73;line-height:1.65;margin-bottom:40px;letter-spacing:.2px}.auth-brand-features{display:flex;flex-direction:column;gap:14px;text-align:left}.auth-brand-feature{display:flex;align-items:center;gap:12px;font-size:13px;color:#fff9}.auth-brand-feature .feat-dot{flex-shrink:0;width:7px;height:7px;border-radius:50%;background:#398bf7;box-shadow:0 0 10px #398bf7b3}.auth-brand-divider{width:60px;height:2px;background:linear-gradient(90deg,transparent,#398bf7,transparent);margin:28px auto 32px;border-radius:2px}.auth-panel-left--dev{background:linear-gradient(145deg,#18040b,#3d0b1d 55%,#220409)}.auth-panel-left--dev:after{background:linear-gradient(90deg,transparent,rgba(209,50,111,.05),transparent)}.auth-panel-left--dev .auth-blob-1{background:radial-gradient(circle,rgba(220,38,38,.52) 0%,transparent 70%)}.auth-panel-left--dev .auth-blob-2{background:radial-gradient(circle,rgba(219,39,119,.44) 0%,transparent 70%)}.auth-panel-left--dev .auth-blob-3{background:radial-gradient(circle,rgba(239,68,68,.38) 0%,transparent 70%)}.auth-panel-left--dev .auth-blob-4{background:radial-gradient(circle,rgba(249,115,22,.28) 0%,transparent 70%)}.auth-panel-left--dev .auth-brand-logo{box-shadow:0 0 0 14px #d1326f12,0 0 50px #d1326f38}.auth-panel-left--dev .auth-brand-logo img{filter:brightness(1.05) drop-shadow(0 0 8px rgba(209,50,111,.45))}.auth-panel-left--dev .auth-brand-title{background:linear-gradient(135deg,#fff 20%,#fca5a5 80%);-webkit-background-clip:text;background-clip:text}.auth-panel-left--dev .auth-brand-divider{background:linear-gradient(90deg,transparent,rgb(209,50,111),transparent)}.auth-panel-left--dev .feat-dot{background:#d1326f;box-shadow:0 0 10px #d1326fb8}.auth-panel-right{position:relative;overflow:hidden;background:var(--background-login)}.auth-panel-right:before{content:\"\";position:absolute;inset:0;background-image:repeating-linear-gradient(-55deg,transparent 0px,transparent 22px,rgba(57,139,247,.045) 22px,rgba(57,139,247,.045) 23px);animation:authLinesMove 10s linear infinite;pointer-events:none;z-index:0}.auth-panel-right:after{content:\"\";position:absolute;top:0;bottom:0;left:-25%;width:25%;background:linear-gradient(90deg,transparent 0%,rgba(57,139,247,.02) 30%,rgba(57,139,247,.045) 50%,rgba(57,139,247,.02) 70%,transparent 100%);animation:authScanLine 7s ease-in-out infinite;animation-delay:3.5s;pointer-events:none;z-index:0}@keyframes authLinesMove{0%{transform:translate(0)}to{transform:translate(46px,46px)}}@keyframes authScanLine{0%{left:-25%}50%{left:120%}to{left:120%}}.auth-panel-bg{position:absolute;inset:0;pointer-events:none;z-index:0;overflow:hidden}.auth-deco{position:absolute;border-radius:50%;pointer-events:none;filter:blur(70px)}.auth-deco-tl{width:300px;height:300px;top:0;left:-120px;transform:translateY(-40%);background:radial-gradient(circle,rgba(57,139,247,.12) 0%,transparent 70%);animation:authOrbPulse 6s ease-in-out infinite}.auth-deco-br{width:340px;height:340px;bottom:0;right:-120px;transform:translateY(40%);background:radial-gradient(circle,rgba(124,58,237,.1) 0%,transparent 70%);animation:authOrbPulse 8s ease-in-out infinite;animation-delay:-4s}@keyframes authOrbPulse{0%,to{opacity:.7}50%{opacity:1}}.auth-form-wrapper{position:absolute;inset:0;overflow-y:auto;overflow-x:hidden;display:flex;flex-direction:column;align-items:center;z-index:1}.auth-form-wrapper>div{width:100%;max-width:420px;margin:auto;padding:36px 16px;box-sizing:border-box}.auth-panel-right--dev:before{background-image:repeating-linear-gradient(-55deg,transparent 0px,transparent 22px,rgba(209,50,111,.05) 22px,rgba(209,50,111,.05) 23px)}.auth-panel-right--dev:after{background:linear-gradient(90deg,transparent 0%,rgba(209,50,111,.02) 30%,rgba(209,50,111,.045) 50%,rgba(209,50,111,.02) 70%,transparent 100%)}.auth-panel-right--dev .auth-deco-tl{background:radial-gradient(circle,rgba(209,50,111,.12) 0%,transparent 70%)}.auth-panel-right--dev .auth-deco-br{background:radial-gradient(circle,rgba(239,68,68,.1) 0%,transparent 70%)}.auth-test-badge{display:inline-flex;align-items:center;gap:7px;background:#d1326f14;border:1px solid rgba(209,50,111,.25);color:#d1326f;font-size:10.5px;font-weight:700;padding:5px 12px;border-radius:20px;margin-bottom:18px;letter-spacing:.8px}.auth-test-badge .badge-dot{width:6px;height:6px;border-radius:50%;background:#d1326f;animation:badgePulse 1.6s ease-in-out infinite;flex-shrink:0}@keyframes badgePulse{0%,to{opacity:1;transform:scale(1)}50%{opacity:.45;transform:scale(.75)}}.auth-card{background:var(--background-card);border-radius:20px;padding:36px 32px 28px;box-shadow:0 4px 28px #00000014;border:1px solid var(--border-color-modal)}.auth-card-title{font-size:22px;font-weight:700;color:var(--text-color);margin-bottom:4px;letter-spacing:-.3px}.auth-card-subtitle{font-size:13px;color:var(--placeholder-color);margin-bottom:26px}.auth-field{position:relative;margin-bottom:1rem}.auth-field .auth-field-icon{position:absolute;left:13px;top:50%;transform:translateY(-50%);color:var(--placeholder-color);font-size:13px;z-index:2;pointer-events:none;transition:color .2s}.auth-field .auth-input{width:100%;padding:15px 40px 15px 37px;background:var(--background-input);border:1.5px solid var(--font-border-input);border-radius:10px;font-size:14px;color:var(--color-input);outline:none;transition:border-color .2s,box-shadow .2s,background .2s}.auth-field .auth-input::placeholder{color:transparent}.auth-field .auth-input:focus{border-color:#398bf7;box-shadow:0 0 0 3.5px #398bf721;background:var(--background-focus-input)}.auth-field .auth-input:focus~.auth-label{top:0;font-size:11px!important;color:#398bf7!important;background:var(--background-card);padding:0 4px;transform:translateY(-50%)}.auth-field .auth-input:focus~.auth-field-icon{color:#398bf7}.auth-field .auth-input:not(:placeholder-shown)~.auth-label{top:0;font-size:11px!important;background:var(--background-card);padding:0 4px;transform:translateY(-50%)}.auth-field .auth-label{position:absolute;left:35px;top:50%;transform:translateY(-50%);color:var(--placeholder-color)!important;font-size:13px!important;font-weight:400!important;pointer-events:none;transition:top .15s ease,font-size .15s ease,color .15s ease,padding .15s ease,background .15s ease;background:transparent;z-index:1;text-align:left!important}.auth-field .auth-toggle-pw{position:absolute;right:10px;top:50%;transform:translateY(-50%);background:none;border:none;color:var(--placeholder-color);cursor:pointer;padding:4px 6px;font-size:13px;z-index:2;line-height:1;transition:color .2s}.auth-field .auth-toggle-pw:hover{color:#398bf7}.auth-field.has-error .auth-input{border-color:#dc3545;box-shadow:none}.auth-field.has-error .auth-field-icon{color:#dc3545}.auth-select{width:100%;padding:13px 14px;background:var(--background-input);border:1.5px solid var(--font-border-input);border-radius:10px;font-size:14px;color:var(--color-input);outline:none;transition:border-color .2s,box-shadow .2s;margin-bottom:1rem;cursor:pointer}.auth-select:focus{border-color:#398bf7;box-shadow:0 0 0 3.5px #398bf721}.auth-btn{width:100%;padding:13px;border:none;border-radius:10px;font-size:14px;font-weight:600;cursor:pointer;transition:transform .15s ease,box-shadow .2s ease,opacity .2s;background:linear-gradient(135deg,#398bf7,#1e5fc4);color:#fff;letter-spacing:.3px;margin-bottom:10px;display:block}.auth-btn:hover:not(:disabled){transform:translateY(-1px);box-shadow:0 5px 18px #398bf761}.auth-btn:active:not(:disabled){transform:translateY(0)}.auth-btn:disabled{opacity:.55;cursor:not-allowed}.auth-btn.auth-btn--red{background:linear-gradient(135deg,#d1326f,#a82859)}.auth-btn.auth-btn--red:hover:not(:disabled){box-shadow:0 5px 18px #d1326f61}.auth-btn.auth-btn--outline{background:transparent;border:1.5px solid var(--font-border-input);color:var(--text-color)}.auth-btn.auth-btn--outline:hover:not(:disabled){background:var(--background-btn-light-hover);box-shadow:none;transform:none}.auth-links{display:flex;flex-direction:column;align-items:center;gap:10px;margin-top:16px;padding-top:16px;border-top:1px solid var(--border-color-modal)}.auth-version{text-align:right;margin-top:14px;padding-top:12px;border-top:1px solid var(--border-color-modal)}.auth-version span{font-size:11px;color:var(--placeholder-color)}.auth-error{font-size:11.5px;color:#dc3545;margin:-6px 0 10px 2px;padding:0}.auth-hint{display:flex;align-items:flex-start;gap:6px;font-size:11.5px;color:var(--placeholder-color);margin:-6px 0 14px 2px;padding:0;line-height:1.35}.auth-hint i{margin-top:2px;flex-shrink:0}.auth-validation-list{margin:-4px 0 12px;padding:0;list-style:none}.auth-validation-list li{font-size:11.5px;color:#dc3545;padding:2px 0}.auth-validation-list li:before{content:\"\\2715 \";font-size:10px}.auth-desc{font-size:13px;color:var(--placeholder-color);margin-bottom:20px;line-height:1.65}.auth-section-title{font-size:15px;font-weight:600;color:var(--text-color);margin-bottom:20px}.font-12{font-size:12px}.form-control:focus{border-color:#0199ff9a!important;box-shadow:0 0 5px .2px #65befa44!important}@media(max-width:900px){.auth-wrapper-login{grid-template-columns:1fr;grid-template-rows:auto 1fr;overflow-y:auto;overflow-x:hidden}.auth-panel-left{padding:14px 24px;justify-content:center}.auth-panel-left .auth-brand-subtitle,.auth-panel-left .auth-brand-features,.auth-panel-left .auth-brand-divider{display:none!important}.auth-panel-left .auth-brand-panel{display:flex!important;flex-direction:row!important;align-items:center;gap:0;text-align:left;max-width:none;width:100%;justify-content:center}.auth-panel-left .auth-brand-logo{width:52px;height:52px;margin:0;flex-shrink:0}.auth-panel-left .auth-brand-logo img{width:34px;height:34px}.auth-panel-left .auth-brand-title{font-size:20px;margin-bottom:0;margin-left:.5rem;flex-shrink:1}.auth-panel-right:after{inset:-25% 0 auto;width:100%;height:25%;background:linear-gradient(180deg,transparent 0%,rgba(57,139,247,.02) 30%,rgba(57,139,247,.045) 50%,rgba(57,139,247,.02) 70%,transparent 100%);animation:authScanLineV 7s ease-in-out infinite;animation-delay:3.5s}.auth-panel-right--dev:after{background:linear-gradient(180deg,transparent 0%,rgba(209,50,111,.02) 30%,rgba(209,50,111,.045) 50%,rgba(209,50,111,.02) 70%,transparent 100%)}}@keyframes authScanLineV{0%{top:-25%}50%{top:120%}to{top:120%}}@media(max-width:480px){.auth-panel-left{padding:12px 16px}.auth-panel-left .auth-brand-logo{width:44px;height:44px}.auth-panel-left .auth-brand-logo img{width:28px;height:28px}.auth-panel-left .auth-brand-title{font-size:17px}.auth-form-wrapper>div{padding:20px 12px}.auth-card{padding:24px 18px 20px;border-radius:16px}.font-12{font-size:10px!important}}\n"] }]
179
454
  }] });
180
455
 
181
456
  class ExpiredPasswordComponent {
@@ -327,5 +602,5 @@ class AuthSender {
327
602
  * Generated bundle index. Do not edit.
328
603
  */
329
604
 
330
- export { AuthComponent, AuthSender, ExpiredPasswordComponent, PwaFloatingComponent, PwaInstallService, RecoverPasswordComponent, RefreshFloatingComponent, SelectBranchComponent };
605
+ export { AUTH_API, AuthComponent, AuthSender, ExpiredPasswordComponent, PwaFloatingComponent, PwaInstallService, RecoverPasswordComponent, RefreshFloatingComponent, SelectBranchComponent, isMfaChallenge, isPushPendiente, provideAuthApi };
331
606
  //# sourceMappingURL=login-tsi.mjs.map