@bravophone/webphone 0.2.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,31 +1,31 @@
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">
1
+ const Z = 'stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"', xe = `<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>`, xe = `<svg viewBox="0 0 24 24" fill="none" ${Z} aria-hidden="true">
5
+ </svg>`, we = `<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>`, we = `<svg viewBox="0 0 24 24" fill="none" ${Z} aria-hidden="true">
11
+ </svg>`, ye = `<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>`, ye = `<svg viewBox="0 0 24 24" fill="none" ${Z} aria-hidden="true">
16
+ </svg>`, ve = `<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>`, ve = `<svg viewBox="0 0 10 16" width="10" height="16" fill="currentColor" aria-hidden="true">
19
+ </svg>`, ke = `<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
- </svg>`, J = {
24
- "phone-waves": fe,
25
- waveform: xe,
26
- headset: we,
27
- "chat-phone": ye
28
- }, ae = "phone-waves", ke = `
23
+ </svg>`, V = {
24
+ "phone-waves": xe,
25
+ waveform: we,
26
+ headset: ye,
27
+ "chat-phone": ve
28
+ }, ae = "phone-waves", Me = `
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
- `, Me = `
98
+ `, Le = `
99
99
  :host { all: initial; }
100
100
  * { box-sizing: border-box; }
101
101
 
@@ -358,22 +358,22 @@ const Z = 'stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-
358
358
  .bp-launcher[data-badge]:not([data-badge=""]) { animation: none; }
359
359
  }
360
360
 
361
- ${ke}
362
- `, ge = "bravophone:widget:geometry", V = 28, X = 32;
363
- function Le(e) {
361
+ ${Me}
362
+ `, ge = "bravophone:widget:geometry", J = 28, X = 32;
363
+ function ze(e) {
364
364
  try {
365
- const a = localStorage.getItem(ge);
366
- if (!a) return { ...e };
367
- const n = JSON.parse(a);
368
- return n.dock ? { ...e, ...n, ...U(n.dock, n) } : { ...e, ...n };
369
- } catch (a) {
365
+ const t = localStorage.getItem(ge);
366
+ if (!t) return { ...e };
367
+ const n = JSON.parse(t);
368
+ return n.dock ? { ...e, ...n, ...P(n.dock, n) } : { ...e, ...n };
369
+ } catch (t) {
370
370
  return { ...e };
371
371
  }
372
372
  }
373
373
  function K(e) {
374
374
  try {
375
375
  localStorage.setItem(ge, JSON.stringify(e));
376
- } catch (a) {
376
+ } catch (t) {
377
377
  }
378
378
  }
379
379
  function he(e) {
@@ -386,140 +386,140 @@ function he(e) {
386
386
  maxHeight: Math.max(e.minHeight, Math.min(e.maxHeight, window.innerHeight))
387
387
  };
388
388
  }
389
- function R(e) {
390
- const a = Math.max(0, window.innerWidth - e.width), n = Math.max(0, window.innerHeight - 40);
389
+ function U(e) {
390
+ const t = Math.max(0, window.innerWidth - e.width), n = Math.max(0, window.innerHeight - 40);
391
391
  return {
392
392
  ...e,
393
- x: Math.min(Math.max(0, e.x), a),
393
+ x: Math.min(Math.max(0, e.x), t),
394
394
  y: Math.min(Math.max(0, e.y), n)
395
395
  };
396
396
  }
397
- function U(e, a) {
398
- const n = window.innerWidth, o = window.innerHeight, i = Math.round(n / 2), d = Math.round(o / 2), u = Math.min(a.width, n);
397
+ function P(e, t) {
398
+ const n = window.innerWidth, i = window.innerHeight, r = Math.round(n / 2), d = Math.round(i / 2), u = Math.min(t.width, n);
399
399
  switch (e) {
400
400
  case "left":
401
- return { x: 0, y: 0, width: u, height: o };
401
+ return { x: 0, y: 0, width: u, height: i };
402
402
  case "right":
403
- return { x: n - u, y: 0, width: u, height: o };
403
+ return { x: n - u, y: 0, width: u, height: i };
404
404
  case "left-half":
405
- return { x: 0, y: 0, width: i, height: o };
405
+ return { x: 0, y: 0, width: r, height: i };
406
406
  case "right-half":
407
- return { x: n - i, y: 0, width: i, height: o };
407
+ return { x: n - r, y: 0, width: r, height: i };
408
408
  case "top":
409
- return { x: a.x, y: 0, width: u, height: d };
409
+ return { x: t.x, y: 0, width: u, height: d };
410
410
  case "bottom":
411
- return { x: a.x, y: o - d, width: u, height: d };
411
+ return { x: t.x, y: i - d, width: u, height: d };
412
412
  case "top-half":
413
413
  return { x: 0, y: 0, width: n, height: d };
414
414
  case "bottom-half":
415
- return { x: 0, y: o - d, width: n, height: d };
415
+ return { x: 0, y: i - d, width: n, height: d };
416
416
  case "max":
417
- return { x: 0, y: 0, width: n, height: o };
417
+ return { x: 0, y: 0, width: n, height: i };
418
418
  default:
419
- return { x: a.x, y: a.y, width: a.width, height: a.height };
419
+ return { x: t.x, y: t.y, width: t.width, height: t.height };
420
420
  }
421
421
  }
422
- function ze(e, a, n) {
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;
422
+ function Se(e, t, n) {
423
+ const i = window.innerWidth, r = window.innerHeight, d = e <= J, u = e >= i - J, f = t <= J, a = t >= r - J;
424
+ return (f || a) && d ? "left-half" : (f || a) && u ? "right-half" : f ? n || "max" : a ? "bottom-half" : d ? "left" : u ? "right" : null;
425
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) => {
431
- if (o) {
432
- if (!r) {
433
- o.hidden = !0;
426
+ function Ee({ root: e, handle: t, handles: n, preview: i, geometry: r, limits: d, topDock: u, onChange: f }) {
427
+ let a = { ...r }, g = null, p = "", c = null, l = null, x = null, k = null;
428
+ const y = () => {
429
+ e.style.left = `${a.x}px`, e.style.top = `${a.y}px`, e.style.width = `${a.width}px`, e.style.height = `${a.height}px`, e.classList.toggle("bp-docked", !!a.dock), f == null || f(a);
430
+ }, C = (o) => {
431
+ if (i) {
432
+ if (!o) {
433
+ i.hidden = !0;
434
434
  return;
435
435
  }
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`;
436
+ i.hidden = !1, i.style.left = `${o.x}px`, i.style.top = `${o.y}px`, i.style.width = `${o.width}px`, i.style.height = `${o.height}px`;
437
437
  }
438
- }, $ = (r, b) => {
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) => {
443
- if (t.dock) {
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 = {
438
+ }, D = (o, b) => {
439
+ const h = he(d);
440
+ let { x: E, y: v, width: M, height: T } = c;
441
+ p.includes("e") && (M = c.width + o), p.includes("w") && (M = c.width - o), p.includes("s") && (T = c.height + b), p.includes("n") && (T = c.height - b), M = Math.min(h.maxWidth, Math.max(h.minWidth, M)), T = Math.min(h.maxHeight, Math.max(h.minHeight, T)), p.includes("w") && (E = c.x + (c.width - M)), p.includes("n") && (v = c.y + (c.height - T)), p.includes("e") && Math.abs(E + M - window.innerWidth) <= X && (M = window.innerWidth - E), p.includes("w") && Math.abs(E) <= X && (M += E, E = 0), p.includes("s") && Math.abs(v + T - window.innerHeight) <= X && (T = window.innerHeight - v), p.includes("n") && Math.abs(v) <= X && (T += v, v = 0), a = { ...a, x: E, y: v, width: M, height: T, dock: null }, y();
442
+ }, W = (o, b, h, E) => {
443
+ if (a.dock) {
444
+ const v = k || { width: d.width, height: d.height }, M = l.x / Math.max(1, a.width);
445
+ a = { ...a, ...v, dock: null }, l = { x: Math.round(v.width * M), y: Math.min(l.y, 32) }, c = {
446
446
  ...c,
447
- x: l - h.x,
448
- y: v - h.y,
449
- px: c.px + r,
447
+ x: h - l.x,
448
+ y: E - l.y,
449
+ px: c.px + o,
450
450
  py: c.py + b
451
- }, r = 0, b = 0;
451
+ }, o = 0, b = 0;
452
452
  }
453
- t = R({ ...t, x: c.x + r, y: c.y + b }), z(), x = ze(l, v, u), C(x ? U(x, t) : null);
454
- }, _ = () => {
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()));
458
- }, D = (r) => {
453
+ a = U({ ...a, x: c.x + o, y: c.y + b }), y(), x = Se(h, E, u), C(x ? P(x, a) : null);
454
+ }, j = () => {
455
+ x && (k = k || { width: a.width, height: a.height }, a = { ...a, ...P(x, a), dock: x }, y());
456
+ }, _ = (o, b) => (h) => {
457
+ h.button === 0 && (o === "drag" && h.target.closest(".bp-btn") || (g = o, p = b || "", c = { px: h.clientX, py: h.clientY, ...a }, l = { x: h.clientX - a.x, y: h.clientY - a.y }, a.dock || (k = { width: a.width, height: a.height }), e.classList.add(o === "drag" ? "bp-dragging" : "bp-resizing"), h.currentTarget.setPointerCapture(h.pointerId), h.preventDefault()));
458
+ }, F = (o) => {
459
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) => {
460
+ const b = o.clientX - c.px, h = o.clientY - c.py;
461
+ g === "drag" ? W(b, h, o.clientX, o.clientY) : D(b, h);
462
+ }, A = (o) => {
463
463
  if (g) {
464
- e.classList.remove("bp-dragging", "bp-resizing"), C(null), g === "drag" && _(), g = null, p = "", c = null, x = null;
464
+ e.classList.remove("bp-dragging", "bp-resizing"), C(null), g === "drag" && j(), g = null, p = "", c = null, x = null;
465
465
  try {
466
- r.currentTarget.releasePointerCapture(r.pointerId);
466
+ o.currentTarget.releasePointerCapture(o.pointerId);
467
467
  } catch (b) {
468
468
  }
469
- K(t);
469
+ K(a);
470
470
  }
471
471
  };
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);
472
+ t.addEventListener("pointerdown", _("drag")), t.addEventListener("pointermove", F), t.addEventListener("pointerup", A), t.addEventListener("pointercancel", A), (n || []).forEach(({ el: o, dir: b }) => {
473
+ o.addEventListener("pointerdown", _("resize", b)), o.addEventListener("pointermove", F), o.addEventListener("pointerup", A), o.addEventListener("pointercancel", A);
474
474
  });
475
- const N = () => {
476
- t = t.dock ? { ...t, ...U(t.dock, t) } : R(t), z();
475
+ const B = () => {
476
+ a = a.dock ? { ...a, ...P(a.dock, a) } : U(a), y();
477
477
  };
478
- window.addEventListener("resize", N);
478
+ window.addEventListener("resize", B);
479
479
  const G = {
480
- start(r) {
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");
480
+ start(o) {
481
+ var b, h;
482
+ g = "drag", c = { px: o.x, py: o.y, ...a }, l = { x: (b = o.cx) != null ? b : a.width / 2, y: (h = o.cy) != null ? h : 20 }, a.dock || (k = { width: a.width, height: a.height }), e.classList.add("bp-dragging");
483
483
  },
484
- move(r) {
484
+ move(o) {
485
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);
486
+ const b = o.x - c.px, h = o.y - c.py;
487
+ W(b, h, c.x + b + l.x, c.y + h + l.y);
488
488
  },
489
489
  end() {
490
- g === "drag" && (e.classList.remove("bp-dragging"), C(null), _(), g = null, c = null, x = null, K(t));
490
+ g === "drag" && (e.classList.remove("bp-dragging"), C(null), j(), g = null, c = null, x = null, K(a));
491
491
  }
492
492
  };
493
- return z(), {
493
+ return y(), {
494
494
  external: G,
495
495
  get geometry() {
496
- return { ...t };
496
+ return { ...a };
497
497
  },
498
- set(r) {
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);
498
+ set(o) {
499
+ const b = he(d), h = { ...a, ...o, dock: null };
500
+ h.width = Math.min(b.maxWidth, Math.max(b.minWidth, h.width)), h.height = Math.min(b.maxHeight, Math.max(b.minHeight, h.height)), a = U(h), y(), K(a);
501
501
  },
502
502
  /** 'left' | 'right' | 'left-half' | 'right-half' | 'max' | 'float' */
503
- dock(r) {
504
- if (!r || r === "float") {
505
- const b = w || { width: d.width, height: d.height };
506
- t = R({ ...t, ...b, dock: null });
503
+ dock(o) {
504
+ if (!o || o === "float") {
505
+ const b = k || { width: d.width, height: d.height };
506
+ a = U({ ...a, ...b, dock: null });
507
507
  } else
508
- t.dock || (w = { width: t.width, height: t.height }), t = { ...t, ...U(r, t), dock: r };
509
- z(), K(t);
508
+ a.dock || (k = { width: a.width, height: a.height }), a = { ...a, ...P(o, a), dock: o };
509
+ y(), K(a);
510
510
  },
511
511
  destroy() {
512
- window.removeEventListener("resize", N);
512
+ window.removeEventListener("resize", B);
513
513
  }
514
514
  };
515
515
  }
516
516
  const be = "bravophone/v1";
517
- function Ee({ frame: e, origin: a, onEvent: n }) {
518
- const o = /* @__PURE__ */ new Map();
519
- let i = 0, d = !1;
517
+ function Te({ frame: e, origin: t, onEvent: n }) {
518
+ const i = /* @__PURE__ */ new Map();
519
+ let r = 0, d = !1;
520
520
  const u = [], f = (g) => {
521
521
  var c;
522
- if (g.origin !== a || g.source !== e.contentWindow) return;
522
+ if (g.origin !== t || g.source !== e.contentWindow) return;
523
523
  const p = g.data;
524
524
  if (!(!p || p.protocol !== be)) {
525
525
  if (p.type === "ready") {
@@ -528,108 +528,108 @@ function Ee({ frame: e, origin: a, onEvent: n }) {
528
528
  return;
529
529
  }
530
530
  if (p.type === "reply") {
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);
531
+ const l = i.get(p.id);
532
+ if (!l) return;
533
+ i.delete(p.id), clearTimeout(l.timer), p.error ? l.reject(new Error(p.error)) : l.resolve(p.payload);
534
534
  return;
535
535
  }
536
536
  p.type === "event" && (n == null || n(p.name, p.payload));
537
537
  }
538
538
  };
539
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 = () => {
543
- var $;
540
+ function a(g, p, { timeout: c = 15e3 } = {}) {
541
+ return new Promise((l, x) => {
542
+ const k = `${Date.now()}-${++r}`, y = () => {
543
+ var D;
544
544
  const C = setTimeout(() => {
545
- o.delete(w), x(new Error(`Bravophone: timeout no comando "${g}"`));
545
+ i.delete(k), x(new Error(`Bravophone: timeout no comando "${g}"`));
546
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 },
549
- a
547
+ i.set(k, { resolve: l, reject: x, timer: C }), (D = e.contentWindow) == null || D.postMessage(
548
+ { protocol: be, type: "command", id: k, command: g, payload: p },
549
+ t
550
550
  );
551
551
  };
552
- d ? z() : u.push(z);
552
+ d ? y() : u.push(y);
553
553
  });
554
554
  }
555
555
  return {
556
- call: t,
556
+ call: a,
557
557
  get ready() {
558
558
  return d;
559
559
  },
560
560
  destroy() {
561
- window.removeEventListener("message", f), o.forEach(({ reject: g, timer: p }) => {
561
+ window.removeEventListener("message", f), i.forEach(({ reject: g, timer: p }) => {
562
562
  clearTimeout(p), g(new Error("Bravophone: widget destruído"));
563
- }), o.clear();
563
+ }), i.clear();
564
564
  }
565
565
  };
566
566
  }
567
- const me = "bravophone:launcher", He = 4, ie = 8;
568
- function Te(e) {
567
+ const me = "bravophone:launcher", He = 4, ne = 8;
568
+ function Ie(e) {
569
569
  try {
570
- const a = localStorage.getItem(me);
571
- return a ? { ...e, ...JSON.parse(a) } : { ...e };
572
- } catch (a) {
570
+ const t = localStorage.getItem(me);
571
+ return t ? { ...e, ...JSON.parse(t) } : { ...e };
572
+ } catch (t) {
573
573
  return { ...e };
574
574
  }
575
575
  }
576
- function ne(e) {
576
+ function re(e) {
577
577
  try {
578
578
  localStorage.setItem(me, JSON.stringify(e));
579
- } catch (a) {
579
+ } catch (t) {
580
580
  }
581
581
  }
582
- function q(e, a) {
583
- const n = Math.max(ie, window.innerHeight - a - ie);
584
- return Math.min(Math.max(ie, e), n);
582
+ function q(e, t) {
583
+ const n = Math.max(ne, window.innerHeight - t - ne);
584
+ return Math.min(Math.max(ne, e), n);
585
585
  }
586
- function $e({ el: e, side: a, y: n, onOpen: o }) {
587
- let i = { side: a, y: q(n, e.offsetHeight || 48) }, d = null, u = !1;
586
+ function $e({ el: e, side: t, y: n, onOpen: i }) {
587
+ let r = { side: t, y: q(n, e.offsetHeight || 48) }, d = null, u = !1;
588
588
  const f = () => {
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";
590
- }, t = (h) => {
591
- h.button === 0 && (d = { py: h.clientY, y: i.y }, u = !1, e.setPointerCapture(h.pointerId));
592
- }, g = (h) => {
589
+ e.dataset.side = r.side, e.style.top = `${r.y}px`, e.style.right = r.side === "right" ? "0px" : "auto", e.style.left = r.side === "left" ? "0px" : "auto";
590
+ }, a = (l) => {
591
+ l.button === 0 && (d = { py: l.clientY, y: r.y }, u = !1, e.setPointerCapture(l.pointerId));
592
+ }, g = (l) => {
593
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) => {
594
+ const x = l.clientY - d.py;
595
+ !u && Math.abs(x) < He || (u || (u = !0, e.classList.add("bp-launcher-dragging")), r.y = q(d.y + x, e.offsetHeight), f());
596
+ }, p = (l) => {
597
597
  if (!d) return;
598
598
  const x = u;
599
599
  d = null, u = !1, e.classList.remove("bp-launcher-dragging");
600
600
  try {
601
- e.releasePointerCapture(h.pointerId);
602
- } catch (w) {
601
+ e.releasePointerCapture(l.pointerId);
602
+ } catch (k) {
603
603
  }
604
- x ? ne(i) : o == null || o();
604
+ x ? re(r) : i == null || i();
605
605
  };
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());
606
+ e.addEventListener("pointerdown", a), e.addEventListener("pointermove", g), e.addEventListener("pointerup", p), e.addEventListener("pointercancel", p), e.addEventListener("keydown", (l) => {
607
+ (l.key === "Enter" || l.key === " ") && (l.preventDefault(), i == null || i());
608
608
  });
609
609
  const c = () => {
610
- i.y = q(i.y, e.offsetHeight), f();
610
+ r.y = q(r.y, e.offsetHeight), f();
611
611
  };
612
612
  return window.addEventListener("resize", c), f(), {
613
613
  get state() {
614
- return { ...i };
614
+ return { ...r };
615
615
  },
616
- setSide(h) {
617
- i.side = h, f(), ne(i);
616
+ setSide(l) {
617
+ r.side = l, f(), re(r);
618
618
  },
619
- moveTo(h) {
620
- i.y = q(h, e.offsetHeight), f(), ne(i);
619
+ moveTo(l) {
620
+ r.y = q(l, e.offsetHeight), f(), re(r);
621
621
  },
622
622
  destroy() {
623
623
  window.removeEventListener("resize", c);
624
624
  }
625
625
  };
626
626
  }
627
- const Ie = "https://cdn.jsdelivr.net/npm";
628
- function Oe(e, a = "@bravophone/webphone") {
629
- return `${Ie}/${a}@${e}/host/`;
627
+ const Oe = "https://cdn.jsdelivr.net/npm";
628
+ function Ce(e, t = "@bravophone/webphone") {
629
+ return `${Oe}/${t}@${e}/host/`;
630
630
  }
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");
631
+ function We({ version: e, parentOrigin: t, session: n, base: i }) {
632
+ const r = i || Ce(e), d = JSON.stringify({ parentOrigin: t, session: n || null }).replace(/</g, "\\u003c");
633
633
  return `<!doctype html>
634
634
  <html lang="pt-BR">
635
635
  <head>
@@ -641,9 +641,9 @@ function We({ version: e, parentOrigin: a, token: n, base: o }) {
641
641
  elas resolvem contra a página do integrador — o documento herda o
642
642
  baseURI do pai — e somem todas: logo, atender, desligar, mudo, hold,
643
643
  transferir. Com <base>, resolvem contra o CDN. -->
644
- <base href="${i}">
645
- <link rel="stylesheet" href="${i}css/dark-theme.css">
646
- <link rel="stylesheet" href="${i}styles/theme-fixes.css">
644
+ <base href="${r}">
645
+ <link rel="stylesheet" href="${r}css/dark-theme.css">
646
+ <link rel="stylesheet" href="${r}styles/theme-fixes.css">
647
647
  <style>
648
648
  html, body { margin: 0; height: 100%; background: #10131c; overflow: hidden; }
649
649
  #app { height: 100%; }
@@ -654,19 +654,38 @@ function We({ version: e, parentOrigin: a, token: n, base: o }) {
654
654
  // O guest-bridge lê daqui: em srcdoc não há query string para carregar a
655
655
  // origem do pai.
656
656
  window.__bpParentOrigin = cfg.parentOrigin;
657
- if (cfg.token) {
658
- // Grava onde o bundle procura, antes dele avaliar, para a sessão subir
659
- // autenticada em vez de piscar a tela de login.
660
- try { localStorage.setItem('bp.local.vxToken', JSON.stringify(cfg.token)); } catch (e) {}
657
+ // Grava a sessão onde o bundle procura, ANTES dele avaliar, para já subir
658
+ // autenticado em vez de piscar a tela de login.
659
+ //
660
+ // As chaves e o prefixo não são escolha nossa: 'bp.local.' é como o
661
+ // chrome-shim mapeia chrome.storage.local, e os nomes vêm do bpSaveSession
662
+ // do bundle. Um token sozinho NÃO basta — sem sip e ramal o webphone não
663
+ // tem o que registrar, e o RouteSelector avisa "faça login pelo webphone".
664
+ if (cfg.session) {
665
+ var s = cfg.session;
666
+ var mapa = {
667
+ bravophoneVxToken: s.vxToken || null,
668
+ bravophoneVxTokenExpiresAt: s.expiresIn ? Date.now() + 1000 * Number(s.expiresIn) : null,
669
+ bravophoneSip: s.sip || null,
670
+ bravophoneTenant: s.tenant || null,
671
+ bravophoneRamal: s.ramal || null,
672
+ bravophoneClienteId: s.clienteId || null,
673
+ bravophoneRamaisUrl: s.ramaisUrl || null
674
+ };
675
+ try {
676
+ for (var k in mapa) {
677
+ if (mapa[k] !== null) localStorage.setItem('bp.local.' + k, JSON.stringify(mapa[k]));
678
+ }
679
+ } catch (e) {}
661
680
  }
662
681
  })();
663
682
  <\/script>
664
- <script src="${i}shim/messages.js"><\/script>
665
- <script src="${i}shim/chrome-shim.js"><\/script>
666
- <script src="${i}js/libwebphone.js"><\/script>
667
- <script src="${i}js/bravophone-route-selector.js"><\/script>
668
- <script defer src="${i}popup.js"><\/script>
669
- <script defer src="${i}shim/guest-bridge.js"><\/script>
683
+ <script src="${r}shim/messages.js"><\/script>
684
+ <script src="${r}shim/chrome-shim.js"><\/script>
685
+ <script src="${r}js/libwebphone.js"><\/script>
686
+ <script src="${r}js/bravophone-route-selector.js"><\/script>
687
+ <script defer src="${r}popup.js"><\/script>
688
+ <script defer src="${r}shim/guest-bridge.js"><\/script>
670
689
  </head>
671
690
  <body>
672
691
  <noscript><strong>O webphone precisa de JavaScript habilitado.</strong></noscript>
@@ -687,83 +706,93 @@ const ue = {
687
706
  maxHeight: 1400,
688
707
  margin: 24
689
708
  };
690
- function y(e, a = {}, n = []) {
691
- const o = document.createElement(e);
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);
694
- return n.forEach((i) => o.appendChild(i)), o;
709
+ function w(e, t = {}, n = []) {
710
+ const i = document.createElement(e);
711
+ for (const [r, d] of Object.entries(t))
712
+ r === "class" ? i.className = d : r === "text" ? i.textContent = d : d != null && i.setAttribute(r, d);
713
+ return n.forEach((r) => i.appendChild(r)), i;
695
714
  }
696
- function Ce(e) {
715
+ function Ae(e) {
697
716
  const {
698
- hostUrl: a,
717
+ hostUrl: t,
699
718
  token: n,
700
- position: o = "bottom-right",
701
- open: i = !1,
702
- launcher: d = !0,
703
- title: u = "BRAVOPHONE",
719
+ session: i,
720
+ position: r = "bottom-right",
721
+ open: d = !1,
722
+ launcher: u = !0,
723
+ title: f = "BRAVOPHONE",
704
724
  // 'bar' por padrão: título, indicador de estado e controles visíveis.
705
725
  // 'none' preserva 100% da UI do webphone — sem barra, o arraste vem de
706
726
  // dentro do iframe e só um botão de fechar aparece no hover.
707
- frame: f = "bar",
727
+ frame: a = "bar",
708
728
  // O que arrastar até a borda de cima faz. 'max' é o gesto universal;
709
729
  // troque para 'top-half' se preferir as metades verticais no topo.
710
- dockTop: t = "max",
730
+ dockTop: g = "max",
711
731
  // Lado da viewport em que a aba de abertura fica colada.
712
- launcherSide: g = "right",
732
+ launcherSide: p = "right",
713
733
  // Desenho da aba: 'phone-waves' | 'waveform' | 'headset' | 'chat-phone'
714
- launcherIcon: p = ae,
715
- // 'hosted' o iframe navega para hostUrl (padrão)
716
- // 'srcdoc' — o iframe roda na origem do site e busca o conteúdo no CDN
717
- mode: c = "hosted",
734
+ launcherIcon: c = ae,
735
+ // 'srcdoc' é o padrão porque é o modo que funciona sem infraestrutura
736
+ // nossa: o webphone vem do CDN, travado nesta versão. 'hosted' navega
737
+ // para hostUrl e depende de um domínio publicado — se ele não existir,
738
+ // o iframe falha em DNS antes de qualquer outra coisa.
739
+ mode: l = "srcdoc",
718
740
  // Base dos assets no modo srcdoc. Padrão: o CDN travado nesta versão.
719
741
  // Serve para desenvolvimento (localhost) e para quem espelhar os assets.
720
- hostBase: h,
721
- version: x,
722
- emit: w
723
- } = e, z = c === "srcdoc", C = z ? window.location.origin : new URL(a).origin, $ = y("div", { "data-bravophone": "root" });
724
- $.style.cssText = "all:initial;position:static";
725
- const j = $.attachShadow({ mode: "open" });
726
- j.appendChild(y("style", { text: Me }));
742
+ hostBase: x,
743
+ version: k,
744
+ emit: y
745
+ } = e, C = l === "srcdoc", D = C ? window.location.origin : new URL(t).origin, W = w("div", { "data-bravophone": "root" });
746
+ W.style.cssText = "all:initial;position:static";
747
+ const j = W.attachShadow({ mode: "open" });
748
+ j.appendChild(w("style", { text: Le }));
727
749
  const _ = (() => {
728
750
  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 }
751
+ const { width: s, height: z, margin: O } = ue, N = window.innerWidth - s - O, ce = window.innerHeight - z - O, pe = {
752
+ "bottom-right": { x: N, y: ce },
753
+ "bottom-left": { x: O, y: ce },
754
+ "top-right": { x: N, y: O },
755
+ "top-left": { x: O, y: O }
734
756
  };
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" }, [
737
- D,
738
- y("span", { class: "bp-title", text: u }),
757
+ return U({ ...(le = pe[r]) != null ? le : pe["bottom-right"], width: s, height: z });
758
+ })(), F = U(ze(_)), A = w("span", { class: "bp-status", "data-state": "connecting" }), B = w("button", { class: "bp-btn bp-btn-min", title: "Minimizar", text: "—" }), G = w("button", { class: "bp-btn bp-btn-close", title: "Fechar", text: "×" }), o = w("div", { class: "bp-header" }, [
739
759
  A,
740
- N
741
- ]), r = y("iframe", {
760
+ w("span", { class: "bp-title", text: f }),
761
+ B,
762
+ G
763
+ ]), b = w("iframe", {
742
764
  class: "bp-frame",
743
765
  // allow= é obrigatório no modo hospedado (cross-origin). Em srcdoc o
744
766
  // microfone já é herdado do topo, mas declarar não custa e documenta.
745
767
  allow: "microphone; autoplay; clipboard-write; speaker-selection",
746
768
  title: "Webphone BRAVOPHONE"
747
769
  });
748
- z ? r.setAttribute(
770
+ C ? b.setAttribute(
749
771
  "srcdoc",
750
- We({ version: x, parentOrigin: C, token: n, base: h })
751
- ) : r.setAttribute(
772
+ We({
773
+ version: k,
774
+ parentOrigin: D,
775
+ base: x,
776
+ // token sozinho vira uma sessão mínima; sem sip/ramal o webphone
777
+ // carrega mas não registra.
778
+ session: i || (n ? { vxToken: n } : null)
779
+ })
780
+ ) : b.setAttribute(
752
781
  "src",
753
- Ae(new URL(a), { token: n, embed: "1", parent: location.origin })
782
+ De(new URL(t), { token: n, embed: "1", parent: location.origin })
754
783
  );
755
- const l = ["n", "s", "w", "e", "nw", "ne", "sw", "se"].map((s) => ({
756
- el: y("div", { class: `bp-h bp-h-${s}` }),
784
+ const E = ["n", "s", "w", "e", "nw", "ne", "sw", "se"].map((s) => ({
785
+ el: w("div", { class: `bp-h bp-h-${s}` }),
757
786
  dir: s
758
- })), v = y("div", { class: "bp-preview" });
787
+ })), v = w("div", { class: "bp-preview" });
759
788
  v.hidden = !0;
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", {
789
+ const M = w("button", { class: "bp-btn bp-btn-close", title: "Fechar", text: "×" }), T = w("div", { class: "bp-overlay" }, [M]), fe = w("div", { class: "bp-body" }, [b, T]), L = w("div", { class: "bp-root" }, [o, fe, ...E.map((s) => s.el)]);
790
+ a !== "bar" && L.classList.add("bp-chromeless"), L.hidden = !d;
791
+ const Q = w("span", { class: "bp-launcher-icon" });
792
+ Q.innerHTML = V[c] || V[ae];
793
+ const oe = w("span", { class: "bp-launcher-grip", "aria-hidden": "true" });
794
+ oe.innerHTML = ke;
795
+ const H = w("div", {
767
796
  class: "bp-launcher",
768
797
  role: "button",
769
798
  tabindex: "0",
@@ -772,65 +801,65 @@ function Ce(e) {
772
801
  }, [
773
802
  oe,
774
803
  Q,
775
- y("span", { class: "bp-badge" })
804
+ w("span", { class: "bp-badge" })
776
805
  ]);
777
- T.dataset.state = "connecting", T.hidden = !d, j.append(v, k, T), document.body.appendChild($);
778
- const se = Te({
779
- side: g,
806
+ H.dataset.state = "connecting", H.hidden = !u, j.append(v, L, H), document.body.appendChild(W);
807
+ const se = Ie({
808
+ side: p,
780
809
  y: Math.round(window.innerHeight / 2 - 24)
781
810
  }), de = $e({
782
- el: T,
811
+ el: H,
783
812
  side: se.side,
784
813
  y: q(se.y, 48),
785
814
  // A aba nunca some, então o clique tem dois papéis: abrir quando fechada,
786
815
  // e localizar quando já aberta.
787
- onOpen: () => O.reveal()
788
- }), I = Se({
789
- root: k,
790
- handle: G,
791
- handles: l,
816
+ onOpen: () => $.reveal()
817
+ }), I = Ee({
818
+ root: L,
819
+ handle: o,
820
+ handles: E,
792
821
  preview: v,
793
822
  geometry: F,
794
823
  limits: ue,
795
- topDock: t,
796
- onChange: (s) => w("resize", { width: s.width, height: s.height, dock: s.dock || null })
797
- }), ee = Ee({
798
- frame: r,
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(() => {
824
+ topDock: g,
825
+ onChange: (s) => y("resize", { width: s.width, height: s.height, dock: s.dock || null })
826
+ }), ee = Te({
827
+ frame: b,
828
+ origin: D,
829
+ onEvent: (s, z) => {
830
+ var O;
831
+ if (s === "ready" && (A.dataset.state = "ready", H.dataset.state = "ready", (i || n) && ee.call("auth", { session: i || { vxToken: n } }).catch(() => {
803
832
  })), s === "state") {
804
- const P = (W = M == null ? void 0 : M.state) != null ? W : "ready";
805
- D.dataset.state = P, T.dataset.state = P;
833
+ const N = (O = z == null ? void 0 : z.state) != null ? O : "ready";
834
+ A.dataset.state = N, H.dataset.state = N;
806
835
  }
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);
836
+ if (s === "call:incoming" && ($.show(), H.dataset.badge = "1", H.dataset.state = "ringing"), s === "call:answered" && (H.dataset.state = "incall"), s === "call:ended" && (delete H.dataset.badge, H.dataset.state = "ready"), s === "drag:start") {
837
+ I.external.start(z);
809
838
  return;
810
839
  }
811
840
  if (s === "drag:move") {
812
- I.external.move(M);
841
+ I.external.move(z);
813
842
  return;
814
843
  }
815
844
  if (s === "drag:end") {
816
845
  I.external.end();
817
846
  return;
818
847
  }
819
- w(s, M);
848
+ y(s, z);
820
849
  }
821
850
  });
822
851
  let Y = !1, te = null;
823
- const O = {
824
- el: $,
852
+ const $ = {
853
+ el: W,
825
854
  bridge: ee,
826
855
  show() {
827
- k.hidden = !1, w("open");
856
+ L.hidden = !1, y("open");
828
857
  },
829
858
  hide() {
830
- k.hidden = !0, w("close");
859
+ L.hidden = !0, y("close");
831
860
  },
832
861
  toggle() {
833
- k.hidden ? O.show() : O.hide();
862
+ L.hidden ? $.show() : $.hide();
834
863
  },
835
864
  /**
836
865
  * Traz a janela para a atenção do usuário.
@@ -838,31 +867,31 @@ function Ce(e) {
838
867
  * visível: um halo curto, para o olho encontrá-la.
839
868
  */
840
869
  reveal() {
841
- if (k.hidden) {
842
- O.show();
870
+ if (L.hidden) {
871
+ $.show();
843
872
  return;
844
873
  }
845
874
  const s = I.geometry;
846
875
  (s.x + s.width < 40 || s.x > window.innerWidth - 40 || s.y > window.innerHeight - 40) && I.set({
847
876
  x: Math.round((window.innerWidth - s.width) / 2),
848
877
  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");
878
+ }), L.classList.remove("bp-attention"), L.offsetWidth, L.classList.add("bp-attention"), clearTimeout(te), te = setTimeout(() => L.classList.remove("bp-attention"), 1800), y("reveal");
850
879
  },
851
880
  get isOpen() {
852
- return !k.hidden;
881
+ return !L.hidden;
853
882
  },
854
883
  minimize(s) {
855
- if (f !== "bar") {
856
- O.hide();
884
+ if (a !== "bar") {
885
+ $.hide();
857
886
  return;
858
887
  }
859
- Y = s != null ? s : !Y, k.classList.toggle("bp-minimized", Y), A.textContent = Y ? "▢" : "—";
888
+ Y = s != null ? s : !Y, L.classList.toggle("bp-minimized", Y), B.textContent = Y ? "▢" : "—";
860
889
  },
861
- move(s, M) {
862
- I.set({ x: s, y: M });
890
+ move(s, z) {
891
+ I.set({ x: s, y: z });
863
892
  },
864
- resize(s, M) {
865
- I.set({ width: s, height: M });
893
+ resize(s, z) {
894
+ I.set({ width: s, height: z });
866
895
  },
867
896
  dock(s) {
868
897
  I.dock(s);
@@ -871,52 +900,56 @@ function Ce(e) {
871
900
  de.setSide(s);
872
901
  },
873
902
  setLauncherIcon(s) {
874
- Q.innerHTML = J[s] || J[ae];
903
+ Q.innerHTML = V[s] || V[ae];
875
904
  },
876
905
  get geometry() {
877
906
  return I.geometry;
878
907
  },
879
908
  destroy() {
880
- clearTimeout(te), ee.destroy(), I.destroy(), de.destroy(), v.remove(), $.remove();
909
+ clearTimeout(te), ee.destroy(), I.destroy(), de.destroy(), v.remove(), W.remove();
881
910
  }
882
911
  };
883
- return N.addEventListener("click", () => O.hide()), A.addEventListener("click", () => O.minimize()), S.addEventListener("click", () => O.hide()), O;
912
+ return G.addEventListener("click", () => $.hide()), B.addEventListener("click", () => $.minimize()), M.addEventListener("click", () => $.hide()), $;
884
913
  }
885
- function Ae(e, a) {
914
+ function De(e, t) {
886
915
  const n = new URL(e.href);
887
- for (const [o, i] of Object.entries(a))
888
- i != null && i !== "" && n.searchParams.set(o, i);
889
- return a.token && (n.searchParams.delete("token"), n.hash = `token=${encodeURIComponent(a.token)}`), n.href;
916
+ for (const [i, r] of Object.entries(t))
917
+ r != null && r !== "" && n.searchParams.set(i, r);
918
+ return t.token && (n.searchParams.delete("token"), n.hash = `token=${encodeURIComponent(t.token)}`), n.href;
890
919
  }
891
- const Be = "https://webphone.bravophone.com/embed/";
892
- let L = null;
893
- const B = /* @__PURE__ */ new Map();
894
- function De(e, a) {
895
- var n, o;
896
- (n = B.get(e)) == null || n.forEach((i) => {
920
+ const Re = "";
921
+ let S = null;
922
+ const R = /* @__PURE__ */ new Map();
923
+ function Be(e, t) {
924
+ var n, i;
925
+ (n = R.get(e)) == null || n.forEach((r) => {
897
926
  try {
898
- i(a);
927
+ r(t);
899
928
  } catch (d) {
900
929
  console.error("[Bravophone] listener falhou:", d);
901
930
  }
902
- }), (o = B.get("*")) == null || o.forEach((i) => {
931
+ }), (i = R.get("*")) == null || i.forEach((r) => {
903
932
  try {
904
- i({ event: e, payload: a });
933
+ r({ event: e, payload: t });
905
934
  } catch (d) {
906
935
  console.error("[Bravophone] listener falhou:", d);
907
936
  }
908
937
  });
909
938
  }
910
939
  function m() {
911
- if (!L) throw new Error("Bravophone: chame Bravophone.init() antes.");
912
- return L;
940
+ if (!S) throw new Error("Bravophone: chame Bravophone.init() antes.");
941
+ return S;
913
942
  }
914
- const re = {
943
+ const ie = {
915
944
  /**
916
945
  * Monta o webphone na página.
917
946
  * @param {object} opts
918
947
  * @param {string} [opts.hostUrl] Origem do webphone hospedado.
919
- * @param {string} [opts.token] Token de sessão do usuário (SSO do integrador).
948
+ * @param {object} [opts.session] Sessão do /api/voxfree/login o objeto
949
+ * inteiro: { vxToken, expiresIn, sip, tenant, ramal, clienteId, ramaisUrl }.
950
+ * É o que o webphone precisa para registrar sem passar pela tela de login.
951
+ * @param {string} [opts.token] Atalho para `{ vxToken }`. Sozinho não
952
+ * basta: sem sip e ramal o webphone carrega mas não registra.
920
953
  * @param {'bottom-right'|'bottom-left'|'top-right'|'top-left'} [opts.position]
921
954
  * @param {boolean} [opts.open] Abrir já visível (padrão: false, só o launcher).
922
955
  * @param {boolean} [opts.launcher] Exibir a aba de abertura (padrão: true).
@@ -928,15 +961,19 @@ const re = {
928
961
  * precisa estar na allowlist de CORS dos backends.
929
962
  */
930
963
  init(e = {}) {
931
- if (L) return L;
964
+ if (S) return S;
932
965
  if (typeof window == "undefined" || !document.body)
933
966
  throw new Error("Bravophone: init() precisa rodar no browser, após o <body> existir.");
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,
967
+ if (location.protocol !== "https:" && location.hostname !== "localhost" && console.warn("[Bravophone] Contexto inseguro: o microfone exige HTTPS ou localhost."), e.mode === "hosted" && !e.hostUrl)
968
+ throw new Error(
969
+ "Bravophone: mode 'hosted' exige hostUrl. Use mode 'srcdoc' (padrão) para carregar o webphone do CDN sem depender de um host próprio."
970
+ );
971
+ return S = Ae({
972
+ hostUrl: Re,
973
+ version: ie.version,
937
974
  ...e,
938
- emit: De
939
- }), L;
975
+ emit: Be
976
+ }), S;
940
977
  },
941
978
  // ---- Controle da janela ----
942
979
  show() {
@@ -955,11 +992,11 @@ const re = {
955
992
  minimize(e) {
956
993
  m().minimize(e);
957
994
  },
958
- move(e, a) {
959
- m().move(e, a);
995
+ move(e, t) {
996
+ m().move(e, t);
960
997
  },
961
- resize(e, a) {
962
- m().resize(e, a);
998
+ resize(e, t) {
999
+ m().resize(e, t);
963
1000
  },
964
1001
  /** 'left' | 'right' | 'left-half' | 'right-half' | 'max' | 'float' */
965
1002
  dock(e) {
@@ -974,15 +1011,15 @@ const re = {
974
1011
  m().setLauncherIcon(e);
975
1012
  },
976
1013
  get isOpen() {
977
- return L ? L.isOpen : !1;
1014
+ return S ? S.isOpen : !1;
978
1015
  },
979
1016
  get geometry() {
980
- return L ? L.geometry : null;
1017
+ return S ? S.geometry : null;
981
1018
  },
982
1019
  // ---- Telefonia ----
983
1020
  /** Disca um número. Aceita formato livre; a normalização é a mesma da extensão. */
984
- call(e, a) {
985
- return m().bridge.call("call", { number: e, meta: a });
1021
+ call(e, t) {
1022
+ return m().bridge.call("call", { number: e, meta: t });
986
1023
  },
987
1024
  hangup() {
988
1025
  return m().bridge.call("hangup");
@@ -1007,8 +1044,10 @@ const re = {
1007
1044
  getStatus() {
1008
1045
  return m().bridge.call("status");
1009
1046
  },
1047
+ /** Aceita a sessão completa do login, ou só o vxToken (insuficiente sozinho). */
1010
1048
  setAuth(e) {
1011
- return m().bridge.call("auth", { token: e });
1049
+ const t = typeof e == "string" ? { vxToken: e } : e;
1050
+ return m().bridge.call("auth", { session: t });
1012
1051
  },
1013
1052
  logout() {
1014
1053
  return m().bridge.call("logout");
@@ -1016,20 +1055,20 @@ const re = {
1016
1055
  // ---- Eventos ----
1017
1056
  /** Eventos: ready, state, call:dialing, call:incoming, call:answered,
1018
1057
  * call:ended, call:failed, resize, open, close, error. */
1019
- on(e, a) {
1020
- return B.has(e) || B.set(e, /* @__PURE__ */ new Set()), B.get(e).add(a), () => re.off(e, a);
1058
+ on(e, t) {
1059
+ return R.has(e) || R.set(e, /* @__PURE__ */ new Set()), R.get(e).add(t), () => ie.off(e, t);
1021
1060
  },
1022
- off(e, a) {
1061
+ off(e, t) {
1023
1062
  var n;
1024
- (n = B.get(e)) == null || n.delete(a);
1063
+ (n = R.get(e)) == null || n.delete(t);
1025
1064
  },
1026
1065
  destroy() {
1027
- L == null || L.destroy(), L = null, B.clear();
1066
+ S == null || S.destroy(), S = null, R.clear();
1028
1067
  },
1029
1068
  // Substituída em build time pelo valor do package.json (ver vite.config.js).
1030
- version: "0.2.1"
1069
+ version: "0.4.0"
1031
1070
  };
1032
- typeof window != "undefined" && (window.Bravophone = re);
1071
+ typeof window != "undefined" && (window.Bravophone = ie);
1033
1072
  export {
1034
- re as default
1073
+ ie as default
1035
1074
  };