@bravophone/webphone 0.2.0 → 0.2.1

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,31 +1,31 @@
1
- const Z = 'stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"', me = `<svg viewBox="0 0 24 24" fill="none" ${Z} aria-hidden="true">
1
+ const Z = 'stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"', fe = `<svg viewBox="0 0 24 24" fill="none" ${Z} aria-hidden="true">
2
2
  <path class="bp-i-body" d="M15.6 12.8a11 11 0 0 1-4.4-4.4l1-1a1.6 1.6 0 0 0 .3-1.7c-.2-.7-.4-1.4-.5-2.2A1.6 1.6 0 0 0 10.4 2H7.9a1.6 1.6 0 0 0-1.6 1.8 15.8 15.8 0 0 0 2.4 6.9 15.6 15.6 0 0 0 4.8 4.8 15.8 15.8 0 0 0 6.9 2.4 1.6 1.6 0 0 0 1.7-1.6v-2.5a1.6 1.6 0 0 0-1.4-1.6c-.8-.1-1.5-.3-2.2-.5a1.6 1.6 0 0 0-1.7.4z"/>
3
3
  <path class="bp-i-wave bp-i-wave-1" d="M14.5 6.2a4 4 0 0 1 3.3 3.3"/>
4
4
  <path class="bp-i-wave bp-i-wave-2" d="M14.1 2.6a7.6 7.6 0 0 1 7.3 7.3"/>
5
- </svg>`, fe = `<svg viewBox="0 0 24 24" fill="none" ${Z} aria-hidden="true">
5
+ </svg>`, xe = `<svg viewBox="0 0 24 24" fill="none" ${Z} aria-hidden="true">
6
6
  <path class="bp-i-bar bp-i-bar-1" d="M4 10v4"/>
7
7
  <path class="bp-i-bar bp-i-bar-2" d="M8.7 6.5v11"/>
8
8
  <path class="bp-i-bar bp-i-bar-3" d="M12 3.5v17"/>
9
9
  <path class="bp-i-bar bp-i-bar-4" d="M15.3 6.5v11"/>
10
10
  <path class="bp-i-bar bp-i-bar-5" d="M20 10v4"/>
11
- </svg>`, xe = `<svg viewBox="0 0 24 24" fill="none" ${Z} aria-hidden="true">
11
+ </svg>`, we = `<svg viewBox="0 0 24 24" fill="none" ${Z} aria-hidden="true">
12
12
  <path class="bp-i-body" d="M4 13v-1a8 8 0 0 1 16 0v1"/>
13
13
  <path class="bp-i-body" d="M20 14.5v2a3.5 3.5 0 0 1-3.5 3.5H13"/>
14
14
  <rect class="bp-i-cup" x="1.6" y="12.6" width="4.4" height="6.4" rx="1.8"/>
15
15
  <rect class="bp-i-cup" x="18" y="12.6" width="4.4" height="6.4" rx="1.8"/>
16
- </svg>`, we = `<svg viewBox="0 0 24 24" fill="none" ${Z} aria-hidden="true">
16
+ </svg>`, ye = `<svg viewBox="0 0 24 24" fill="none" ${Z} aria-hidden="true">
17
17
  <path class="bp-i-body" d="M21 11.5a8.4 8.4 0 0 1-9 8.4 9 9 0 0 1-2.9-.5L3 21.5l1.5-4.6A8.4 8.4 0 0 1 12 3.1a8.4 8.4 0 0 1 9 8.4z"/>
18
18
  <path class="bp-i-hand" d="M14.6 14.4a6.5 6.5 0 0 1-3.2-3.2l.7-.7a1 1 0 0 0 .2-1.1 6 6 0 0 1-.3-1.2 1 1 0 0 0-1-.8H9.6a1 1 0 0 0-1 1.1 9.6 9.6 0 0 0 4.8 7.2 1 1 0 0 0 1.4-.9v-1.2a1 1 0 0 0-.8-1z"/>
19
- </svg>`, ye = `<svg viewBox="0 0 10 16" width="10" height="16" fill="currentColor" aria-hidden="true">
19
+ </svg>`, ve = `<svg viewBox="0 0 10 16" width="10" height="16" fill="currentColor" aria-hidden="true">
20
20
  <circle cx="2.6" cy="2.6" r="1.35"/><circle cx="7.4" cy="2.6" r="1.35"/>
21
21
  <circle cx="2.6" cy="8" r="1.35"/><circle cx="7.4" cy="8" r="1.35"/>
22
22
  <circle cx="2.6" cy="13.4" r="1.35"/><circle cx="7.4" cy="13.4" r="1.35"/>
23
23
  </svg>`, J = {
24
- "phone-waves": me,
25
- waveform: fe,
26
- headset: xe,
27
- "chat-phone": we
28
- }, te = "phone-waves", ve = `
24
+ "phone-waves": fe,
25
+ waveform: xe,
26
+ headset: we,
27
+ "chat-phone": ye
28
+ }, ae = "phone-waves", ke = `
29
29
  .bp-launcher-icon svg { width: 100%; height: 100%; display: block; overflow: visible; }
30
30
 
31
31
  /* Ponto de status no canto do ícone — verde registrado, cinza sem linha. */
@@ -95,7 +95,7 @@ const Z = 'stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-
95
95
  .bp-i-wave, .bp-i-body, .bp-i-hand, .bp-i-bar { animation: none !important; }
96
96
  .bp-launcher-icon { transition: none; }
97
97
  }
98
- `, ke = `
98
+ `, Me = `
99
99
  :host { all: initial; }
100
100
  * { box-sizing: border-box; }
101
101
 
@@ -227,6 +227,21 @@ const Z = 'stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-
227
227
  /* Uma janela docada nao se redimensiona pelas bordas coladas na viewport. */
228
228
  .bp-root.bp-docked { border-radius: 0; }
229
229
 
230
+ /* ---- destaque: "a janela esta aqui" ----
231
+ Disparado ao clicar na aba com o webphone ja aberto. Um halo que cresce e
232
+ some, no lugar de um shake: em interface, tremer significa erro ou acao
233
+ negada (senha errada), e aqui nada deu errado. */
234
+ @keyframes bp-attention {
235
+ 0% { box-shadow: 0 12px 40px rgba(0,0,0,.45), 0 0 0 0 rgba(124,108,245,.55); }
236
+ 55% { box-shadow: 0 12px 40px rgba(0,0,0,.45), 0 0 0 12px rgba(124,108,245,0); }
237
+ 100% { box-shadow: 0 12px 40px rgba(0,0,0,.45), 0 0 0 0 rgba(124,108,245,0); }
238
+ }
239
+ .bp-root.bp-attention { animation: bp-attention .85s ease-out 2; }
240
+
241
+ @media (prefers-reduced-motion: reduce) {
242
+ .bp-root.bp-attention { animation: none; outline: 2px solid #7c6cf5; outline-offset: 2px; }
243
+ }
244
+
230
245
  /* ---- previa de encaixe (docking) ----
231
246
  Fantasma que mostra onde a janela vai parar antes de soltar. */
232
247
  .bp-preview {
@@ -244,7 +259,9 @@ const Z = 'stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-
244
259
  .bp-launcher {
245
260
  position: fixed;
246
261
  top: 50%;
247
- z-index: 2147482999;
262
+ /* Acima da janela (2147483000): a aba nunca some, e uma janela docada na
263
+ mesma borda a esconderia. */
264
+ z-index: 2147483001;
248
265
  display: flex;
249
266
  align-items: center;
250
267
  gap: 0;
@@ -341,11 +358,11 @@ const Z = 'stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-
341
358
  .bp-launcher[data-badge]:not([data-badge=""]) { animation: none; }
342
359
  }
343
360
 
344
- ${ve}
345
- `, ue = "bravophone:widget:geometry", V = 28, X = 32;
346
- function Me(e) {
361
+ ${ke}
362
+ `, ge = "bravophone:widget:geometry", V = 28, X = 32;
363
+ function Le(e) {
347
364
  try {
348
- const a = localStorage.getItem(ue);
365
+ const a = localStorage.getItem(ge);
349
366
  if (!a) return { ...e };
350
367
  const n = JSON.parse(a);
351
368
  return n.dock ? { ...e, ...n, ...U(n.dock, n) } : { ...e, ...n };
@@ -355,7 +372,7 @@ function Me(e) {
355
372
  }
356
373
  function K(e) {
357
374
  try {
358
- localStorage.setItem(ue, JSON.stringify(e));
375
+ localStorage.setItem(ge, JSON.stringify(e));
359
376
  } catch (a) {
360
377
  }
361
378
  }
@@ -378,7 +395,7 @@ function R(e) {
378
395
  };
379
396
  }
380
397
  function U(e, a) {
381
- const n = window.innerWidth, o = window.innerHeight, i = Math.round(n / 2), s = Math.round(o / 2), u = Math.min(a.width, n);
398
+ const n = window.innerWidth, o = window.innerHeight, i = Math.round(n / 2), d = Math.round(o / 2), u = Math.min(a.width, n);
382
399
  switch (e) {
383
400
  case "left":
384
401
  return { x: 0, y: 0, width: u, height: o };
@@ -389,13 +406,13 @@ function U(e, a) {
389
406
  case "right-half":
390
407
  return { x: n - i, y: 0, width: i, height: o };
391
408
  case "top":
392
- return { x: a.x, y: 0, width: u, height: s };
409
+ return { x: a.x, y: 0, width: u, height: d };
393
410
  case "bottom":
394
- return { x: a.x, y: o - s, width: u, height: s };
411
+ return { x: a.x, y: o - d, width: u, height: d };
395
412
  case "top-half":
396
- return { x: 0, y: 0, width: n, height: s };
413
+ return { x: 0, y: 0, width: n, height: d };
397
414
  case "bottom-half":
398
- return { x: 0, y: o - s, width: n, height: s };
415
+ return { x: 0, y: o - d, width: n, height: d };
399
416
  case "max":
400
417
  return { x: 0, y: 0, width: n, height: o };
401
418
  default:
@@ -403,14 +420,14 @@ function U(e, a) {
403
420
  }
404
421
  }
405
422
  function ze(e, a, n) {
406
- const o = window.innerWidth, i = window.innerHeight, s = e <= V, u = e >= o - V, m = a <= V, t = a >= i - V;
407
- return (m || t) && s ? "left-half" : (m || t) && u ? "right-half" : m ? n || "max" : t ? "bottom-half" : s ? "left" : u ? "right" : null;
408
- }
409
- function Le({ root: e, handle: a, handles: n, preview: o, geometry: i, limits: s, topDock: u, onChange: m }) {
410
- let t = { ...i }, g = null, p = "", d = null, l = null, x = null, y = null;
411
- const M = () => {
412
- e.style.left = `${t.x}px`, e.style.top = `${t.y}px`, e.style.width = `${t.width}px`, e.style.height = `${t.height}px`, e.classList.toggle("bp-docked", !!t.dock), m == null || m(t);
413
- }, W = (r) => {
423
+ const o = window.innerWidth, i = window.innerHeight, d = e <= V, u = e >= o - V, f = a <= V, t = a >= i - V;
424
+ return (f || t) && d ? "left-half" : (f || t) && u ? "right-half" : f ? n || "max" : t ? "bottom-half" : d ? "left" : u ? "right" : null;
425
+ }
426
+ function Se({ root: e, handle: a, handles: n, preview: o, geometry: i, limits: d, topDock: u, onChange: f }) {
427
+ let t = { ...i }, g = null, p = "", c = null, h = null, x = null, w = null;
428
+ const z = () => {
429
+ e.style.left = `${t.x}px`, e.style.top = `${t.y}px`, e.style.width = `${t.width}px`, e.style.height = `${t.height}px`, e.classList.toggle("bp-docked", !!t.dock), f == null || f(t);
430
+ }, C = (r) => {
414
431
  if (o) {
415
432
  if (!r) {
416
433
  o.hidden = !0;
@@ -419,32 +436,32 @@ function Le({ root: e, handle: a, handles: n, preview: o, geometry: i, limits: s
419
436
  o.hidden = !1, o.style.left = `${r.x}px`, o.style.top = `${r.y}px`, o.style.width = `${r.width}px`, o.style.height = `${r.height}px`;
420
437
  }
421
438
  }, $ = (r, b) => {
422
- const h = he(s);
423
- let { x: v, y: z, width: L, height: H } = d;
424
- p.includes("e") && (L = d.width + r), p.includes("w") && (L = d.width - r), p.includes("s") && (H = d.height + b), p.includes("n") && (H = d.height - b), L = Math.min(h.maxWidth, Math.max(h.minWidth, L)), H = Math.min(h.maxHeight, Math.max(h.minHeight, H)), p.includes("w") && (v = d.x + (d.width - L)), p.includes("n") && (z = d.y + (d.height - H)), p.includes("e") && Math.abs(v + L - window.innerWidth) <= X && (L = window.innerWidth - v), p.includes("w") && Math.abs(v) <= X && (L += v, v = 0), p.includes("s") && Math.abs(z + H - window.innerHeight) <= X && (H = window.innerHeight - z), p.includes("n") && Math.abs(z) <= X && (H += z, z = 0), t = { ...t, x: v, y: z, width: L, height: H, dock: null }, M();
425
- }, j = (r, b, h, v) => {
439
+ const l = he(d);
440
+ let { x: v, y: S, width: E, height: H } = c;
441
+ p.includes("e") && (E = c.width + r), p.includes("w") && (E = c.width - r), p.includes("s") && (H = c.height + b), p.includes("n") && (H = c.height - b), E = Math.min(l.maxWidth, Math.max(l.minWidth, E)), H = Math.min(l.maxHeight, Math.max(l.minHeight, H)), p.includes("w") && (v = c.x + (c.width - E)), p.includes("n") && (S = c.y + (c.height - H)), p.includes("e") && Math.abs(v + E - window.innerWidth) <= X && (E = window.innerWidth - v), p.includes("w") && Math.abs(v) <= X && (E += v, v = 0), p.includes("s") && Math.abs(S + H - window.innerHeight) <= X && (H = window.innerHeight - S), p.includes("n") && Math.abs(S) <= X && (H += S, S = 0), t = { ...t, x: v, y: S, width: E, height: H, dock: null }, z();
442
+ }, j = (r, b, l, v) => {
426
443
  if (t.dock) {
427
- const z = y || { width: s.width, height: s.height }, L = l.x / Math.max(1, t.width);
428
- t = { ...t, ...z, dock: null }, l = { x: Math.round(z.width * L), y: Math.min(l.y, 32) }, d = {
429
- ...d,
430
- x: h - l.x,
431
- y: v - l.y,
432
- px: d.px + r,
433
- py: d.py + b
444
+ const S = w || { width: d.width, height: d.height }, E = h.x / Math.max(1, t.width);
445
+ t = { ...t, ...S, dock: null }, h = { x: Math.round(S.width * E), y: Math.min(h.y, 32) }, c = {
446
+ ...c,
447
+ x: l - h.x,
448
+ y: v - h.y,
449
+ px: c.px + r,
450
+ py: c.py + b
434
451
  }, r = 0, b = 0;
435
452
  }
436
- t = R({ ...t, x: d.x + r, y: d.y + b }), M(), x = ze(h, v, u), W(x ? U(x, t) : null);
453
+ t = R({ ...t, x: c.x + r, y: c.y + b }), z(), x = ze(l, v, u), C(x ? U(x, t) : null);
437
454
  }, _ = () => {
438
- x && (y = y || { width: t.width, height: t.height }, t = { ...t, ...U(x, t), dock: x }, M());
439
- }, G = (r, b) => (h) => {
440
- h.button === 0 && (r === "drag" && h.target.closest(".bp-btn") || (g = r, p = b || "", d = { px: h.clientX, py: h.clientY, ...t }, l = { x: h.clientX - t.x, y: h.clientY - t.y }, t.dock || (y = { width: t.width, height: t.height }), e.classList.add(r === "drag" ? "bp-dragging" : "bp-resizing"), h.currentTarget.setPointerCapture(h.pointerId), h.preventDefault()));
455
+ x && (w = w || { width: t.width, height: t.height }, t = { ...t, ...U(x, t), dock: x }, z());
456
+ }, F = (r, b) => (l) => {
457
+ l.button === 0 && (r === "drag" && l.target.closest(".bp-btn") || (g = r, p = b || "", c = { px: l.clientX, py: l.clientY, ...t }, h = { x: l.clientX - t.x, y: l.clientY - t.y }, t.dock || (w = { width: t.width, height: t.height }), e.classList.add(r === "drag" ? "bp-dragging" : "bp-resizing"), l.currentTarget.setPointerCapture(l.pointerId), l.preventDefault()));
441
458
  }, D = (r) => {
442
- if (!g || !d) return;
443
- const b = r.clientX - d.px, h = r.clientY - d.py;
444
- g === "drag" ? j(b, h, r.clientX, r.clientY) : $(b, h);
445
- }, B = (r) => {
459
+ if (!g || !c) return;
460
+ const b = r.clientX - c.px, l = r.clientY - c.py;
461
+ g === "drag" ? j(b, l, r.clientX, r.clientY) : $(b, l);
462
+ }, A = (r) => {
446
463
  if (g) {
447
- e.classList.remove("bp-dragging", "bp-resizing"), W(null), g === "drag" && _(), g = null, p = "", d = null, x = null;
464
+ e.classList.remove("bp-dragging", "bp-resizing"), C(null), g === "drag" && _(), g = null, p = "", c = null, x = null;
448
465
  try {
449
466
  r.currentTarget.releasePointerCapture(r.pointerId);
450
467
  } catch (b) {
@@ -452,173 +469,179 @@ function Le({ root: e, handle: a, handles: n, preview: o, geometry: i, limits: s
452
469
  K(t);
453
470
  }
454
471
  };
455
- a.addEventListener("pointerdown", G("drag")), a.addEventListener("pointermove", D), a.addEventListener("pointerup", B), a.addEventListener("pointercancel", B), (n || []).forEach(({ el: r, dir: b }) => {
456
- r.addEventListener("pointerdown", G("resize", b)), r.addEventListener("pointermove", D), r.addEventListener("pointerup", B), r.addEventListener("pointercancel", B);
472
+ a.addEventListener("pointerdown", F("drag")), a.addEventListener("pointermove", D), a.addEventListener("pointerup", A), a.addEventListener("pointercancel", A), (n || []).forEach(({ el: r, dir: b }) => {
473
+ r.addEventListener("pointerdown", F("resize", b)), r.addEventListener("pointermove", D), r.addEventListener("pointerup", A), r.addEventListener("pointercancel", A);
457
474
  });
458
- const P = () => {
459
- t = t.dock ? { ...t, ...U(t.dock, t) } : R(t), M();
475
+ const N = () => {
476
+ t = t.dock ? { ...t, ...U(t.dock, t) } : R(t), z();
460
477
  };
461
- window.addEventListener("resize", P);
462
- const Y = {
478
+ window.addEventListener("resize", N);
479
+ const G = {
463
480
  start(r) {
464
- var b, h;
465
- g = "drag", d = { px: r.x, py: r.y, ...t }, l = { x: (b = r.cx) != null ? b : t.width / 2, y: (h = r.cy) != null ? h : 20 }, t.dock || (y = { width: t.width, height: t.height }), e.classList.add("bp-dragging");
481
+ var b, l;
482
+ g = "drag", c = { px: r.x, py: r.y, ...t }, h = { x: (b = r.cx) != null ? b : t.width / 2, y: (l = r.cy) != null ? l : 20 }, t.dock || (w = { width: t.width, height: t.height }), e.classList.add("bp-dragging");
466
483
  },
467
484
  move(r) {
468
- if (g !== "drag" || !d) return;
469
- const b = r.x - d.px, h = r.y - d.py;
470
- j(b, h, d.x + b + l.x, d.y + h + l.y);
485
+ if (g !== "drag" || !c) return;
486
+ const b = r.x - c.px, l = r.y - c.py;
487
+ j(b, l, c.x + b + h.x, c.y + l + h.y);
471
488
  },
472
489
  end() {
473
- g === "drag" && (e.classList.remove("bp-dragging"), W(null), _(), g = null, d = null, x = null, K(t));
490
+ g === "drag" && (e.classList.remove("bp-dragging"), C(null), _(), g = null, c = null, x = null, K(t));
474
491
  }
475
492
  };
476
- return M(), {
477
- external: Y,
493
+ return z(), {
494
+ external: G,
478
495
  get geometry() {
479
496
  return { ...t };
480
497
  },
481
498
  set(r) {
482
- const b = he(s), h = { ...t, ...r, dock: null };
483
- h.width = Math.min(b.maxWidth, Math.max(b.minWidth, h.width)), h.height = Math.min(b.maxHeight, Math.max(b.minHeight, h.height)), t = R(h), M(), K(t);
499
+ const b = he(d), l = { ...t, ...r, dock: null };
500
+ l.width = Math.min(b.maxWidth, Math.max(b.minWidth, l.width)), l.height = Math.min(b.maxHeight, Math.max(b.minHeight, l.height)), t = R(l), z(), K(t);
484
501
  },
485
502
  /** 'left' | 'right' | 'left-half' | 'right-half' | 'max' | 'float' */
486
503
  dock(r) {
487
504
  if (!r || r === "float") {
488
- const b = y || { width: s.width, height: s.height };
505
+ const b = w || { width: d.width, height: d.height };
489
506
  t = R({ ...t, ...b, dock: null });
490
507
  } else
491
- t.dock || (y = { width: t.width, height: t.height }), t = { ...t, ...U(r, t), dock: r };
492
- M(), K(t);
508
+ t.dock || (w = { width: t.width, height: t.height }), t = { ...t, ...U(r, t), dock: r };
509
+ z(), K(t);
493
510
  },
494
511
  destroy() {
495
- window.removeEventListener("resize", P);
512
+ window.removeEventListener("resize", N);
496
513
  }
497
514
  };
498
515
  }
499
- const le = "bravophone/v1";
500
- function Se({ frame: e, origin: a, onEvent: n }) {
516
+ const be = "bravophone/v1";
517
+ function Ee({ frame: e, origin: a, onEvent: n }) {
501
518
  const o = /* @__PURE__ */ new Map();
502
- let i = 0, s = !1;
503
- const u = [], m = (g) => {
504
- var d;
519
+ let i = 0, d = !1;
520
+ const u = [], f = (g) => {
521
+ var c;
505
522
  if (g.origin !== a || g.source !== e.contentWindow) return;
506
523
  const p = g.data;
507
- if (!(!p || p.protocol !== le)) {
524
+ if (!(!p || p.protocol !== be)) {
508
525
  if (p.type === "ready") {
509
- for (s = !0; u.length; ) u.shift()();
510
- n == null || n("ready", (d = p.payload) != null ? d : {});
526
+ for (d = !0; u.length; ) u.shift()();
527
+ n == null || n("ready", (c = p.payload) != null ? c : {});
511
528
  return;
512
529
  }
513
530
  if (p.type === "reply") {
514
- const l = o.get(p.id);
515
- if (!l) return;
516
- o.delete(p.id), clearTimeout(l.timer), p.error ? l.reject(new Error(p.error)) : l.resolve(p.payload);
531
+ const h = o.get(p.id);
532
+ if (!h) return;
533
+ o.delete(p.id), clearTimeout(h.timer), p.error ? h.reject(new Error(p.error)) : h.resolve(p.payload);
517
534
  return;
518
535
  }
519
536
  p.type === "event" && (n == null || n(p.name, p.payload));
520
537
  }
521
538
  };
522
- window.addEventListener("message", m);
523
- function t(g, p, { timeout: d = 15e3 } = {}) {
524
- return new Promise((l, x) => {
525
- const y = `${Date.now()}-${++i}`, M = () => {
539
+ window.addEventListener("message", f);
540
+ function t(g, p, { timeout: c = 15e3 } = {}) {
541
+ return new Promise((h, x) => {
542
+ const w = `${Date.now()}-${++i}`, z = () => {
526
543
  var $;
527
- const W = setTimeout(() => {
528
- o.delete(y), x(new Error(`Bravophone: timeout no comando "${g}"`));
529
- }, d);
530
- o.set(y, { resolve: l, reject: x, timer: W }), ($ = e.contentWindow) == null || $.postMessage(
531
- { protocol: le, type: "command", id: y, command: g, payload: p },
544
+ const C = setTimeout(() => {
545
+ o.delete(w), x(new Error(`Bravophone: timeout no comando "${g}"`));
546
+ }, c);
547
+ o.set(w, { resolve: h, reject: x, timer: C }), ($ = e.contentWindow) == null || $.postMessage(
548
+ { protocol: be, type: "command", id: w, command: g, payload: p },
532
549
  a
533
550
  );
534
551
  };
535
- s ? M() : u.push(M);
552
+ d ? z() : u.push(z);
536
553
  });
537
554
  }
538
555
  return {
539
556
  call: t,
540
557
  get ready() {
541
- return s;
558
+ return d;
542
559
  },
543
560
  destroy() {
544
- window.removeEventListener("message", m), o.forEach(({ reject: g, timer: p }) => {
561
+ window.removeEventListener("message", f), o.forEach(({ reject: g, timer: p }) => {
545
562
  clearTimeout(p), g(new Error("Bravophone: widget destruído"));
546
563
  }), o.clear();
547
564
  }
548
565
  };
549
566
  }
550
- const ge = "bravophone:launcher", Ee = 4, ae = 8;
551
- function He(e) {
567
+ const me = "bravophone:launcher", He = 4, ie = 8;
568
+ function Te(e) {
552
569
  try {
553
- const a = localStorage.getItem(ge);
570
+ const a = localStorage.getItem(me);
554
571
  return a ? { ...e, ...JSON.parse(a) } : { ...e };
555
572
  } catch (a) {
556
573
  return { ...e };
557
574
  }
558
575
  }
559
- function ie(e) {
576
+ function ne(e) {
560
577
  try {
561
- localStorage.setItem(ge, JSON.stringify(e));
578
+ localStorage.setItem(me, JSON.stringify(e));
562
579
  } catch (a) {
563
580
  }
564
581
  }
565
- function F(e, a) {
566
- const n = Math.max(ae, window.innerHeight - a - ae);
567
- return Math.min(Math.max(ae, e), n);
582
+ function q(e, a) {
583
+ const n = Math.max(ie, window.innerHeight - a - ie);
584
+ return Math.min(Math.max(ie, e), n);
568
585
  }
569
586
  function $e({ el: e, side: a, y: n, onOpen: o }) {
570
- let i = { side: a, y: F(n, e.offsetHeight || 48) }, s = null, u = !1;
571
- const m = () => {
587
+ let i = { side: a, y: q(n, e.offsetHeight || 48) }, d = null, u = !1;
588
+ const f = () => {
572
589
  e.dataset.side = i.side, e.style.top = `${i.y}px`, e.style.right = i.side === "right" ? "0px" : "auto", e.style.left = i.side === "left" ? "0px" : "auto";
573
- }, t = (l) => {
574
- l.button === 0 && (s = { py: l.clientY, y: i.y }, u = !1, e.setPointerCapture(l.pointerId));
575
- }, g = (l) => {
576
- if (!s) return;
577
- const x = l.clientY - s.py;
578
- !u && Math.abs(x) < Ee || (u || (u = !0, e.classList.add("bp-launcher-dragging")), i.y = F(s.y + x, e.offsetHeight), m());
579
- }, p = (l) => {
580
- if (!s) return;
590
+ }, t = (h) => {
591
+ h.button === 0 && (d = { py: h.clientY, y: i.y }, u = !1, e.setPointerCapture(h.pointerId));
592
+ }, g = (h) => {
593
+ if (!d) return;
594
+ const x = h.clientY - d.py;
595
+ !u && Math.abs(x) < He || (u || (u = !0, e.classList.add("bp-launcher-dragging")), i.y = q(d.y + x, e.offsetHeight), f());
596
+ }, p = (h) => {
597
+ if (!d) return;
581
598
  const x = u;
582
- s = null, u = !1, e.classList.remove("bp-launcher-dragging");
599
+ d = null, u = !1, e.classList.remove("bp-launcher-dragging");
583
600
  try {
584
- e.releasePointerCapture(l.pointerId);
585
- } catch (y) {
601
+ e.releasePointerCapture(h.pointerId);
602
+ } catch (w) {
586
603
  }
587
- x ? ie(i) : o == null || o();
604
+ x ? ne(i) : o == null || o();
588
605
  };
589
- e.addEventListener("pointerdown", t), e.addEventListener("pointermove", g), e.addEventListener("pointerup", p), e.addEventListener("pointercancel", p), e.addEventListener("keydown", (l) => {
590
- (l.key === "Enter" || l.key === " ") && (l.preventDefault(), o == null || o());
606
+ e.addEventListener("pointerdown", t), e.addEventListener("pointermove", g), e.addEventListener("pointerup", p), e.addEventListener("pointercancel", p), e.addEventListener("keydown", (h) => {
607
+ (h.key === "Enter" || h.key === " ") && (h.preventDefault(), o == null || o());
591
608
  });
592
- const d = () => {
593
- i.y = F(i.y, e.offsetHeight), m();
609
+ const c = () => {
610
+ i.y = q(i.y, e.offsetHeight), f();
594
611
  };
595
- return window.addEventListener("resize", d), m(), {
612
+ return window.addEventListener("resize", c), f(), {
596
613
  get state() {
597
614
  return { ...i };
598
615
  },
599
- setSide(l) {
600
- i.side = l, m(), ie(i);
616
+ setSide(h) {
617
+ i.side = h, f(), ne(i);
601
618
  },
602
- moveTo(l) {
603
- i.y = F(l, e.offsetHeight), m(), ie(i);
619
+ moveTo(h) {
620
+ i.y = q(h, e.offsetHeight), f(), ne(i);
604
621
  },
605
622
  destroy() {
606
- window.removeEventListener("resize", d);
623
+ window.removeEventListener("resize", c);
607
624
  }
608
625
  };
609
626
  }
610
- const Te = "https://cdn.jsdelivr.net/npm";
611
- function Ie(e, a = "@bravophone/webphone") {
612
- return `${Te}/${a}@${e}/host/`;
627
+ const Ie = "https://cdn.jsdelivr.net/npm";
628
+ function Oe(e, a = "@bravophone/webphone") {
629
+ return `${Ie}/${a}@${e}/host/`;
613
630
  }
614
- function Oe({ version: e, parentOrigin: a, token: n, base: o }) {
615
- const i = o || Ie(e), s = JSON.stringify({ parentOrigin: a, token: n || null }).replace(/</g, "\\u003c");
631
+ function We({ version: e, parentOrigin: a, token: n, base: o }) {
632
+ const i = o || Oe(e), d = JSON.stringify({ parentOrigin: a, token: n || null }).replace(/</g, "\\u003c");
616
633
  return `<!doctype html>
617
634
  <html lang="pt-BR">
618
635
  <head>
619
636
  <meta charset="UTF-8">
620
637
  <meta name="viewport" content="width=device-width,initial-scale=1">
621
638
  <title>Webphone BRAVOPHONE</title>
639
+ <!-- CRÍTICO no modo srcdoc. O bundle referencia as imagens por caminho
640
+ RELATIVO (src="images/answer.png"), fora do public_path. Sem <base>,
641
+ elas resolvem contra a página do integrador — o documento herda o
642
+ baseURI do pai — e somem todas: logo, atender, desligar, mudo, hold,
643
+ transferir. Com <base>, resolvem contra o CDN. -->
644
+ <base href="${i}">
622
645
  <link rel="stylesheet" href="${i}css/dark-theme.css">
623
646
  <link rel="stylesheet" href="${i}styles/theme-fixes.css">
624
647
  <style>
@@ -627,7 +650,7 @@ function Oe({ version: e, parentOrigin: a, token: n, base: o }) {
627
650
  </style>
628
651
  <script>
629
652
  (function () {
630
- var cfg = ${s};
653
+ var cfg = ${d};
631
654
  // O guest-bridge lê daqui: em srcdoc não há query string para carregar a
632
655
  // origem do pai.
633
656
  window.__bpParentOrigin = cfg.parentOrigin;
@@ -651,7 +674,7 @@ function Oe({ version: e, parentOrigin: a, token: n, base: o }) {
651
674
  </body>
652
675
  </html>`;
653
676
  }
654
- const be = {
677
+ const ue = {
655
678
  // 380x640 é a geometria da janela nativa da extensão — o layout do
656
679
  // webphone é calibrado para ela, então é o ponto de partida aqui também.
657
680
  width: 380,
@@ -664,212 +687,231 @@ const be = {
664
687
  maxHeight: 1400,
665
688
  margin: 24
666
689
  };
667
- function w(e, a = {}, n = []) {
690
+ function y(e, a = {}, n = []) {
668
691
  const o = document.createElement(e);
669
- for (const [i, s] of Object.entries(a))
670
- i === "class" ? o.className = s : i === "text" ? o.textContent = s : s != null && o.setAttribute(i, s);
692
+ for (const [i, d] of Object.entries(a))
693
+ i === "class" ? o.className = d : i === "text" ? o.textContent = d : d != null && o.setAttribute(i, d);
671
694
  return n.forEach((i) => o.appendChild(i)), o;
672
695
  }
673
- function We(e) {
696
+ function Ce(e) {
674
697
  const {
675
698
  hostUrl: a,
676
699
  token: n,
677
700
  position: o = "bottom-right",
678
701
  open: i = !1,
679
- launcher: s = !0,
702
+ launcher: d = !0,
680
703
  title: u = "BRAVOPHONE",
681
- // 'none' preserva 100% da UI do webphone: sem barra de titulo, o arraste
682
- // vem de dentro do iframe. 'bar' adiciona a barra com titulo e controles.
683
- frame: m = "none",
704
+ // 'bar' por padrão: título, indicador de estado e controles visíveis.
705
+ // 'none' preserva 100% da UI do webphone sem barra, o arraste vem de
706
+ // dentro do iframe e só um botão de fechar aparece no hover.
707
+ frame: f = "bar",
684
708
  // O que arrastar até a borda de cima faz. 'max' é o gesto universal;
685
709
  // troque para 'top-half' se preferir as metades verticais no topo.
686
710
  dockTop: t = "max",
687
711
  // Lado da viewport em que a aba de abertura fica colada.
688
712
  launcherSide: g = "right",
689
713
  // Desenho da aba: 'phone-waves' | 'waveform' | 'headset' | 'chat-phone'
690
- launcherIcon: p = te,
714
+ launcherIcon: p = ae,
691
715
  // 'hosted' — o iframe navega para hostUrl (padrão)
692
716
  // 'srcdoc' — o iframe roda na origem do site e busca o conteúdo no CDN
693
- mode: d = "hosted",
717
+ mode: c = "hosted",
694
718
  // Base dos assets no modo srcdoc. Padrão: o CDN travado nesta versão.
695
719
  // Serve para desenvolvimento (localhost) e para quem espelhar os assets.
696
- hostBase: l,
720
+ hostBase: h,
697
721
  version: x,
698
- emit: y
699
- } = e, M = d === "srcdoc", W = M ? window.location.origin : new URL(a).origin, $ = w("div", { "data-bravophone": "root" });
722
+ emit: w
723
+ } = e, z = c === "srcdoc", C = z ? window.location.origin : new URL(a).origin, $ = y("div", { "data-bravophone": "root" });
700
724
  $.style.cssText = "all:initial;position:static";
701
725
  const j = $.attachShadow({ mode: "open" });
702
- j.appendChild(w("style", { text: ke }));
726
+ j.appendChild(y("style", { text: Me }));
703
727
  const _ = (() => {
704
- var pe;
705
- const { width: c, height: E, margin: O } = be, N = window.innerWidth - c - O, de = window.innerHeight - E - O, ce = {
706
- "bottom-right": { x: N, y: de },
707
- "bottom-left": { x: O, y: de },
708
- "top-right": { x: N, y: O },
709
- "top-left": { x: O, y: O }
728
+ var le;
729
+ const { width: s, height: M, margin: W } = ue, P = window.innerWidth - s - W, ce = window.innerHeight - M - W, pe = {
730
+ "bottom-right": { x: P, y: ce },
731
+ "bottom-left": { x: W, y: ce },
732
+ "top-right": { x: P, y: W },
733
+ "top-left": { x: W, y: W }
710
734
  };
711
- return R({ ...(pe = ce[o]) != null ? pe : ce["bottom-right"], width: c, height: E });
712
- })(), G = R(Me(_)), D = w("span", { class: "bp-status", "data-state": "connecting" }), B = w("button", { class: "bp-btn bp-btn-min", title: "Minimizar", text: "—" }), P = w("button", { class: "bp-btn bp-btn-close", title: "Fechar", text: "×" }), Y = w("div", { class: "bp-header" }, [
735
+ return R({ ...(le = pe[o]) != null ? le : pe["bottom-right"], width: s, height: M });
736
+ })(), F = R(Le(_)), D = y("span", { class: "bp-status", "data-state": "connecting" }), A = y("button", { class: "bp-btn bp-btn-min", title: "Minimizar", text: "—" }), N = y("button", { class: "bp-btn bp-btn-close", title: "Fechar", text: "×" }), G = y("div", { class: "bp-header" }, [
713
737
  D,
714
- w("span", { class: "bp-title", text: u }),
715
- B,
716
- P
717
- ]), r = w("iframe", {
738
+ y("span", { class: "bp-title", text: u }),
739
+ A,
740
+ N
741
+ ]), r = y("iframe", {
718
742
  class: "bp-frame",
719
743
  // allow= é obrigatório no modo hospedado (cross-origin). Em srcdoc o
720
744
  // microfone já é herdado do topo, mas declarar não custa e documenta.
721
745
  allow: "microphone; autoplay; clipboard-write; speaker-selection",
722
746
  title: "Webphone BRAVOPHONE"
723
747
  });
724
- M ? r.setAttribute(
748
+ z ? r.setAttribute(
725
749
  "srcdoc",
726
- Oe({ version: x, parentOrigin: W, token: n, base: l })
750
+ We({ version: x, parentOrigin: C, token: n, base: h })
727
751
  ) : r.setAttribute(
728
752
  "src",
729
- Be(new URL(a), { token: n, embed: "1", parent: location.origin })
753
+ Ae(new URL(a), { token: n, embed: "1", parent: location.origin })
730
754
  );
731
- const h = ["n", "s", "w", "e", "nw", "ne", "sw", "se"].map((c) => ({
732
- el: w("div", { class: `bp-h bp-h-${c}` }),
733
- dir: c
734
- })), v = w("div", { class: "bp-preview" });
755
+ const l = ["n", "s", "w", "e", "nw", "ne", "sw", "se"].map((s) => ({
756
+ el: y("div", { class: `bp-h bp-h-${s}` }),
757
+ dir: s
758
+ })), v = y("div", { class: "bp-preview" });
735
759
  v.hidden = !0;
736
- const z = w("button", { class: "bp-btn bp-btn-close", title: "Fechar", text: "×" }), L = w("div", { class: "bp-overlay" }, [z]), H = w("div", { class: "bp-body" }, [r, L]), T = w("div", { class: "bp-root" }, [Y, H, ...h.map((c) => c.el)]);
737
- m !== "bar" && T.classList.add("bp-chromeless"), T.hidden = !i;
738
- const Q = w("span", { class: "bp-launcher-icon" });
739
- Q.innerHTML = J[p] || J[te];
740
- const re = w("span", { class: "bp-launcher-grip", "aria-hidden": "true" });
741
- re.innerHTML = ye;
742
- const S = w("div", {
760
+ const S = y("button", { class: "bp-btn bp-btn-close", title: "Fechar", text: "×" }), E = y("div", { class: "bp-overlay" }, [S]), H = y("div", { class: "bp-body" }, [r, E]), k = y("div", { class: "bp-root" }, [G, H, ...l.map((s) => s.el)]);
761
+ f !== "bar" && k.classList.add("bp-chromeless"), k.hidden = !i;
762
+ const Q = y("span", { class: "bp-launcher-icon" });
763
+ Q.innerHTML = J[p] || J[ae];
764
+ const oe = y("span", { class: "bp-launcher-grip", "aria-hidden": "true" });
765
+ oe.innerHTML = ve;
766
+ const T = y("div", {
743
767
  class: "bp-launcher",
744
768
  role: "button",
745
769
  tabindex: "0",
746
770
  title: "Abrir webphone",
747
771
  "aria-label": "Abrir webphone"
748
772
  }, [
749
- re,
773
+ oe,
750
774
  Q,
751
- w("span", { class: "bp-badge" })
775
+ y("span", { class: "bp-badge" })
752
776
  ]);
753
- S.dataset.state = "connecting", S.hidden = !s || i, j.append(v, T, S), document.body.appendChild($);
754
- const oe = He({
777
+ T.dataset.state = "connecting", T.hidden = !d, j.append(v, k, T), document.body.appendChild($);
778
+ const se = Te({
755
779
  side: g,
756
780
  y: Math.round(window.innerHeight / 2 - 24)
757
- }), se = $e({
758
- el: S,
759
- side: oe.side,
760
- y: F(oe.y, 48),
761
- onOpen: () => I.show()
762
- }), A = Le({
763
- root: T,
764
- handle: Y,
765
- handles: h,
781
+ }), de = $e({
782
+ el: T,
783
+ side: se.side,
784
+ y: q(se.y, 48),
785
+ // A aba nunca some, então o clique tem dois papéis: abrir quando fechada,
786
+ // e localizar quando já aberta.
787
+ onOpen: () => O.reveal()
788
+ }), I = Se({
789
+ root: k,
790
+ handle: G,
791
+ handles: l,
766
792
  preview: v,
767
- geometry: G,
768
- limits: be,
793
+ geometry: F,
794
+ limits: ue,
769
795
  topDock: t,
770
- onChange: (c) => y("resize", { width: c.width, height: c.height, dock: c.dock || null })
771
- }), ee = Se({
796
+ onChange: (s) => w("resize", { width: s.width, height: s.height, dock: s.dock || null })
797
+ }), ee = Ee({
772
798
  frame: r,
773
- origin: W,
774
- onEvent: (c, E) => {
775
- var O;
776
- if (c === "ready" && (D.dataset.state = "ready", S.dataset.state = "ready", n && ee.call("auth", { token: n }).catch(() => {
777
- })), c === "state") {
778
- const N = (O = E == null ? void 0 : E.state) != null ? O : "ready";
779
- D.dataset.state = N, S.dataset.state = N;
799
+ origin: C,
800
+ onEvent: (s, M) => {
801
+ var W;
802
+ if (s === "ready" && (D.dataset.state = "ready", T.dataset.state = "ready", n && ee.call("auth", { token: n }).catch(() => {
803
+ })), s === "state") {
804
+ const P = (W = M == null ? void 0 : M.state) != null ? W : "ready";
805
+ D.dataset.state = P, T.dataset.state = P;
780
806
  }
781
- if (c === "call:incoming" && (I.show(), S.dataset.badge = "1", S.dataset.state = "ringing"), c === "call:answered" && (S.dataset.state = "incall"), (c === "call:ended" || c === "call:failed") && (delete S.dataset.badge, S.dataset.state = "ready"), c === "drag:start") {
782
- A.external.start(E);
807
+ if (s === "call:incoming" && (O.show(), T.dataset.badge = "1", T.dataset.state = "ringing"), s === "call:answered" && (T.dataset.state = "incall"), s === "call:ended" && (delete T.dataset.badge, T.dataset.state = "ready"), s === "drag:start") {
808
+ I.external.start(M);
783
809
  return;
784
810
  }
785
- if (c === "drag:move") {
786
- A.external.move(E);
811
+ if (s === "drag:move") {
812
+ I.external.move(M);
787
813
  return;
788
814
  }
789
- if (c === "drag:end") {
790
- A.external.end();
815
+ if (s === "drag:end") {
816
+ I.external.end();
791
817
  return;
792
818
  }
793
- y(c, E);
819
+ w(s, M);
794
820
  }
795
821
  });
796
- let q = !1;
797
- const I = {
822
+ let Y = !1, te = null;
823
+ const O = {
798
824
  el: $,
799
825
  bridge: ee,
800
826
  show() {
801
- T.hidden = !1, S.hidden = !0, y("open");
827
+ k.hidden = !1, w("open");
802
828
  },
803
829
  hide() {
804
- T.hidden = !0, s && (S.hidden = !1), y("close");
830
+ k.hidden = !0, w("close");
805
831
  },
806
832
  toggle() {
807
- T.hidden ? I.show() : I.hide();
833
+ k.hidden ? O.show() : O.hide();
834
+ },
835
+ /**
836
+ * Traz a janela para a atenção do usuário.
837
+ * Fechada: abre. Aberta e fora de vista: traz de volta. Aberta e
838
+ * visível: um halo curto, para o olho encontrá-la.
839
+ */
840
+ reveal() {
841
+ if (k.hidden) {
842
+ O.show();
843
+ return;
844
+ }
845
+ const s = I.geometry;
846
+ (s.x + s.width < 40 || s.x > window.innerWidth - 40 || s.y > window.innerHeight - 40) && I.set({
847
+ x: Math.round((window.innerWidth - s.width) / 2),
848
+ y: Math.round((window.innerHeight - s.height) / 2)
849
+ }), k.classList.remove("bp-attention"), k.offsetWidth, k.classList.add("bp-attention"), clearTimeout(te), te = setTimeout(() => k.classList.remove("bp-attention"), 1800), w("reveal");
808
850
  },
809
851
  get isOpen() {
810
- return !T.hidden;
852
+ return !k.hidden;
811
853
  },
812
- minimize(c) {
813
- if (m !== "bar") {
814
- I.hide();
854
+ minimize(s) {
855
+ if (f !== "bar") {
856
+ O.hide();
815
857
  return;
816
858
  }
817
- q = c != null ? c : !q, T.classList.toggle("bp-minimized", q), B.textContent = q ? "▢" : "—";
859
+ Y = s != null ? s : !Y, k.classList.toggle("bp-minimized", Y), A.textContent = Y ? "▢" : "—";
818
860
  },
819
- move(c, E) {
820
- A.set({ x: c, y: E });
861
+ move(s, M) {
862
+ I.set({ x: s, y: M });
821
863
  },
822
- resize(c, E) {
823
- A.set({ width: c, height: E });
864
+ resize(s, M) {
865
+ I.set({ width: s, height: M });
824
866
  },
825
- dock(c) {
826
- A.dock(c);
867
+ dock(s) {
868
+ I.dock(s);
827
869
  },
828
- setLauncherSide(c) {
829
- se.setSide(c);
870
+ setLauncherSide(s) {
871
+ de.setSide(s);
830
872
  },
831
- setLauncherIcon(c) {
832
- Q.innerHTML = J[c] || J[te];
873
+ setLauncherIcon(s) {
874
+ Q.innerHTML = J[s] || J[ae];
833
875
  },
834
876
  get geometry() {
835
- return A.geometry;
877
+ return I.geometry;
836
878
  },
837
879
  destroy() {
838
- ee.destroy(), A.destroy(), se.destroy(), v.remove(), $.remove();
880
+ clearTimeout(te), ee.destroy(), I.destroy(), de.destroy(), v.remove(), $.remove();
839
881
  }
840
882
  };
841
- return P.addEventListener("click", () => I.hide()), B.addEventListener("click", () => I.minimize()), z.addEventListener("click", () => I.hide()), I;
883
+ return N.addEventListener("click", () => O.hide()), A.addEventListener("click", () => O.minimize()), S.addEventListener("click", () => O.hide()), O;
842
884
  }
843
- function Be(e, a) {
885
+ function Ae(e, a) {
844
886
  const n = new URL(e.href);
845
887
  for (const [o, i] of Object.entries(a))
846
888
  i != null && i !== "" && n.searchParams.set(o, i);
847
889
  return a.token && (n.searchParams.delete("token"), n.hash = `token=${encodeURIComponent(a.token)}`), n.href;
848
890
  }
849
- const Ae = "https://webphone.bravophone.com/embed/";
850
- let k = null;
851
- const C = /* @__PURE__ */ new Map();
852
- function Ce(e, a) {
891
+ const Be = "https://webphone.bravophone.com/embed/";
892
+ let L = null;
893
+ const B = /* @__PURE__ */ new Map();
894
+ function De(e, a) {
853
895
  var n, o;
854
- (n = C.get(e)) == null || n.forEach((i) => {
896
+ (n = B.get(e)) == null || n.forEach((i) => {
855
897
  try {
856
898
  i(a);
857
- } catch (s) {
858
- console.error("[Bravophone] listener falhou:", s);
899
+ } catch (d) {
900
+ console.error("[Bravophone] listener falhou:", d);
859
901
  }
860
- }), (o = C.get("*")) == null || o.forEach((i) => {
902
+ }), (o = B.get("*")) == null || o.forEach((i) => {
861
903
  try {
862
904
  i({ event: e, payload: a });
863
- } catch (s) {
864
- console.error("[Bravophone] listener falhou:", s);
905
+ } catch (d) {
906
+ console.error("[Bravophone] listener falhou:", d);
865
907
  }
866
908
  });
867
909
  }
868
- function f() {
869
- if (!k) throw new Error("Bravophone: chame Bravophone.init() antes.");
870
- return k;
910
+ function m() {
911
+ if (!L) throw new Error("Bravophone: chame Bravophone.init() antes.");
912
+ return L;
871
913
  }
872
- const ne = {
914
+ const re = {
873
915
  /**
874
916
  * Monta o webphone na página.
875
917
  * @param {object} opts
@@ -886,104 +928,108 @@ const ne = {
886
928
  * precisa estar na allowlist de CORS dos backends.
887
929
  */
888
930
  init(e = {}) {
889
- if (k) return k;
931
+ if (L) return L;
890
932
  if (typeof window == "undefined" || !document.body)
891
933
  throw new Error("Bravophone: init() precisa rodar no browser, após o <body> existir.");
892
- return location.protocol !== "https:" && location.hostname !== "localhost" && console.warn("[Bravophone] Contexto inseguro: o microfone exige HTTPS ou localhost."), k = We({
893
- hostUrl: Ae,
894
- version: ne.version,
934
+ return location.protocol !== "https:" && location.hostname !== "localhost" && console.warn("[Bravophone] Contexto inseguro: o microfone exige HTTPS ou localhost."), L = Ce({
935
+ hostUrl: Be,
936
+ version: re.version,
895
937
  ...e,
896
- emit: Ce
897
- }), k;
938
+ emit: De
939
+ }), L;
898
940
  },
899
941
  // ---- Controle da janela ----
900
942
  show() {
901
- f().show();
943
+ m().show();
902
944
  },
903
945
  hide() {
904
- f().hide();
946
+ m().hide();
905
947
  },
906
948
  toggle() {
907
- f().toggle();
949
+ m().toggle();
950
+ },
951
+ /** Abre a janela; se já estiver aberta, traz para a vista e destaca. */
952
+ reveal() {
953
+ m().reveal();
908
954
  },
909
955
  minimize(e) {
910
- f().minimize(e);
956
+ m().minimize(e);
911
957
  },
912
958
  move(e, a) {
913
- f().move(e, a);
959
+ m().move(e, a);
914
960
  },
915
961
  resize(e, a) {
916
- f().resize(e, a);
962
+ m().resize(e, a);
917
963
  },
918
964
  /** 'left' | 'right' | 'left-half' | 'right-half' | 'max' | 'float' */
919
965
  dock(e) {
920
- f().dock(e);
966
+ m().dock(e);
921
967
  },
922
968
  /** Move a aba de abertura para o outro lado da viewport. */
923
969
  setLauncherSide(e) {
924
- f().setLauncherSide(e);
970
+ m().setLauncherSide(e);
925
971
  },
926
972
  /** 'phone-waves' | 'waveform' | 'headset' | 'chat-phone' */
927
973
  setLauncherIcon(e) {
928
- f().setLauncherIcon(e);
974
+ m().setLauncherIcon(e);
929
975
  },
930
976
  get isOpen() {
931
- return k ? k.isOpen : !1;
977
+ return L ? L.isOpen : !1;
932
978
  },
933
979
  get geometry() {
934
- return k ? k.geometry : null;
980
+ return L ? L.geometry : null;
935
981
  },
936
982
  // ---- Telefonia ----
937
983
  /** Disca um número. Aceita formato livre; a normalização é a mesma da extensão. */
938
984
  call(e, a) {
939
- return f().bridge.call("call", { number: e, meta: a });
985
+ return m().bridge.call("call", { number: e, meta: a });
940
986
  },
941
987
  hangup() {
942
- return f().bridge.call("hangup");
988
+ return m().bridge.call("hangup");
943
989
  },
944
990
  answer() {
945
- return f().bridge.call("answer");
991
+ return m().bridge.call("answer");
946
992
  },
947
993
  /** Alterna o mudo — o bundle só expõe toggle, não aceita estado alvo. */
948
994
  mute() {
949
- return f().bridge.call("mute");
995
+ return m().bridge.call("mute");
950
996
  },
951
997
  /** Alterna a espera. Também toggle. */
952
998
  hold() {
953
- return f().bridge.call("hold");
999
+ return m().bridge.call("hold");
954
1000
  },
955
1001
  sendDTMF(e) {
956
- return f().bridge.call("dtmf", { tone: e });
1002
+ return m().bridge.call("dtmf", { tone: e });
957
1003
  },
958
1004
  transfer(e) {
959
- return f().bridge.call("transfer", { to: e });
1005
+ return m().bridge.call("transfer", { to: e });
960
1006
  },
961
1007
  getStatus() {
962
- return f().bridge.call("status");
1008
+ return m().bridge.call("status");
963
1009
  },
964
1010
  setAuth(e) {
965
- return f().bridge.call("auth", { token: e });
1011
+ return m().bridge.call("auth", { token: e });
966
1012
  },
967
1013
  logout() {
968
- return f().bridge.call("logout");
1014
+ return m().bridge.call("logout");
969
1015
  },
970
1016
  // ---- Eventos ----
971
1017
  /** Eventos: ready, state, call:dialing, call:incoming, call:answered,
972
1018
  * call:ended, call:failed, resize, open, close, error. */
973
1019
  on(e, a) {
974
- return C.has(e) || C.set(e, /* @__PURE__ */ new Set()), C.get(e).add(a), () => ne.off(e, a);
1020
+ return B.has(e) || B.set(e, /* @__PURE__ */ new Set()), B.get(e).add(a), () => re.off(e, a);
975
1021
  },
976
1022
  off(e, a) {
977
1023
  var n;
978
- (n = C.get(e)) == null || n.delete(a);
1024
+ (n = B.get(e)) == null || n.delete(a);
979
1025
  },
980
1026
  destroy() {
981
- k == null || k.destroy(), k = null, C.clear();
1027
+ L == null || L.destroy(), L = null, B.clear();
982
1028
  },
983
1029
  // Substituída em build time pelo valor do package.json (ver vite.config.js).
984
- version: "0.2.0"
1030
+ version: "0.2.1"
985
1031
  };
986
- typeof window != "undefined" && (window.Bravophone = ne);
1032
+ typeof window != "undefined" && (window.Bravophone = re);
987
1033
  export {
988
- ne as default
1034
+ re as default
989
1035
  };