@sphoro/bugcatch-web-sdk 0.20.0 → 0.21.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.
- package/README.md +39 -1
- package/dist/bugcatch-call.umd.js +1 -1
- package/dist/bugcatch-core.es.js +652 -497
- package/dist/bugcatch-core.es.js.map +1 -1
- package/dist/bugcatch-panel.es.js +1140 -938
- package/dist/bugcatch-panel.es.js.map +1 -1
- package/dist/bugcatch-panel.umd.js +237 -145
- package/dist/bugcatch-panel.umd.js.map +1 -1
- package/dist/bugcatch.standalone.umd.js +243 -151
- package/dist/bugcatch.standalone.umd.js.map +1 -1
- package/dist/bugcatch.umd.js +8 -8
- package/dist/bugcatch.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/feedback.js +94 -0
- package/src/identity.js +1 -1
- package/src/index.d.ts +56 -6
- package/src/index.js +111 -7
- package/src/panel/compose.js +1 -1
- package/src/panel/feedback.js +205 -0
- package/src/panel/icons.js +6 -0
- package/src/panel/index.js +83 -13
- package/src/panel/styles.js +47 -0
- package/src/widget.js +14 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(function(){"use strict";const Ie='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M4 11.5a7.5 7 0 0 1 7.5-7h1a7.5 7 0 0 1 0 14H9l-4.2 2.6a.5.5 0 0 1-.76-.5l.5-3.1A7 7 0 0 1 4 11.5z"/><path d="M8.5 11.5h.01M12 11.5h.01M15.5 11.5h.01" stroke-width="2.6"/></svg>',De='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="4.2"/><path d="M12 2.6v2.2M12 19.2v2.2M2.6 12h2.2M19.2 12h2.2M5.4 5.4l1.6 1.6M17 17l1.6 1.6M18.6 5.4L17 7M7 17l-1.6 1.6"/></svg>',je='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M20 13.4A8.2 8.2 0 1 1 10.6 4a6.6 6.6 0 0 0 9.4 9.4z"/></svg>',Ve='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><rect x="2.8" y="4.4" width="18.4" height="12.6" rx="2.2"/><path d="M8.6 20.2h6.8"/><path d="M12 4.4v12.6"/><path d="M12 7.2a3.6 3.6 0 0 1 0 7.2z" fill="currentColor" stroke="none"/></svg>',F='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M12 7.5v5.2M12 16.3h.01"/></svg>',J='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M6 6l12 12M18 6L6 18"/></svg>',O='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12.8l4.6 4.4L19 7"/></svg>',ue='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M12 11v5.5M12 7.7h.01"/></svg>',Oe='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10.3 4.2a2 2 0 0 1 3.4 0l7.6 13.1a2 2 0 0 1-1.7 3H4.4a2 2 0 0 1-1.7-3z"/><path d="M12 9.5v4.2M12 17h.01"/></svg>',Be='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M3 8.5A1.5 1.5 0 0 1 4.5 7h2.2a1 1 0 0 0 .83-.45l.94-1.4A1 1 0 0 1 9.3 4.7h5.4a1 1 0 0 1 .83.45l.94 1.4a1 1 0 0 0 .83.45h2.2A1.5 1.5 0 0 1 21 8.5v9A1.5 1.5 0 0 1 19.5 19h-15A1.5 1.5 0 0 1 3 17.5z"/><circle cx="12" cy="13" r="3.4"/></svg>',Ne='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="6" width="12.5" height="12" rx="2.2"/><path d="M15.5 10.8l4.2-2.6a.6.6 0 0 1 .92.5v6.6a.6.6 0 0 1-.92.5l-4.2-2.6z"/></svg>',he='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M20 11.5l-7.6 7.6a4.6 4.6 0 0 1-6.5-6.5l8-8a3.2 3.2 0 0 1 4.5 4.5l-8 8a1.8 1.8 0 0 1-2.5-2.5l7.1-7.1"/></svg>',fe='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="2.5" width="6" height="11" rx="3"/><path d="M5.5 11a6.5 6.5 0 0 0 13 0M12 17.5V21M9 21h6"/></svg>',be='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M4 12l16-8-6 16-2.6-6.2L4 12Z"/></svg>',We='<svg viewBox="0 0 24 24" fill="currentColor"><rect x="7" y="7" width="10" height="10" rx="2"/></svg>',Pe='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14.5 5.5L8 12l6.5 6.5"/></svg>',ee='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M6.2 3.5h3l1.5 3.7-2 1.4a11.5 11.5 0 0 0 5.7 5.7l1.4-2 3.7 1.5v3a1.8 1.8 0 0 1-2 1.8A15.6 15.6 0 0 1 4.4 5.5a1.8 1.8 0 0 1 1.8-2z"/></svg>',Ye='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 12a8 8 0 1 1-2.6-5.9M20 4v4.5h-4.5"/></svg>',Fe='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.5 6l6 6-6 6"/></svg>',ge='<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 2.9l2.75 5.82 6.37.76-4.7 4.37 1.24 6.3L12 17.03l-5.66 3.12 1.24-6.3-4.7-4.37 6.37-.76z"/></svg>',_e='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M3.5 13.5l2.6-7.2A1.5 1.5 0 0 1 7.5 5.3h9a1.5 1.5 0 0 1 1.4 1L20.5 13.5V18a1.5 1.5 0 0 1-1.5 1.5H5A1.5 1.5 0 0 1 3.5 18z"/><path d="M3.5 13.5h4.8l1.2 2.2h5l1.2-2.2h4.8"/></svg>',Ke='<svg class="bc-brand" viewBox="0 0 254 60" fill="none" role="img" aria-label="sphoro BugCatch"><g fill="currentColor"><path transform="translate(0.00 40.00) scale(0.04000 -0.04000)" d="M276.00 -14.00Q179.00 -14.00 117.00 28.00Q55.00 70.00 42.00 148.00L158.00 178.00Q165.00 143.00 181.50 123.00Q198.00 103.00 222.50 94.50Q247.00 86.00 276.00 86.00Q320.00 86.00 341.00 101.50Q362.00 117.00 362.00 140.00Q362.00 163.00 342.00 175.50Q322.00 188.00 278.00 196.00L250.00 201.00Q198.00 211.00 155.00 228.50Q112.00 246.00 86.00 277.00Q60.00 308.00 60.00 357.00Q60.00 431.00 114.00 470.50Q168.00 510.00 256.00 510.00Q339.00 510.00 394.00 473.00Q449.00 436.00 466.00 376.00L349.00 340.00Q341.00 378.00 316.50 394.00Q292.00 410.00 256.00 410.00Q220.00 410.00 201.00 397.50Q182.00 385.00 182.00 363.00Q182.00 339.00 202.00 327.50Q222.00 316.00 256.00 310.00L284.00 305.00Q340.00 295.00 385.50 278.50Q431.00 262.00 457.50 231.50Q484.00 201.00 484.00 149.00Q484.00 71.00 427.50 28.50Q371.00 -14.00 276.00 -14.00Z"/><path transform="translate(19.56 40.00) scale(0.04000 -0.04000)" d="M70.00 -200.00V496.00H194.00V436.00H212.00Q229.00 465.00 265.00 487.50Q301.00 510.00 368.00 510.00Q428.00 510.00 479.00 480.50Q530.00 451.00 561.00 394.00Q592.00 337.00 592.00 256.00V240.00Q592.00 159.00 561.00 102.00Q530.00 45.00 479.00 15.50Q428.00 -14.00 368.00 -14.00Q323.00 -14.00 292.50 -3.50Q262.00 7.00 243.50 23.50Q225.00 40.00 214.00 57.00H196.00V-200.00ZM330.00 96.00Q389.00 96.00 427.50 133.50Q466.00 171.00 466.00 243.00V253.00Q466.00 325.00 427.00 362.50Q388.00 400.00 330.00 400.00Q272.00 400.00 233.00 362.50Q194.00 325.00 194.00 253.00V243.00Q194.00 171.00 233.00 133.50Q272.00 96.00 330.00 96.00Z"/><path transform="translate(43.68 40.00) scale(0.04000 -0.04000)" d="M70.00 0.00V700.00H196.00V435.00H214.00Q222.00 451.00 239.00 467.00Q256.00 483.00 284.50 493.50Q313.00 504.00 357.00 504.00Q415.00 504.00 458.50 477.50Q502.00 451.00 526.00 404.50Q550.00 358.00 550.00 296.00V0.00H424.00V286.00Q424.00 342.00 396.50 370.00Q369.00 398.00 318.00 398.00Q260.00 398.00 228.00 359.50Q196.00 321.00 196.00 252.00V0.00Z"/><path transform="translate(66.92 40.00) scale(0.04000 -0.04000)" d="M306.00 -14.00Q232.00 -14.00 173.00 16.00Q114.00 46.00 80.00 103.00Q46.00 160.00 46.00 240.00V256.00Q46.00 336.00 80.00 393.00Q114.00 450.00 173.00 480.00Q232.00 510.00 306.00 510.00Q380.00 510.00 439.00 480.00Q498.00 450.00 532.00 393.00Q566.00 336.00 566.00 256.00V240.00Q566.00 160.00 532.00 103.00Q498.00 46.00 439.00 16.00Q380.00 -14.00 306.00 -14.00ZM306.00 98.00Q364.00 98.00 402.00 135.50Q440.00 173.00 440.00 243.00V253.00Q440.00 323.00 402.50 360.50Q365.00 398.00 306.00 398.00Q248.00 398.00 210.00 360.50Q172.00 323.00 172.00 253.00V243.00Q172.00 173.00 210.00 135.50Q248.00 98.00 306.00 98.00Z"/><path transform="translate(90.00 40.00) scale(0.04000 -0.04000)" d="M70.00 0.00V496.00H194.00V440.00H212.00Q223.00 470.00 248.50 484.00Q274.00 498.00 308.00 498.00H368.00V386.00H306.00Q258.00 386.00 227.00 360.50Q196.00 335.00 196.00 282.00V0.00Z"/><path transform="translate(104.44 40.00) scale(0.04000 -0.04000)" d="M306.00 -14.00Q232.00 -14.00 173.00 16.00Q114.00 46.00 80.00 103.00Q46.00 160.00 46.00 240.00V256.00Q46.00 336.00 80.00 393.00Q114.00 450.00 173.00 480.00Q232.00 510.00 306.00 510.00Q380.00 510.00 439.00 480.00Q498.00 450.00 532.00 393.00Q566.00 336.00 566.00 256.00V240.00Q566.00 160.00 532.00 103.00Q498.00 46.00 439.00 16.00Q380.00 -14.00 306.00 -14.00ZM306.00 98.00Q364.00 98.00 402.00 135.50Q440.00 173.00 440.00 243.00V253.00Q440.00 323.00 402.50 360.50Q365.00 398.00 306.00 398.00Q248.00 398.00 210.00 360.50Q172.00 323.00 172.00 253.00V243.00Q172.00 173.00 210.00 135.50Q248.00 98.00 306.00 98.00Z"/></g><rect x="139.52" y="16" width="1.6" height="26" rx="0.8" fill="var(--bc-brand-mark, #5647ee)" opacity="0.4"/><g fill="var(--bc-brand-mark, #5647ee)"><path transform="translate(154.52 35.00) scale(0.01400 -0.01400)" d="M46.35 0.00V105.85H139.75V594.15H46.35V700.00H404.08Q467.38 700.00 514.79 678.41Q562.20 656.83 588.70 617.33Q615.20 577.83 615.20 523.35V513.70Q615.20 465.52 597.03 434.76Q578.85 404.00 553.91 387.24Q528.98 370.48 506.28 363.30V346.35Q528.98 340.35 555.24 323.50Q581.50 306.65 600.00 275.48Q618.50 244.30 618.50 194.48V184.48Q618.50 126.65 591.41 85.24Q564.33 43.83 516.83 21.91Q469.33 0.00 406.85 0.00ZM259.85 109.15H392.60Q441.20 109.15 469.80 132.60Q498.40 156.05 498.40 198.55V208.20Q498.40 250.70 470.21 274.15Q442.02 297.60 392.60 297.60H259.85ZM259.85 406.75H391.65Q437.55 406.75 466.32 430.11Q495.10 453.48 495.10 493.80V503.80Q495.10 544.95 466.74 567.90Q438.37 590.85 391.65 590.85H259.85Z"/><path transform="translate(167.00 35.00) scale(0.01400 -0.01400)" d="M335.30 -14.00Q251.22 -14.00 190.60 16.63Q129.97 47.25 97.56 104.96Q65.15 162.68 65.15 243.03V700.00H185.25V239.73Q185.25 170.48 224.03 131.99Q262.80 93.50 335.30 93.50Q407.80 93.50 446.57 131.99Q485.35 170.48 485.35 239.73V700.00H605.45V243.03Q605.45 162.68 573.13 104.96Q540.80 47.25 480.09 16.63Q419.38 -14.00 335.30 -14.00Z"/><path transform="translate(179.60 35.00) scale(0.01400 -0.01400)" d="M311.85 -14.00Q238.45 -14.00 179.69 18.50Q120.92 51.00 86.69 113.67Q52.45 176.35 52.45 266.87V433.13Q52.45 569.00 128.01 641.50Q203.57 714.00 332.35 714.00Q460.13 714.00 529.23 645.59Q598.33 577.17 598.33 460.87V456.70H479.87V464.52Q479.87 504.67 463.76 536.86Q447.65 569.05 414.99 587.77Q382.32 606.50 332.35 606.50Q257.63 606.50 215.09 560.70Q172.55 514.90 172.55 435.13V264.87Q172.55 185.93 215.09 138.89Q257.63 91.85 334.00 91.85Q410.02 91.85 445.12 132.83Q480.22 173.80 480.22 237.92V249.67H302.85V351.88H598.33V0.00H487.52V69.10H470.57Q462.70 50.87 446.06 31.44Q429.42 12.00 397.64 -1.00Q365.85 -14.00 311.85 -14.00Z"/><path transform="translate(192.05 35.00) scale(0.01400 -0.01400)" d="M332.35 -14.00Q203.57 -14.00 128.01 58.50Q52.45 131.00 52.45 266.87V433.13Q52.45 569.00 128.01 641.50Q203.57 714.00 332.35 714.00Q460.13 714.00 529.58 643.85Q599.03 573.70 599.03 451.57V445.75H480.57V455.22Q480.57 521.42 444.15 563.96Q407.72 606.50 332.35 606.50Q257.63 606.50 215.09 560.70Q172.55 514.90 172.55 435.13V264.87Q172.55 185.93 215.09 139.71Q257.63 93.50 332.35 93.50Q407.72 93.50 444.15 136.45Q480.57 179.40 480.57 244.78V262.25H599.03V248.43Q599.03 126.30 529.58 56.15Q460.13 -14.00 332.35 -14.00Z"/><path transform="translate(204.25 35.00) scale(0.01400 -0.01400)" d="M19.75 0.00 211.62 700.00H421.33L613.20 0.00H489.27L447.42 159.60H185.53L143.68 0.00ZM214.25 270.40H418.70L324.95 624.87H308.00Z"/><path transform="translate(216.31 35.00) scale(0.01400 -0.01400)" d="M233.95 0.00V590.85H24.70V700.00H563.30V590.85H354.05V0.00Z"/><path transform="translate(227.75 35.00) scale(0.01400 -0.01400)" d="M332.35 -14.00Q203.57 -14.00 128.01 58.50Q52.45 131.00 52.45 266.87V433.13Q52.45 569.00 128.01 641.50Q203.57 714.00 332.35 714.00Q460.13 714.00 529.58 643.85Q599.03 573.70 599.03 451.57V445.75H480.57V455.22Q480.57 521.42 444.15 563.96Q407.72 606.50 332.35 606.50Q257.63 606.50 215.09 560.70Q172.55 514.90 172.55 435.13V264.87Q172.55 185.93 215.09 139.71Q257.63 93.50 332.35 93.50Q407.72 93.50 444.15 136.45Q480.57 179.40 480.57 244.78V262.25H599.03V248.43Q599.03 126.30 529.58 56.15Q460.13 -14.00 332.35 -14.00Z"/><path transform="translate(239.95 35.00) scale(0.01400 -0.01400)" d="M69.50 0.00V700.00H189.60V405.58H466.40V700.00H586.50V0.00H466.40V296.42H189.60V0.00Z"/></g></svg>',Ue=`
|
|
1
|
+
(function(){"use strict";const Ve='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M4 11.5a7.5 7 0 0 1 7.5-7h1a7.5 7 0 0 1 0 14H9l-4.2 2.6a.5.5 0 0 1-.76-.5l.5-3.1A7 7 0 0 1 4 11.5z"/><path d="M8.5 11.5h.01M12 11.5h.01M15.5 11.5h.01" stroke-width="2.6"/></svg>',Be='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="4.2"/><path d="M12 2.6v2.2M12 19.2v2.2M2.6 12h2.2M19.2 12h2.2M5.4 5.4l1.6 1.6M17 17l1.6 1.6M18.6 5.4L17 7M7 17l-1.6 1.6"/></svg>',Oe='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M20 13.4A8.2 8.2 0 1 1 10.6 4a6.6 6.6 0 0 0 9.4 9.4z"/></svg>',Ne='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><rect x="2.8" y="4.4" width="18.4" height="12.6" rx="2.2"/><path d="M8.6 20.2h6.8"/><path d="M12 4.4v12.6"/><path d="M12 7.2a3.6 3.6 0 0 1 0 7.2z" fill="currentColor" stroke="none"/></svg>',W='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M12 7.5v5.2M12 16.3h.01"/></svg>',J='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M6 6l12 12M18 6L6 18"/></svg>',O='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12.8l4.6 4.4L19 7"/></svg>',fe='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M12 11v5.5M12 7.7h.01"/></svg>',Fe='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10.3 4.2a2 2 0 0 1 3.4 0l7.6 13.1a2 2 0 0 1-1.7 3H4.4a2 2 0 0 1-1.7-3z"/><path d="M12 9.5v4.2M12 17h.01"/></svg>',We='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M3 8.5A1.5 1.5 0 0 1 4.5 7h2.2a1 1 0 0 0 .83-.45l.94-1.4A1 1 0 0 1 9.3 4.7h5.4a1 1 0 0 1 .83.45l.94 1.4a1 1 0 0 0 .83.45h2.2A1.5 1.5 0 0 1 21 8.5v9A1.5 1.5 0 0 1 19.5 19h-15A1.5 1.5 0 0 1 3 17.5z"/><circle cx="12" cy="13" r="3.4"/></svg>',Pe='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="6" width="12.5" height="12" rx="2.2"/><path d="M15.5 10.8l4.2-2.6a.6.6 0 0 1 .92.5v6.6a.6.6 0 0 1-.92.5l-4.2-2.6z"/></svg>',be='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M20 11.5l-7.6 7.6a4.6 4.6 0 0 1-6.5-6.5l8-8a3.2 3.2 0 0 1 4.5 4.5l-8 8a1.8 1.8 0 0 1-2.5-2.5l7.1-7.1"/></svg>',ge='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="2.5" width="6" height="11" rx="3"/><path d="M5.5 11a6.5 6.5 0 0 0 13 0M12 17.5V21M9 21h6"/></svg>',ie='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M4 12l16-8-6 16-2.6-6.2L4 12Z"/></svg>',Ke='<svg viewBox="0 0 24 24" fill="currentColor"><rect x="7" y="7" width="10" height="10" rx="2"/></svg>',Ye='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14.5 5.5L8 12l6.5 6.5"/></svg>',ee='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M6.2 3.5h3l1.5 3.7-2 1.4a11.5 11.5 0 0 0 5.7 5.7l1.4-2 3.7 1.5v3a1.8 1.8 0 0 1-2 1.8A15.6 15.6 0 0 1 4.4 5.5a1.8 1.8 0 0 1 1.8-2z"/></svg>',_e='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M8 6a4 4 0 0 1 8 0"/><rect x="7" y="7.5" width="10" height="12" rx="5"/><path d="M7 11H3.5M7 15.5H4M17 11h3.5M17 15.5h3M12 8v11.5"/></svg>',Ue='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 12a8 8 0 1 1-2.6-5.9M20 4v4.5h-4.5"/></svg>',Ze='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.5 6l6 6-6 6"/></svg>',me='<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 2.9l2.75 5.82 6.37.76-4.7 4.37 1.24 6.3L12 17.03l-5.66 3.12 1.24-6.3-4.7-4.37 6.37-.76z"/></svg>',Ge='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M3.5 13.5l2.6-7.2A1.5 1.5 0 0 1 7.5 5.3h9a1.5 1.5 0 0 1 1.4 1L20.5 13.5V18a1.5 1.5 0 0 1-1.5 1.5H5A1.5 1.5 0 0 1 3.5 18z"/><path d="M3.5 13.5h4.8l1.2 2.2h5l1.2-2.2h4.8"/></svg>',Xe='<svg class="bc-brand" viewBox="0 0 254 60" fill="none" role="img" aria-label="sphoro BugCatch"><g fill="currentColor"><path transform="translate(0.00 40.00) scale(0.04000 -0.04000)" d="M276.00 -14.00Q179.00 -14.00 117.00 28.00Q55.00 70.00 42.00 148.00L158.00 178.00Q165.00 143.00 181.50 123.00Q198.00 103.00 222.50 94.50Q247.00 86.00 276.00 86.00Q320.00 86.00 341.00 101.50Q362.00 117.00 362.00 140.00Q362.00 163.00 342.00 175.50Q322.00 188.00 278.00 196.00L250.00 201.00Q198.00 211.00 155.00 228.50Q112.00 246.00 86.00 277.00Q60.00 308.00 60.00 357.00Q60.00 431.00 114.00 470.50Q168.00 510.00 256.00 510.00Q339.00 510.00 394.00 473.00Q449.00 436.00 466.00 376.00L349.00 340.00Q341.00 378.00 316.50 394.00Q292.00 410.00 256.00 410.00Q220.00 410.00 201.00 397.50Q182.00 385.00 182.00 363.00Q182.00 339.00 202.00 327.50Q222.00 316.00 256.00 310.00L284.00 305.00Q340.00 295.00 385.50 278.50Q431.00 262.00 457.50 231.50Q484.00 201.00 484.00 149.00Q484.00 71.00 427.50 28.50Q371.00 -14.00 276.00 -14.00Z"/><path transform="translate(19.56 40.00) scale(0.04000 -0.04000)" d="M70.00 -200.00V496.00H194.00V436.00H212.00Q229.00 465.00 265.00 487.50Q301.00 510.00 368.00 510.00Q428.00 510.00 479.00 480.50Q530.00 451.00 561.00 394.00Q592.00 337.00 592.00 256.00V240.00Q592.00 159.00 561.00 102.00Q530.00 45.00 479.00 15.50Q428.00 -14.00 368.00 -14.00Q323.00 -14.00 292.50 -3.50Q262.00 7.00 243.50 23.50Q225.00 40.00 214.00 57.00H196.00V-200.00ZM330.00 96.00Q389.00 96.00 427.50 133.50Q466.00 171.00 466.00 243.00V253.00Q466.00 325.00 427.00 362.50Q388.00 400.00 330.00 400.00Q272.00 400.00 233.00 362.50Q194.00 325.00 194.00 253.00V243.00Q194.00 171.00 233.00 133.50Q272.00 96.00 330.00 96.00Z"/><path transform="translate(43.68 40.00) scale(0.04000 -0.04000)" d="M70.00 0.00V700.00H196.00V435.00H214.00Q222.00 451.00 239.00 467.00Q256.00 483.00 284.50 493.50Q313.00 504.00 357.00 504.00Q415.00 504.00 458.50 477.50Q502.00 451.00 526.00 404.50Q550.00 358.00 550.00 296.00V0.00H424.00V286.00Q424.00 342.00 396.50 370.00Q369.00 398.00 318.00 398.00Q260.00 398.00 228.00 359.50Q196.00 321.00 196.00 252.00V0.00Z"/><path transform="translate(66.92 40.00) scale(0.04000 -0.04000)" d="M306.00 -14.00Q232.00 -14.00 173.00 16.00Q114.00 46.00 80.00 103.00Q46.00 160.00 46.00 240.00V256.00Q46.00 336.00 80.00 393.00Q114.00 450.00 173.00 480.00Q232.00 510.00 306.00 510.00Q380.00 510.00 439.00 480.00Q498.00 450.00 532.00 393.00Q566.00 336.00 566.00 256.00V240.00Q566.00 160.00 532.00 103.00Q498.00 46.00 439.00 16.00Q380.00 -14.00 306.00 -14.00ZM306.00 98.00Q364.00 98.00 402.00 135.50Q440.00 173.00 440.00 243.00V253.00Q440.00 323.00 402.50 360.50Q365.00 398.00 306.00 398.00Q248.00 398.00 210.00 360.50Q172.00 323.00 172.00 253.00V243.00Q172.00 173.00 210.00 135.50Q248.00 98.00 306.00 98.00Z"/><path transform="translate(90.00 40.00) scale(0.04000 -0.04000)" d="M70.00 0.00V496.00H194.00V440.00H212.00Q223.00 470.00 248.50 484.00Q274.00 498.00 308.00 498.00H368.00V386.00H306.00Q258.00 386.00 227.00 360.50Q196.00 335.00 196.00 282.00V0.00Z"/><path transform="translate(104.44 40.00) scale(0.04000 -0.04000)" d="M306.00 -14.00Q232.00 -14.00 173.00 16.00Q114.00 46.00 80.00 103.00Q46.00 160.00 46.00 240.00V256.00Q46.00 336.00 80.00 393.00Q114.00 450.00 173.00 480.00Q232.00 510.00 306.00 510.00Q380.00 510.00 439.00 480.00Q498.00 450.00 532.00 393.00Q566.00 336.00 566.00 256.00V240.00Q566.00 160.00 532.00 103.00Q498.00 46.00 439.00 16.00Q380.00 -14.00 306.00 -14.00ZM306.00 98.00Q364.00 98.00 402.00 135.50Q440.00 173.00 440.00 243.00V253.00Q440.00 323.00 402.50 360.50Q365.00 398.00 306.00 398.00Q248.00 398.00 210.00 360.50Q172.00 323.00 172.00 253.00V243.00Q172.00 173.00 210.00 135.50Q248.00 98.00 306.00 98.00Z"/></g><rect x="139.52" y="16" width="1.6" height="26" rx="0.8" fill="var(--bc-brand-mark, #5647ee)" opacity="0.4"/><g fill="var(--bc-brand-mark, #5647ee)"><path transform="translate(154.52 35.00) scale(0.01400 -0.01400)" d="M46.35 0.00V105.85H139.75V594.15H46.35V700.00H404.08Q467.38 700.00 514.79 678.41Q562.20 656.83 588.70 617.33Q615.20 577.83 615.20 523.35V513.70Q615.20 465.52 597.03 434.76Q578.85 404.00 553.91 387.24Q528.98 370.48 506.28 363.30V346.35Q528.98 340.35 555.24 323.50Q581.50 306.65 600.00 275.48Q618.50 244.30 618.50 194.48V184.48Q618.50 126.65 591.41 85.24Q564.33 43.83 516.83 21.91Q469.33 0.00 406.85 0.00ZM259.85 109.15H392.60Q441.20 109.15 469.80 132.60Q498.40 156.05 498.40 198.55V208.20Q498.40 250.70 470.21 274.15Q442.02 297.60 392.60 297.60H259.85ZM259.85 406.75H391.65Q437.55 406.75 466.32 430.11Q495.10 453.48 495.10 493.80V503.80Q495.10 544.95 466.74 567.90Q438.37 590.85 391.65 590.85H259.85Z"/><path transform="translate(167.00 35.00) scale(0.01400 -0.01400)" d="M335.30 -14.00Q251.22 -14.00 190.60 16.63Q129.97 47.25 97.56 104.96Q65.15 162.68 65.15 243.03V700.00H185.25V239.73Q185.25 170.48 224.03 131.99Q262.80 93.50 335.30 93.50Q407.80 93.50 446.57 131.99Q485.35 170.48 485.35 239.73V700.00H605.45V243.03Q605.45 162.68 573.13 104.96Q540.80 47.25 480.09 16.63Q419.38 -14.00 335.30 -14.00Z"/><path transform="translate(179.60 35.00) scale(0.01400 -0.01400)" d="M311.85 -14.00Q238.45 -14.00 179.69 18.50Q120.92 51.00 86.69 113.67Q52.45 176.35 52.45 266.87V433.13Q52.45 569.00 128.01 641.50Q203.57 714.00 332.35 714.00Q460.13 714.00 529.23 645.59Q598.33 577.17 598.33 460.87V456.70H479.87V464.52Q479.87 504.67 463.76 536.86Q447.65 569.05 414.99 587.77Q382.32 606.50 332.35 606.50Q257.63 606.50 215.09 560.70Q172.55 514.90 172.55 435.13V264.87Q172.55 185.93 215.09 138.89Q257.63 91.85 334.00 91.85Q410.02 91.85 445.12 132.83Q480.22 173.80 480.22 237.92V249.67H302.85V351.88H598.33V0.00H487.52V69.10H470.57Q462.70 50.87 446.06 31.44Q429.42 12.00 397.64 -1.00Q365.85 -14.00 311.85 -14.00Z"/><path transform="translate(192.05 35.00) scale(0.01400 -0.01400)" d="M332.35 -14.00Q203.57 -14.00 128.01 58.50Q52.45 131.00 52.45 266.87V433.13Q52.45 569.00 128.01 641.50Q203.57 714.00 332.35 714.00Q460.13 714.00 529.58 643.85Q599.03 573.70 599.03 451.57V445.75H480.57V455.22Q480.57 521.42 444.15 563.96Q407.72 606.50 332.35 606.50Q257.63 606.50 215.09 560.70Q172.55 514.90 172.55 435.13V264.87Q172.55 185.93 215.09 139.71Q257.63 93.50 332.35 93.50Q407.72 93.50 444.15 136.45Q480.57 179.40 480.57 244.78V262.25H599.03V248.43Q599.03 126.30 529.58 56.15Q460.13 -14.00 332.35 -14.00Z"/><path transform="translate(204.25 35.00) scale(0.01400 -0.01400)" d="M19.75 0.00 211.62 700.00H421.33L613.20 0.00H489.27L447.42 159.60H185.53L143.68 0.00ZM214.25 270.40H418.70L324.95 624.87H308.00Z"/><path transform="translate(216.31 35.00) scale(0.01400 -0.01400)" d="M233.95 0.00V590.85H24.70V700.00H563.30V590.85H354.05V0.00Z"/><path transform="translate(227.75 35.00) scale(0.01400 -0.01400)" d="M332.35 -14.00Q203.57 -14.00 128.01 58.50Q52.45 131.00 52.45 266.87V433.13Q52.45 569.00 128.01 641.50Q203.57 714.00 332.35 714.00Q460.13 714.00 529.58 643.85Q599.03 573.70 599.03 451.57V445.75H480.57V455.22Q480.57 521.42 444.15 563.96Q407.72 606.50 332.35 606.50Q257.63 606.50 215.09 560.70Q172.55 514.90 172.55 435.13V264.87Q172.55 185.93 215.09 139.71Q257.63 93.50 332.35 93.50Q407.72 93.50 444.15 136.45Q480.57 179.40 480.57 244.78V262.25H599.03V248.43Q599.03 126.30 529.58 56.15Q460.13 -14.00 332.35 -14.00Z"/><path transform="translate(239.95 35.00) scale(0.01400 -0.01400)" d="M69.50 0.00V700.00H189.60V405.58H466.40V700.00H586.50V0.00H466.40V296.42H189.60V0.00Z"/></g></svg>',Je='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M4.5 5.5h15a1 1 0 0 1 1 1v9a1 1 0 0 1-1 1h-8l-4.3 3.2a.5.5 0 0 1-.8-.4v-2.8H4.5a1 1 0 0 1-1-1v-9a1 1 0 0 1 1-1z"/><path d="M12 8.4l.9 1.9 2 .3-1.5 1.4.4 2-1.8-1-1.8 1 .4-2-1.5-1.4 2-.3z"/></svg>',et='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M9 17.5h6M10 21h4"/><path d="M12 3a6 6 0 0 0-3.6 10.8c.6.5 1 1.2 1 2V17h5.2v-1.2c0-.8.4-1.5 1-2A6 6 0 0 0 12 3z"/></svg>',tt='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 20s-7.5-4.6-7.5-10.2A4.3 4.3 0 0 1 12 7.2a4.3 4.3 0 0 1 7.5 2.6C19.5 15.4 12 20 12 20z"/></svg>',at='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M9.6 9.4a2.5 2.5 0 0 1 4.8.9c0 1.7-2.4 2.2-2.4 3.6M12 17h.01"/></svg>',nt='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.8" stroke-linecap="round"><path d="M6.5 12h.01M12 12h.01M17.5 12h.01"/></svg>',ot=`
|
|
2
2
|
@keyframes bc-fade-in { from { opacity: 0 } to { opacity: 1 } }
|
|
3
3
|
@keyframes bc-fade-out { to { opacity: 0 } }
|
|
4
4
|
@keyframes bc-panel-in { from { opacity: 0; transform: translateY(14px) scale(.965) } to { opacity: 1; transform: none } }
|
|
@@ -296,6 +296,53 @@ textarea { min-height: 76px; resize: vertical; }
|
|
|
296
296
|
.seg button[aria-pressed=true]::before { opacity: 1; }
|
|
297
297
|
.seg button:focus-visible { outline-offset: -2px; }
|
|
298
298
|
|
|
299
|
+
/* ---------- report a bug, or give feedback ----------
|
|
300
|
+
The same stone track as the severity control, two wide segments, under the
|
|
301
|
+
header so it stays put while the form scrolls. Each form's own parts carry
|
|
302
|
+
bug-only or fb-only; the other screens (history, a conversation, a call)
|
|
303
|
+
carry neither, so a mode left on the panel cannot hide anything of theirs. */
|
|
304
|
+
.modes {
|
|
305
|
+
flex: none; display: grid; grid-template-columns: 1fr 1fr; gap: 2px;
|
|
306
|
+
margin: 12px var(--bc-pad) 0; padding: 3px; background: var(--bc-stone); border-radius: 999px;
|
|
307
|
+
}
|
|
308
|
+
.modes button {
|
|
309
|
+
display: inline-flex; align-items: center; justify-content: center; gap: 7px; min-width: 0;
|
|
310
|
+
height: 32px; padding: 0 8px; font: inherit; font-size: var(--bc-fs-sm); font-weight: 520; line-height: 1; white-space: nowrap;
|
|
311
|
+
color: var(--bc-muted); background: none; border: none; border-radius: 999px;
|
|
312
|
+
cursor: pointer; transition: background 180ms var(--bc-ease), color 180ms, box-shadow 180ms;
|
|
313
|
+
}
|
|
314
|
+
.modes button svg { font-size: 15px; flex: none; }
|
|
315
|
+
.modes button:hover { color: var(--bc-fg); }
|
|
316
|
+
.modes button[aria-pressed=true] {
|
|
317
|
+
background: var(--bc-raised); color: var(--bc-fg); font-weight: 600;
|
|
318
|
+
box-shadow: 0 1px 2px rgba(20,18,14,.10), 0 0 0 .5px rgba(20,18,14,.08);
|
|
319
|
+
}
|
|
320
|
+
.modes button:focus-visible { outline-offset: -2px; }
|
|
321
|
+
.panel[data-mode="feedback"] .bug-only,
|
|
322
|
+
.panel:not([data-mode="feedback"]) .fb-only { display: none !important; }
|
|
323
|
+
|
|
324
|
+
/* ---------- feedback ---------- */
|
|
325
|
+
.feedback { animation: bc-fade-in 200ms ease both; }
|
|
326
|
+
.feedback textarea { min-height: 96px; }
|
|
327
|
+
.feedback .kinds { display: flex; flex-wrap: wrap; gap: 6px; }
|
|
328
|
+
.feedback .kinds .tool[aria-pressed=true] { background: var(--bc-accent); border-color: var(--bc-accent); color: var(--bc-on-accent); }
|
|
329
|
+
.feedback .kinds .tool[aria-pressed=true] svg { color: currentColor; }
|
|
330
|
+
.faces { display: flex; gap: 6px; }
|
|
331
|
+
.face {
|
|
332
|
+
flex: 1 1 0; display: grid; place-items: center; height: 42px; padding: 0;
|
|
333
|
+
font: inherit; font-size: 24px; color: var(--bc-muted); background: var(--bc-stone);
|
|
334
|
+
border: 1px solid transparent; border-radius: var(--bc-r-md); cursor: pointer;
|
|
335
|
+
transition: background 160ms, color 160ms, transform 160ms var(--bc-ease);
|
|
336
|
+
}
|
|
337
|
+
.face:hover { color: var(--bc-fg); background: color-mix(in srgb, var(--bc-fg) 8%, var(--bc-stone)); }
|
|
338
|
+
.face:active { transform: scale(.94); }
|
|
339
|
+
.face[aria-pressed=true] { color: var(--bc-on-accent); background: var(--bc-accent); }
|
|
340
|
+
.face:focus-visible { outline-offset: 2px; }
|
|
341
|
+
.face-word { font-weight: 560; color: var(--bc-muted); }
|
|
342
|
+
.fb-as { margin: 0; font-size: var(--bc-fs-xs); line-height: 1.45; color: var(--bc-muted); }
|
|
343
|
+
.fb-as strong { color: var(--bc-fg); font-weight: 600; word-break: break-all; }
|
|
344
|
+
.fb-who:empty { display: none; }
|
|
345
|
+
|
|
299
346
|
/* ---------- attachments ----------
|
|
300
347
|
Three ring pills in a row: optional, so they take one line, not a band of
|
|
301
348
|
dashed drop zones. */
|
|
@@ -1031,29 +1078,29 @@ div.done { padding: 44px 26px 44px; text-align: center; animation: bc-fade-in 24
|
|
|
1031
1078
|
@media (hover: none) {
|
|
1032
1079
|
.tool:hover:not(:disabled) { transform: none; }
|
|
1033
1080
|
}
|
|
1034
|
-
`;function
|
|
1081
|
+
`;function se({title:e,sub:t,id:a="",back:s=!1,theme:c=""}){return`
|
|
1035
1082
|
<div class="head">
|
|
1036
|
-
${
|
|
1083
|
+
${s?`<button class="icon-btn back" type="button" data-act="back" aria-label="Back to your reports">${Ye}</button>`:""}
|
|
1037
1084
|
<span class="orb mark" aria-hidden="true"></span>
|
|
1038
1085
|
<div class="titles">
|
|
1039
1086
|
<h2${a?` id="${a}"`:""}>${k(e)}</h2>
|
|
1040
1087
|
<p>${k(t)}</p>
|
|
1041
1088
|
</div>
|
|
1042
|
-
${
|
|
1043
|
-
aria-label="Theme: ${k(
|
|
1089
|
+
${c?`<button class="icon-btn theme" type="button" data-act="theme" title="Theme: ${k(c)}"
|
|
1090
|
+
aria-label="Theme: ${k(c)}. Change theme"><span class="m-light">${Be}</span><span class="m-dark">${Oe}</span><span class="m-auto">${Ne}</span></button>`:""}
|
|
1044
1091
|
<button class="icon-btn" type="button" data-act="close" aria-label="Close">${J}</button>
|
|
1045
|
-
</div>`}function
|
|
1092
|
+
</div>`}function ce(e,t){return`<div class="empty"><span class="empty-ico" aria-hidden="true">${t}</span>${k(e)}</div>`}function rt(e){return Array.from({length:e},()=>`
|
|
1046
1093
|
<div class="row" aria-hidden="true">
|
|
1047
1094
|
<span class="row-ico"></span>
|
|
1048
1095
|
<span class="who"><span class="skel" style="width:70%"></span><span class="skel" style="width:40%;height:9px"></span></span>
|
|
1049
|
-
</div>`).join("")+'<span class="sr-only">Loading…</span>'}function
|
|
1096
|
+
</div>`).join("")+'<span class="sr-only">Loading…</span>'}function it(){return`
|
|
1050
1097
|
<div aria-hidden="true" style="display:flex;flex-direction:column;gap:10px;padding-top:6px">
|
|
1051
1098
|
<span class="skel" style="width:42%;height:34px;border-radius:16px;align-self:center"></span>
|
|
1052
1099
|
<span class="skel" style="width:66%;height:52px;border-radius:18px"></span>
|
|
1053
1100
|
<span class="skel" style="width:48%;height:38px;border-radius:18px;align-self:flex-end"></span>
|
|
1054
1101
|
</div>
|
|
1055
|
-
<span class="sr-only">Loading…</span>`}function
|
|
1056
|
-
<div class="compose">
|
|
1102
|
+
<span class="sr-only">Loading…</span>`}function st(e){const t=String(e).trim().split(/\s+/).filter(Boolean);return t.length?(t[0][0]+(t.length>1?t[t.length-1][0]:"")).toUpperCase():"?"}function _(e){const t=new Date(e);return Number.isFinite(t.getTime())?`${t.getFullYear()}-${t.getMonth()}-${t.getDate()}`:null}function ct(e){const t=new Date(e),a=new Date,s=new Date(a.getFullYear(),a.getMonth(),a.getDate()-1);if(_(t)===_(a))return"Today";if(_(t)===_(s))return"Yesterday";try{return t.toLocaleDateString(void 0,{weekday:"short",day:"numeric",month:"short",...t.getFullYear()!==a.getFullYear()?{year:"numeric"}:{}})}catch{return Z(e)}}function ve(e){const t=new Date(e);if(!Number.isFinite(t.getTime()))return"";try{return t.toLocaleTimeString(void 0,{hour:"numeric",minute:"2-digit"})}catch{return""}}function ye(e){return e.scrollHeight-e.scrollTop-e.clientHeight<40}function U(e,{smooth:t=!1}={}){const a=typeof matchMedia=="function"&&matchMedia("(prefers-reduced-motion: reduce)").matches;t&&!a&&e.scrollTo?e.scrollTo({top:e.scrollHeight,behavior:"smooth"}):e.scrollTop=e.scrollHeight}function le(e){return{OPEN:"Open",IN_PROGRESS:"In progress",RESOLVED:"Fixed",CLOSED:"Closed"}[e]||String(e||"").toLowerCase()}function Z(e){const t=new Date(e).getTime();if(!Number.isFinite(t))return"";const a=Math.floor((Date.now()-t)/864e5);if(a<=0)return"today";if(a===1)return"yesterday";if(a<30)return`${a} days ago`;const s=Math.floor(a/30);return s===1?"a month ago":`${s} months ago`}function k(e){return String(e).replace(/[&<>"']/g,t=>({"&":"&","<":"<",">":">",'"':""","'":"'"})[t])}typeof window<"u"&&window.fetch&&window.fetch.bind(window);const we=["image/png","image/jpeg","image/webp","image/gif","video/webm","video/mp4","audio/webm","audio/ogg","audio/mpeg","audio/mp4","audio/wav","application/pdf","text/plain","text/csv","application/json","application/zip","application/msword","application/vnd.openxmlformats-officedocument.wordprocessingml.document","application/vnd.ms-excel","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"],xe=["image/png","image/jpeg","image/webp","video/webm","video/mp4"],lt=()=>{var e;return!!((e=navigator==null?void 0:navigator.mediaDevices)!=null&&e.getUserMedia&&typeof MediaRecorder<"u")},dt=()=>{var e;return!!((e=navigator==null?void 0:navigator.mediaDevices)!=null&&e.getDisplayMedia&&typeof MediaRecorder<"u")},pt=()=>{var e;return!!((e=navigator==null?void 0:navigator.mediaDevices)!=null&&e.getDisplayMedia)};function ut(e,t=we){const a=String(e||"").split(";")[0].trim().toLowerCase();return t.includes(a)?a:null}async function ht(){const e=await navigator.mediaDevices.getDisplayMedia({video:{frameRate:1},audio:!1});try{const t=e.getVideoTracks()[0],a=document.createElement("video");a.srcObject=e,a.muted=!0,a.playsInline=!0,await a.play(),await new Promise(d=>requestAnimationFrame(()=>requestAnimationFrame(d)));const{width:s,height:c}=t.getSettings(),u=document.createElement("canvas");u.width=s||a.videoWidth,u.height=c||a.videoHeight,u.getContext("2d").drawImage(a,0,0,u.width,u.height);const f=await new Promise(d=>u.toBlob(d,"image/png"));if(!f)throw new Error("The browser returned an empty screenshot.");return{blob:f,mime:"image/png",kind:"SCREENSHOT"}}finally{e.getTracks().forEach(t=>t.stop())}}async function ft({maxMs:e=12e4,onTick:t,onAutoStop:a}={}){const s=await navigator.mediaDevices.getDisplayMedia({video:{frameRate:15},audio:!1}),c=["video/webm;codecs=vp9","video/webm;codecs=vp8","video/webm"].find(p=>MediaRecorder.isTypeSupported(p))||"video/webm",u=new MediaRecorder(s,{mimeType:c,videoBitsPerSecond:25e5}),f=[];u.ondataavailable=p=>{p.data.size&&f.push(p.data)},u.start(1e3);const d=Date.now(),h=setInterval(()=>t==null?void 0:t(Math.floor((Date.now()-d)/1e3)),500),b=()=>{clearInterval(h),clearTimeout(n),s.getTracks().forEach(p=>p.stop())},g=new Promise(p=>{u.onstop=()=>{b(),p(new Blob(f,{type:c}))}}),$=()=>{u.state!=="inactive"&&u.stop(),a==null||a()};s.getVideoTracks()[0].addEventListener("ended",$);const n=setTimeout($,e);return{mime:c,maxMs:e,async stop(){return clearTimeout(n),u.state!=="inactive"&&u.stop(),{blob:await g,mime:c,kind:"VIDEO"}},cancel(){b(),u.state!=="inactive"&&u.stop()}}}async function bt({maxMs:e=12e4,onTick:t,onAutoStop:a}={}){const s=await navigator.mediaDevices.getUserMedia({audio:!0}),c=["audio/webm;codecs=opus","audio/webm","audio/mp4","audio/ogg"].find(p=>MediaRecorder.isTypeSupported(p))||"",u=new MediaRecorder(s,c?{mimeType:c}:void 0),f=[];u.ondataavailable=p=>{p.data.size&&f.push(p.data)},u.start(1e3);const d=Date.now(),h=setInterval(()=>t==null?void 0:t(Math.floor((Date.now()-d)/1e3)),500),b=()=>{clearInterval(h),clearTimeout(n),s.getTracks().forEach(p=>p.stop())},g=new Promise(p=>{u.onstop=()=>{b(),p(new Blob(f,{type:u.mimeType||c}))}}),n=setTimeout(()=>{u.state!=="inactive"&&u.stop(),a==null||a()},e);return{mime:u.mimeType||c,maxMs:e,async stop(){clearTimeout(n),u.state!=="inactive"&&u.stop();const p=await g;return{blob:p,mime:p.type||u.mimeType||c,kind:"AUDIO"}},cancel(){b(),u.state!=="inactive"&&u.stop()}}}function Y(e){return e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(0)} KB`:`${(e/1024/1024).toFixed(1)} MB`}function te(e){const t=Math.floor(e/60),a=e%60;return`${t}:${String(a).padStart(2,"0")}`}const gt=7*24*60*60*1e3;let ae;function mt(){return ae||(ae=new Promise((e,t)=>{const a=indexedDB.open("bugcatch-drafts",1);a.onupgradeneeded=()=>a.result.createObjectStore("drafts"),a.onsuccess=()=>e(a.result),a.onerror=()=>t(a.error),a.onblocked=()=>t(new Error("Draft storage is blocked."))}).catch(e=>{throw ae=null,e})),ae}function vt(e,t){var a,s;return JSON.stringify([e.apiBase,e.projectId,t||((a=e.user)==null?void 0:a.email)||((s=e.user)==null?void 0:s.id)||"anonymous"])}async function ne(e,t){const a=await mt();return new Promise((s,c)=>{const u=a.transaction("drafts",t===void 0?"readonly":"readwrite"),f=u.objectStore("drafts"),d=t===void 0?f.get(e):t===null?f.delete(e):f.put({...t,savedAt:Date.now()},e);u.oncomplete=()=>s(d.result),u.onerror=()=>c(u.error),u.onabort=()=>c(u.error||new Error("Draft was not saved."))})}async function yt(e){const t=await ne(e);return t&&Date.now()-t.savedAt>gt?(await ne(e,null),null):t||null}const ke=[{value:"LOW",label:"Low"},{value:"MEDIUM",label:"Medium"},{value:"HIGH",label:"High"},{value:"CRITICAL",label:"Critical"}],$e="MEDIUM";function wt(e){const t=e.attachments!==!1,a=t&&pt(),s=t&&dt();return`
|
|
1103
|
+
<div class="compose bug-only">
|
|
1057
1104
|
<div class="field">
|
|
1058
1105
|
<label for="bc-title">What went wrong?</label>
|
|
1059
1106
|
<input id="bc-title" type="text" placeholder="e.g. The checkout button does nothing" autocomplete="off"
|
|
@@ -1072,8 +1119,8 @@ div.done { padding: 44px 26px 44px; text-align: center; animation: bc-fade-in 24
|
|
|
1072
1119
|
<div class="field">
|
|
1073
1120
|
<label id="bc-prio-l">How much is it getting in your way?</label>
|
|
1074
1121
|
<div class="seg" role="group" aria-labelledby="bc-prio-l">
|
|
1075
|
-
${
|
|
1076
|
-
<button type="button" data-prio="${
|
|
1122
|
+
${ke.map(c=>`
|
|
1123
|
+
<button type="button" data-prio="${c.value}" aria-pressed="${c.value===$e}">${c.label}</button>
|
|
1077
1124
|
`).join("")}
|
|
1078
1125
|
</div>
|
|
1079
1126
|
</div>
|
|
@@ -1084,23 +1131,23 @@ div.done { padding: 44px 26px 44px; text-align: center; animation: bc-fade-in 24
|
|
|
1084
1131
|
<span class="count" aria-live="polite"></span>
|
|
1085
1132
|
</div>
|
|
1086
1133
|
<div class="tools" role="group" aria-labelledby="bc-att-l">
|
|
1087
|
-
${a?`<button class="tool" type="button" data-act="shot">${
|
|
1088
|
-
${
|
|
1089
|
-
<button class="tool" type="button" data-act="file">${
|
|
1134
|
+
${a?`<button class="tool" type="button" data-act="shot">${We}Screenshot</button>`:""}
|
|
1135
|
+
${s?`<button class="tool" type="button" data-act="rec">${Pe}Record screen</button>`:""}
|
|
1136
|
+
<button class="tool" type="button" data-act="file">${be}Upload file</button>
|
|
1090
1137
|
</div>
|
|
1091
1138
|
<div class="thumbs"></div>
|
|
1092
|
-
<input type="file" accept="${
|
|
1139
|
+
<input type="file" accept="${xe.join(",")}" multiple hidden />
|
|
1093
1140
|
</div>`:""}
|
|
1094
|
-
</div>`}function
|
|
1095
|
-
${
|
|
1096
|
-
<span class="kind">${R} · ${
|
|
1141
|
+
</div>`}function xt(e){var he,G,X,z;const{client:t,cfg:a,root:s,host:c,dock:u,scrim:f,$:d,say:h,titleInput:b,descInput:g,compose:$,sendBtn:n,note:p}=e,y=d(".thumbs"),L=f.querySelector("input[type=file]"),o=[];let i=$e,l=null;const r=document.createElement("div");r.setAttribute("role","status"),r.className="note",$.prepend(r);const S=vt(a,(he=t.signedInAs())==null?void 0:he.email);let E=a.drafts===!1,x=!1,m=Promise.resolve(),M;function v(){if(clearTimeout(M),!E||x||a.drafts===!1)return m;const w=b.value||g.value||o.length?{title:b.value,description:g.value,priority:i,items:o.map(({blob:Q,mime:R,kind:D})=>({blob:Q,mime:R,kind:D}))}:null;return m=m.catch(()=>{}).then(()=>ne(S,w)).then(()=>{r.textContent=w?"Draft saved on this device":""}).catch(()=>{r.textContent="Draft could not be saved. Keep this tab open."}),m}function q(){clearTimeout(M),M=setTimeout(v,250)}$.addEventListener("input",q),$.addEventListener("change",q);const C=()=>{v()};window.addEventListener("pagehide",C);function A(){o.filter(w=>w.status==="failed").forEach(N)}window.addEventListener("online",A),a.drafts!==!1&&($.inert=!0,yt(S).then(w=>{e.closed||!w||(r.innerHTML='<span>You have an unfinished report on this device.</span> <button type="button" data-resume>Resume report</button> <button type="button" data-discard>Discard</button>',r.querySelector("[data-resume]").onclick=()=>{b.value=w.title||"",g.value=w.description||"",i=ke.some(Q=>Q.value===w.priority)?w.priority:"MEDIUM",f.querySelectorAll("[data-prio]").forEach(Q=>Q.setAttribute("aria-pressed",String(Q.dataset.prio===i)));for(const Q of(w.items||[]).slice(0,a.maxAttachments??5))P(Q);E=!0,v()},r.querySelector("[data-discard]").onclick=()=>{E=!0,v()})}).catch(()=>{r.textContent="Draft storage is unavailable. Keep this tab open."}).finally(()=>{$.inert=e.mustRate(),r.querySelector("[data-resume]")||(E=!0)})),e.onDestroy(()=>{var w;v(),clearTimeout(M),window.removeEventListener("pagehide",C),window.removeEventListener("online",A),l==null||l.cancel(),o.forEach(Q=>Q.previewUrl&&URL.revokeObjectURL(Q.previewUrl)),(w=s.querySelector(".recbar"))==null||w.remove()}),f.querySelectorAll("[data-prio]").forEach(w=>{w.addEventListener("click",()=>{i=w.dataset.prio,q(),f.querySelectorAll("[data-prio]").forEach(Q=>{Q.setAttribute("aria-pressed",String(Q===w))})})});const B=d("#bc-title-err");function T(w){B.hidden=!w,B.innerHTML=w?`${W}<span>${k(w)}</span>`:"",b.classList.toggle("invalid",!!w),b.setAttribute("aria-invalid",String(!!w))}b.addEventListener("input",()=>{b.value.trim()&&T("")});function I(){const w=o.some(j=>j.status==="uploading"),Q=e.mustRate();n.disabled=e.sending||w||Q||o.some(j=>j.status==="failed"),p.textContent=Q?"Rate your last report to send a new one.":w?"Waiting for the upload to finish…":o.some(j=>j.status==="failed")?"Retry or remove failed attachments before sending.":"";const R=a.maxAttachments??5;f.querySelectorAll(".tool").forEach(j=>{j.disabled=e.sending||o.length>=R});const D=d(".field-head .count");D&&(D.textContent=o.length?`${o.length} of ${R}`:"")}e.refreshSendState=I;function H(w){var K;const Q=w.el,R=w.kind==="VIDEO"?"Video":"Shot",D=w.kind==="VIDEO"?`<video src="${w.previewUrl}" muted playsinline preload="metadata"></video>`:`<img src="${w.previewUrl}" alt="" />`;let j="";w.status==="uploading"?j=`<div class="veil"><div class="spinner"></div><div class="bar"><i style="width:${Math.round(w.progress*100)}%"></i></div></div>`:w.status==="failed"&&(j=`<div class="veil err"><button type="button" data-act="retry" aria-label="Retry upload">${Ue}</button>Failed</div>`),Q.innerHTML=`
|
|
1142
|
+
${D}
|
|
1143
|
+
<span class="kind">${R} · ${Y(w.size)}</span>
|
|
1097
1144
|
<button class="drop" type="button" data-act="drop" aria-label="Remove ${R.toLowerCase()}">${J}</button>
|
|
1098
|
-
${
|
|
1145
|
+
${j}`,Q.querySelector('[data-act="drop"]').addEventListener("click",()=>V(w)),(K=Q.querySelector('[data-act="retry"]'))==null||K.addEventListener("click",()=>N(w))}function V(w){const Q=o.indexOf(w);Q>=0&&o.splice(Q,1),w.previewUrl&&URL.revokeObjectURL(w.previewUrl),w.el.remove(),v(),I()}async function N(w){w.status="uploading",w.progress=0,H(w),I();try{const{storageKey:Q,mime:R}=await t.uploadAttachment(w.blob,w.mime,D=>{w.progress=D;const j=w.el.querySelector(".bar i");j&&(j.style.width=`${Math.round(D*100)}%`)});w.storageKey=Q,w.mime=R,w.status="ready"}catch(Q){w.status="failed",h(Q.message.replace("[BugCatch] ",""))}H(w),I()}function P({blob:w,mime:Q,kind:R}){const D=a.maxAttachmentBytes??26214400;if(w.size>D){h(`That file is ${Y(w.size)} — the limit is ${Y(D)}.`);return}const j=ut(Q||w.type,xe);if(!j){h("Only PNG, JPEG, WebP, WebM and MP4 files can be attached to a report.");return}const K={blob:w,kind:R,mime:j,size:w.size,previewUrl:URL.createObjectURL(w),status:"uploading",progress:0,storageKey:null,el:document.createElement("div")};K.el.className="thumb",o.push(K),y.appendChild(K.el),h(""),v(),N(K)}async function re(w){c.style.opacity="0",c.style.pointerEvents="none",await new Promise(Q=>requestAnimationFrame(()=>requestAnimationFrame(Q)));try{return await w()}finally{c.style.opacity="",c.style.pointerEvents=""}}(G=f.querySelector('[data-act="shot"]'))==null||G.addEventListener("click",async()=>{try{const w=await re(ht);P(w)}catch(w){(w==null?void 0:w.name)!=="NotAllowedError"&&h(`Screenshot failed: ${w.message}`)}}),(X=f.querySelector('[data-act="file"]'))==null||X.addEventListener("click",()=>L.click()),L==null||L.addEventListener("change",()=>{const w=(a.maxAttachments??5)-o.length;[...L.files].slice(0,Math.max(w,0)).forEach(Q=>{P({blob:Q,mime:Q.type,kind:Q.type.startsWith("video/")?"VIDEO":"SCREENSHOT"})}),L.value=""}),(z=f.querySelector('[data-act="rec"]'))==null||z.addEventListener("click",async()=>{const w=a.maxRecordingMs??12e4;let Q;try{l=await ft({maxMs:w,onTick:R=>{Q&&(Q.querySelector(".time").textContent=te(R))},onAutoStop:()=>{l&&F({keep:!0})}})}catch(R){(R==null?void 0:R.name)!=="NotAllowedError"&&h(`Recording failed: ${R.message}`);return}f.style.display="none",u.hidden=!0,Q=document.createElement("div"),Q.className="recbar",Q.innerHTML=`
|
|
1099
1146
|
<span class="dot"></span>
|
|
1100
1147
|
<span class="time">0:00</span>
|
|
1101
1148
|
<span class="hint">Recording — up to ${te(Math.round(w/1e3))}</span>
|
|
1102
1149
|
<button class="stop" type="button">Stop</button>
|
|
1103
|
-
<button class="ghost" type="button">Discard</button>`,Q.querySelector(".stop").addEventListener("click",()=>
|
|
1150
|
+
<button class="ghost" type="button">Discard</button>`,Q.querySelector(".stop").addEventListener("click",()=>F({keep:!0})),Q.querySelector(".ghost").addEventListener("click",()=>F({keep:!1})),s.appendChild(Q),Q.querySelector(".stop").focus()});async function F({keep:w}){var R;const Q=l;if(Q){if(l=null,(R=s.querySelector(".recbar"))==null||R.remove(),f.style.display="",u.hidden=!1,!w){Q.cancel(),b.focus();return}try{const D=await Q.stop();D.blob.size?P(D):h("That recording came back empty — nothing was captured.")}catch(D){h(`Recording failed: ${D.message}`)}b.focus()}}e.isRecording=()=>!!l,e.stopRecording=F,n.addEventListener("click",async()=>{var R;const w=b.value;if(!w.trim()){T("Add a few words about what went wrong — a short sentence is plenty."),b.focus();return}if(e.holdForReference())return;e.sending=!0,h(""),I();const Q=n.innerHTML;n.innerHTML='<span class="spinner" aria-hidden="true"></span>Sending…';try{const D=await t.report({title:w,description:g.value,priority:i,references:e.answeredReference(),issue:((R=e.pickedIssue())==null?void 0:R.key)||null,attachments:o.filter(j=>j.status==="ready").map(j=>({type:j.kind,storageKey:j.storageKey,mime:j.mime}))});if(D!=null&&D.cancelled){e.sending=!1,n.innerHTML=Q,I();return}x=!0,clearTimeout(M),await m,a.drafts!==!1&&await ne(S,null).catch(()=>{}),e.succeed(D)}catch(D){e.sending=!1,n.innerHTML=Q,h(D.message.replace("[BugCatch] ","")),I(),e.recheckSignIn()}})}const kt=2e4,Se=120,de=200;function Me(e){if(typeof e!="string"||!e.trim()||e.length>400)return null;try{return new RegExp(e.trim(),"gi")}catch{return null}}const Le=e=>String(e).replace(/\s+/g," ").trim().slice(0,Se);function Ee(e,t){const a=e&&e.normalize;if(a==="phone"){const s=t.replace(/\D/g,"");return s.length===10?s:s.length===12&&s.startsWith("91")?s.slice(2):s.length===11&&s.startsWith("0")?s.slice(1):t}return a==="upper"?t.toUpperCase():t}function Te(e){const t=e.length>1&&e[1]!==void 0?e[1]:e[0];return typeof t!="string"||!t.trim()?null:{value:Le(t),start:e.index,end:e.index+e[0].length}}function $t(e,t){return((e.slice(t.start,t.valueStart)+e.slice(t.valueEnd,t.end)).match(/[a-z]/gi)||[]).length}const St=/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}|[A-Za-z0-9][\w-]{5,40}/gi,Qe=/[\w-]/;function Mt(e,t){const a=(e||[]).filter(n=>n&&n.scan!==!1&&n.pattern),s=[],c=[],u=(t||[]).map(n=>typeof n=="string"?n.slice(0,kt):"");u.forEach((n,p)=>{n&&a.forEach((y,L)=>{const o=Me(y.pattern);if(!o)return;let i,l=0;for(o.lastIndex=0;(i=o.exec(n))!==null&&!(++l>de);){if(i[0]===""){o.lastIndex+=1;continue}const r=Te(i);if(!r)continue;const S=i.length>1&&i[1]!==void 0?i[1]:i[0],E=i.index+Math.max(0,i[0].indexOf(S)),x={block:p,order:L,key:y.key,label:y.label,value:Ee(y,r.value),start:r.start,end:r.end,valueStart:E,valueEnd:E+S.length};x.weight=$t(n,x),s.push(x)}})});const f=s.filter(n=>!s.some(p=>p!==n&&p.block===n.block&&p.key!==n.key&&p.valueStart<=n.valueStart&&p.valueEnd>=n.valueEnd&&p.weight>n.weight)),d=new Map;for(const n of f){const p=n.value.toLowerCase();d.has(p)||d.set(p,{value:n.value,keys:new Map});const y=d.get(p);y.keys.has(n.key)||y.keys.set(n.key,{key:n.key,label:n.label,order:n.order})}const h=[],b=[],g=new Map;for(const n of d.values()){const p=[...n.keys.values()].sort((o,i)=>o.order-i.order);if(p.length>1){b.push({value:n.value,kinds:p.map(({key:o,label:i})=>({key:o,label:i}))});continue}const[{key:y,label:L}]=p;g.has(y)||g.set(y,[]),g.get(y).push({key:y,label:L,value:n.value})}for(const n of g.values())if(n.length===1)h.push(n[0]);else for(const p of n)b.push({value:p.value,kinds:[{key:p.key,label:p.label}]});const $=new Set(d.keys());return u.forEach((n,p)=>{if(!n)return;const y=s.filter(l=>l.block===p),L=new RegExp(St.source,"gi");let o,i=0;for(;(o=L.exec(n))!==null&&++i<=de;){const l=o.index,r=l+o[0].length;if(y.some(v=>l<v.end&&r>v.start))continue;const S=n[l-1]||"",E=n[r]||"";if(Qe.test(S)||Qe.test(E)||S==="/"||S==="@"||E==="@"||S==="."||E==="."&&/\w/.test(n[r+1]||"")||!/\d/.test(o[0]))continue;const x=Le(o[0]),m=x.toLowerCase();if($.has(m))continue;const M=(e||[]).filter(v=>v&&qe(v,x)).map(({key:v,label:q})=>({key:v,label:q}));M.length&&($.add(m),c.push({value:x,kinds:M}))}}),{found:h,conflicts:b,loose:c}}function qe(e,t){const a=typeof t=="string"?t.trim():"";if(!a||a.length>Se)return null;const s=Me(e&&(e.valuePattern||e.pattern));if(!s)return null;let c,u=0;for(s.lastIndex=0;(c=s.exec(a))!==null&&!(++u>de);){if(c[0]===""){s.lastIndex+=1;continue}const f=c.index+c[0].length===a.length,d=c.index===0||c.index===1;if(f&&d){const h=Te(c);if(h)return Ee(e,h.value)}}return null}function Lt(e){const{client:t,say:a,titleInput:s,descInput:c,sendBtn:u,refsBox:f}=e;let d={policy:"off",fields:[]},h=!1,b=null,g="",$="",n=[],p="ask",y=!1,L=!1;t.referenceFields().then(T=>{d=T,E()}).catch(()=>{});function o(){return d.policy==="off"||!d.fields.length?{found:[],conflicts:[],loose:[]}:Mt(d.fields,[s.value,c.value])}function i(T=o()){return T.found.length>0&&T.conflicts.length===0}function l(){return!b||!g.trim()?[]:[{key:b,value:g.trim().slice(0,120)}]}const r=document.createElement("p");r.className="ref-found",r.setAttribute("aria-live","polite"),r.hidden=!0,c.closest(".field").after(r);let S;function E(){const T=o();if(i(T)){const I=T.found.slice(0,2).map(H=>`${k(H.label)} <b>${k(m(H.value))}</b>`).join(", ");r.innerHTML=`${O}<span>Found your ${I} — no need to add it again.</span>`,r.hidden=!1,h&&!l().length&&(h=!1,q())}else r.hidden=!0,r.innerHTML=""}const x=()=>{clearTimeout(S),S=setTimeout(E,250)};s.addEventListener("input",x),c.addEventListener("input",x);function m(T){return T.length>20?`${T.slice(0,8)}…${T.slice(-4)}`:T}function M(T){const I=T.trim().toLowerCase();return n.find(H=>H.value.toLowerCase()===I)||null}function v(T){g=T.value,T.kinds.length===1?b=T.kinds[0].key:T.kinds.some(I=>I.key===b)||(b=null),$="",L=!1}function q(){var G,X;if(!h){f.hidden=!0,f.innerHTML="";return}const T=d.fields.find(z=>z.key===b)||null,I=d.policy!=="required",H=M(g),V=H&&H.kinds.length>1?d.fields.filter(z=>H.kinds.some(w=>w.key===z.key)):d.fields,N=n.length>1&&n.every(z=>z.kinds.length===1&&z.kinds[0].key===n[0].kinds[0].key),P={confirm:n.length>1?["Which one is this about?","We found more than one ID in your message. Pick the one this problem is about."]:["Is this the right ID?","This could be more than one kind of ID. Tell us which it is."],suggest:["Is this your ID?","We spotted this in your message. Tell us what it is so we can find your record."],ask:I?["One more thing","So we can find your record — this helps us answer faster."]:["We need one detail","We need one of these to look this up."]}[p];f.hidden=!1;const re=V.length>6;f.innerHTML=`
|
|
1104
1151
|
<div class="ask-head">
|
|
1105
1152
|
<span class="avatar orb" aria-hidden="true"></span>
|
|
1106
1153
|
<div>
|
|
@@ -1108,245 +1155,290 @@ div.done { padding: 44px 26px 44px; text-align: center; animation: bc-fade-in 24
|
|
|
1108
1155
|
<p class="why">${k(P[1])}</p>
|
|
1109
1156
|
</div>
|
|
1110
1157
|
</div>
|
|
1111
|
-
${
|
|
1158
|
+
${n.length>1?`
|
|
1112
1159
|
<div class="chips cands" role="group" aria-label="IDs found in your message">
|
|
1113
|
-
${
|
|
1114
|
-
<button type="button" data-ref-cand="${w}" title="${k(
|
|
1115
|
-
aria-pressed="${!!
|
|
1160
|
+
${n.map((z,w)=>`
|
|
1161
|
+
<button type="button" data-ref-cand="${w}" title="${k(z.value)}"
|
|
1162
|
+
aria-pressed="${!!H&&H===z}">${k(m(z.value))}</button>
|
|
1116
1163
|
`).join("")}
|
|
1117
1164
|
</div>`:""}
|
|
1118
|
-
${
|
|
1165
|
+
${V.length>1&&!re&&!N?`
|
|
1119
1166
|
<div class="chips" role="group" aria-label="Which detail you are giving">
|
|
1120
|
-
${
|
|
1121
|
-
<button type="button" data-ref-kind="${k(
|
|
1167
|
+
${V.map(z=>`
|
|
1168
|
+
<button type="button" data-ref-kind="${k(z.key)}" aria-pressed="${!!T&&z.key===T.key}">${k(z.label)}</button>
|
|
1122
1169
|
`).join("")}
|
|
1123
1170
|
</div>`:""}
|
|
1124
1171
|
<div class="row">
|
|
1125
|
-
${
|
|
1172
|
+
${re?`
|
|
1126
1173
|
<select class="ref-kind" aria-label="Which detail you are giving">
|
|
1127
1174
|
${T?"":'<option value="" selected disabled>What is it?</option>'}
|
|
1128
|
-
${
|
|
1129
|
-
<option value="${k(
|
|
1175
|
+
${V.map(z=>`
|
|
1176
|
+
<option value="${k(z.key)}" ${T&&z.key===T.key?"selected":""}>${k(z.label)}</option>
|
|
1130
1177
|
`).join("")}
|
|
1131
1178
|
</select>`:""}
|
|
1132
|
-
<input class="ref-value${
|
|
1179
|
+
<input class="ref-value${$?" invalid":""}" type="${(T==null?void 0:T.inputMode)==="email"?"email":"text"}"
|
|
1133
1180
|
inputmode="${k((T==null?void 0:T.inputMode)==="numeric"||(T==null?void 0:T.inputMode)==="tel"?"numeric":"text")}"
|
|
1134
|
-
value="${k(
|
|
1181
|
+
value="${k(g)}"
|
|
1135
1182
|
placeholder="${k(T?T.placeholder||T.label:"Your ID")}"
|
|
1136
|
-
aria-label="${k(T?T.label:"Your ID")}" ${
|
|
1183
|
+
aria-label="${k(T?T.label:"Your ID")}" ${$?'aria-invalid="true"':""} />
|
|
1137
1184
|
</div>
|
|
1138
1185
|
${T!=null&&T.hint?`<p class="hint">${k(T.hint)}</p>`:""}
|
|
1139
|
-
${
|
|
1140
|
-
${
|
|
1186
|
+
${$?`<p class="field-err" role="alert">${W}<span>${k($)}</span></p>`:""}
|
|
1187
|
+
${I?`<button type="button" class="link" data-act="ref-skip">${p==="ask"?"I don't have this — send without it":"Not sure — send as it is"}</button>`:""}`,f.querySelectorAll("[data-ref-cand]").forEach(z=>{z.addEventListener("click",()=>{v(n[Number(z.dataset.refCand)]),q()})}),f.querySelectorAll("[data-ref-kind]").forEach(z=>{z.addEventListener("click",()=>{b=z.dataset.refKind,$="",L=!1,q()})});const F=f.querySelector(".ref-value");F.addEventListener("input",()=>{g=F.value,$="",L=!1}),F.addEventListener("keydown",z=>{z.key==="Enter"&&(z.preventDefault(),u.click())}),(G=f.querySelector(".ref-kind"))==null||G.addEventListener("change",z=>{var w;b=z.target.value,$="",q(),(w=f.querySelector(".ref-value"))==null||w.focus()}),(X=f.querySelector('[data-act="ref-skip"]'))==null||X.addEventListener("click",()=>{y=!0,h=!1,b=null,g="",$="",L=!1,q(),a("")}),((!T&&g?f.querySelector("[data-ref-kind], .ref-kind"):null)||F).focus()}function C(T){if(n=T.conflicts.length?T.conflicts:T.loose.slice(0,4),p=T.conflicts.length?"confirm":T.loose.length?"suggest":"ask",h=!0,n.length)if(n.length===1)v(n[0]);else{g="";const[I]=n;b=n.every(V=>V.kinds.length===1&&V.kinds[0].key===I.kinds[0].key)?I.kinds[0].key:null}else b=b||d.fields[0].key;q()}function A(){if(d.policy==="off"||!d.fields.length||l().length)return!1;const T=o();return i(T)||y&&d.policy!=="required"?!1:T}function B(){if(h&&g.trim()&&!b)return $="Pick what this ID is.",q(),!0;const T=A();if(T)return h?q():C(T),a(""),!0;if(b&&g.trim()){const I=d.fields.find(H=>H.key===b);if(!L&&I&&!qe(I,g))return $=`That does not look like a ${I.label.toLowerCase()}. Press Send again to use it anyway.`,L=!0,q(),!0}return!1}e.holdForReference=B,e.answeredReference=l}const Et={info:fe,success:O,warning:Fe,critical:W};function Tt(e,{where:t,onDismiss:a}){const s=document.createElement("div");s.className=`notice tone-${e.tone} at-${t}`,s.setAttribute("role","status");const c=document.createElement("span");c.className="notice-ico",c.setAttribute("aria-hidden","true"),c.innerHTML=Et[e.tone]||fe;const u=document.createElement("div");u.className="notice-text";const f=document.createElement("strong");if(f.textContent=e.title,u.append(f),e.body){const d=document.createElement("p");d.textContent=e.body,u.append(d)}if(e.ctaHref&&e.ctaLabel){const d=document.createElement("a");d.className="notice-cta",d.href=e.ctaHref,d.textContent=e.ctaLabel,/^https?:/i.test(e.ctaHref)&&(d.target="_blank",d.rel="noopener noreferrer"),u.append(d)}if(s.append(c,u),e.dismissible&&a){const d=document.createElement("button");d.type="button",d.className="notice-x",d.setAttribute("aria-label","Dismiss this notice"),d.innerHTML=J,d.addEventListener("click",()=>a(e)),s.append(d)}return s}const Qt=3;function qt(e){const{client:t,cfg:a,notices:s}=e;let c=[];function u(){const d=c.slice(0,Qt);s.replaceChildren(...d.map(h=>Tt(h,{where:"panel",onDismiss:f}))),s.hidden=d.length===0}function f(d){t.dismissAnnouncement(d),c=c.filter(h=>h!==d),u(),e.titleInput.focus()}a.announcements!==!1&&typeof t.announcements=="function"&&t.announcements().then(d=>{e.closed||(c=d,u())}).catch(()=>{})}function Ct(e){const{client:t,cfg:a,titleInput:s,known:c}=e;let u=[],f="",d=null,h=null;function b(){a.knownIssues!==!1&&t.knownIssues().then(y=>{u=y,n()}).catch(()=>{})}let g=null;function $(y){if(a.knownIssues===!1)return;clearTimeout(g),h==null||h.abort();const L=(y||"").trim();if(L.length<3){b();return}g=setTimeout(()=>{h=new AbortController,t.matchKnownIssues(L,{signal:h.signal}).then(o=>{o.length&&(u=o,n())}).catch(()=>{})},250)}function n(){if(!u.length){c.hidden=!0,c.innerHTML="";return}c.hidden=!1,c.innerHTML=`
|
|
1141
1188
|
<p class="known-h">Already reported</p>
|
|
1142
|
-
${
|
|
1143
|
-
<div class="issue ${
|
|
1189
|
+
${u.map(y=>`
|
|
1190
|
+
<div class="issue ${y.joined?"is-joined":""}">
|
|
1144
1191
|
<span class="who">
|
|
1145
|
-
<span class="t">${k(
|
|
1146
|
-
<span class="meta">${k(
|
|
1192
|
+
<span class="t">${k(y.title)}</span>
|
|
1193
|
+
<span class="meta">${k(p(y))}</span>
|
|
1147
1194
|
</span>
|
|
1148
|
-
<button class="join" type="button" data-join="${k(
|
|
1149
|
-
${
|
|
1195
|
+
<button class="join" type="button" data-join="${k(y.id)}"
|
|
1196
|
+
${y.joined?"disabled":""}>${y.joined?"Following":"Me too"}</button>
|
|
1150
1197
|
</div>
|
|
1151
|
-
${
|
|
1198
|
+
${d===y.id?`
|
|
1152
1199
|
<div class="ask">
|
|
1153
1200
|
<input type="email" class="join-email" placeholder="you@example.com"
|
|
1154
1201
|
aria-label="Your email, so we can tell you when this is fixed" />
|
|
1155
|
-
<button class="ghost" type="button" data-join-confirm="${k(
|
|
1202
|
+
<button class="ghost" type="button" data-join-confirm="${k(y.id)}">Follow</button>
|
|
1156
1203
|
</div>`:""}
|
|
1157
1204
|
`).join("")}
|
|
1158
|
-
${
|
|
1205
|
+
${f?`<p class="err">${k(f)}</p>`:""}`}function p(y){const L=y.status==="IN_PROGRESS"?"Being worked on now":"Not fixed yet",o=y.affectedCount===0?"":` · ${y.affectedCount} ${y.affectedCount===1?"person has":"people have"} said this is happening to them`;return`${L} · reported ${Z(y.since)}${o}`}c.addEventListener("click",async y=>{var r,S,E,x,m;const L=y.target.closest("[data-join]"),o=y.target.closest("[data-join-confirm]");if(!L&&!o)return;const i=(o||L).getAttribute(o?"data-join-confirm":"data-join");f="";const l=((S=(r=c.querySelector(".join-email"))==null?void 0:r.value)==null?void 0:S.trim())||((E=t.signedInAs())==null?void 0:E.email)||((x=t.config.user)==null?void 0:x.email);if(!l){d=i,n(),(m=c.querySelector(".join-email"))==null||m.focus();return}try{const M=await t.meToo(i,{email:l});d=null,u=u.map(v=>v.id===i?{...v,joined:!0,affectedCount:M.affectedCount??v.affectedCount}:v),n()}catch(M){f=M.message.replace("[BugCatch] ",""),n()}}),b(),s.addEventListener("input",()=>$(s.value))}function zt(e){const{client:t,cfg:a,titleInput:s,descInput:c,picks:u}=e;let f=[],d=null;function h(){if(!f.length){u.hidden=!0,u.innerHTML="";return}u.hidden=!1,u.innerHTML=`
|
|
1159
1206
|
<p class="picks-h">Get an answer right away</p>
|
|
1160
1207
|
<div class="picks-grid" role="group" aria-label="Common questions">
|
|
1161
|
-
${
|
|
1162
|
-
<button type="button" class="pick" data-pick="${k(
|
|
1163
|
-
${
|
|
1164
|
-
aria-pressed="${(
|
|
1165
|
-
<span class="t">${k(
|
|
1166
|
-
${
|
|
1208
|
+
${f.map((b,g)=>`
|
|
1209
|
+
<button type="button" class="pick" data-pick="${k(b.key)}"
|
|
1210
|
+
${b.hint?`title="${k(b.hint)}" aria-describedby="bc-pick-h${g}"`:""}
|
|
1211
|
+
aria-pressed="${(d==null?void 0:d.key)===b.key}">
|
|
1212
|
+
<span class="t">${k(b.title)}</span>
|
|
1213
|
+
${b.hint?`<span class="h sr-only" id="bc-pick-h${g}">${k(b.hint)}</span>`:""}
|
|
1167
1214
|
</button>`).join("")}
|
|
1168
1215
|
</div>
|
|
1169
|
-
${
|
|
1216
|
+
${d?`<p class="picks-note">${O}<span>Our assistant will check your account and reply here. Add anything else below, then send.</span></p>`:""}`}u.addEventListener("click",b=>{const g=b.target.closest("[data-pick]");if(!g)return;const $=f.find(p=>p.key===g.dataset.pick);if(!$)return;const n=d&&s.value.trim()===d.title;(d==null?void 0:d.key)===$.key?(d=null,n&&(s.value="")):(d=$,(!s.value.trim()||n)&&(s.value=$.title)),s.dispatchEvent(new Event("input",{bubbles:!0})),h(),d&&c.focus()}),a.agentIssues!==!1&&typeof t.agentIssues=="function"&&t.agentIssues().then(b=>{f=b,h()}).catch(()=>{}),e.pickedIssue=()=>d}function At(e){const{client:t,scrim:a,say:s,callBtn:c,close:u}=e;let f=!1;function d(){t.callKind().then(g=>{g&&(f=!0,e.preloadCall(),c.hidden=e.mustSignIn()||e.mustRate())}).catch(()=>{})}d(),c.addEventListener("click",async()=>{e.sending=!0,s(""),e.refreshSendState(),c.disabled=!0,c.innerHTML='<span class="spinner"></span>Ringing…';try{const g=await t.startCall();h(g)}catch(g){e.sending=!1,c.disabled=!1,c.innerHTML=`${ee}Talk to the team`,e.refreshSendState(),g.filed?e.succeed(g.filed,{callFailed:g.reason||"The call could not be started."}):(s(g.message.replace("[BugCatch] ","")),e.recheckSignIn())}});function h(g){const $=a.querySelector(".panel"),n=g!=null&&g.bugId?String(g.bugId).slice(0,8):null;$.innerHTML=`
|
|
1170
1217
|
<div class="call">
|
|
1171
1218
|
<div class="call-head">
|
|
1172
1219
|
<span class="call-dot" aria-hidden="true"></span>
|
|
1173
1220
|
<strong class="call-state">Ringing…</strong>
|
|
1174
1221
|
</div>
|
|
1175
1222
|
<p class="call-note">
|
|
1176
|
-
We're ringing the team now. Someone will pick up if they're free — your report${
|
|
1223
|
+
We're ringing the team now. Someone will pick up if they're free — your report${n?` <code>${k(n)}</code>`:""} is already filed either way, so nothing is lost if nobody answers.
|
|
1177
1224
|
</p>
|
|
1178
1225
|
<div class="foot">
|
|
1179
1226
|
<span class="spacer"></span>
|
|
1180
1227
|
<button class="primary" type="button" data-act="hangup">Cancel</button>
|
|
1181
1228
|
</div>
|
|
1182
|
-
</div>`;const
|
|
1229
|
+
</div>`;const p=$.querySelector(".call-state"),y=$.querySelector(".call-dot"),L={ringing:"Ringing the team…",connecting:"Someone answered — connecting…",connected:"Connected",missed:"Nobody was free",ended:"Call ended",failed:"The call dropped"},o=["ended","failed","missed"],i=t.on("call",({state:l})=>{if(p.textContent=L[l]||l,y.classList.toggle("off",o.includes(l)),o.includes(l)&&($.querySelector('[data-act="hangup"]').textContent="Close",l==="missed")){const r=$.querySelector(".call-note");r&&(r.textContent="Nobody was free to pick up just now. Your report is filed and the team will reply in the chat.")}});$.querySelector('[data-act="hangup"]').addEventListener("click",()=>{i(),t.endCall(),u()})}function b(g,$,n){const p=document.createElement("div");p.className="livecall",p.innerHTML=`
|
|
1183
1230
|
<span class="call-dot" aria-hidden="true"></span>
|
|
1184
1231
|
<span class="who" role="status" aria-live="polite">Calling the team…</span>
|
|
1185
1232
|
<span class="secs" hidden></span>
|
|
1186
|
-
${
|
|
1233
|
+
${n!=null&&n.recorded?'<span class="call-kept">This call is recorded.</span>':""}
|
|
1187
1234
|
<button class="act" type="button" data-act="mute" hidden>Mute</button>
|
|
1188
|
-
<button class="act danger" type="button" data-act="hangup">Cancel</button>`,
|
|
1235
|
+
<button class="act danger" type="button" data-act="hangup">Cancel</button>`,g.insertBefore(p,$);const y=p.querySelector(".who"),L=p.querySelector(".secs"),o=p.querySelector(".call-dot"),i=p.querySelector('[data-act="mute"]'),l=p.querySelector('[data-act="hangup"]');let r=null;const S=()=>{r&&(clearInterval(r),r=null)},E=m=>{S(),o.classList.add("off"),p.classList.add("over"),y.textContent=m,L.hidden=!0,i.hidden=!0,l.textContent="Dismiss",l.classList.remove("danger")},x=t.on("call",({state:m})=>{if(m==="ringing"&&(y.textContent="Calling the team…"),m==="connecting"&&(y.textContent="Someone answered — connecting…"),m==="connected"){y.textContent="You're on a call with the team",i.hidden=!1,L.hidden=!1;const M=Date.now();S(),r=setInterval(()=>{L.textContent=te(Math.floor((Date.now()-M)/1e3))},1e3),L.textContent="0s"}m==="missed"&&E("Nobody was free. Send a message instead and the team will pick it up."),m==="ended"&&E("Call ended."),m==="failed"&&E("The call dropped.")});i.addEventListener("click",()=>{const m=n.setMuted(!n.isMuted());i.textContent=m?"Unmute":"Mute",y.textContent=m?"You're muted":"You're on a call with the team"}),l.addEventListener("click",()=>{x(),S(),t.endCall(),p.remove(),e.refreshThread(e.openReportId())})}e.offerCall=d,e.callOffered=()=>f,e.showLiveCall=b}function Ht(e){var x;const{client:t,say:a,compose:s,sendBtn:c,historyBtn:u,callBtn:f,whoami:d}=e;let h={mode:t.lastLoginMode||"off",signedIn:null},b="idle",g=((x=t.config.user)==null?void 0:x.email)||"",$="",n=!1,p="";const y=()=>h.mode==="required"&&!h.signedIn;function L(){const m=y();s.hidden=m,c.hidden=m,u&&(u.hidden=m),m?f.hidden=!0:e.callOffered()&&!e.mustRate()&&(f.hidden=!1)}function o(){var M;if(h.mode==="off"){d.hidden=!0,d.innerHTML="";return}d.hidden=!1,d.classList.toggle("asking",b!=="idle");const m=p?`<div class="after err">${k(p)}</div>`:"";if(b==="idle"){if(h.signedIn){d.innerHTML=`<span class="who">Signed in as <strong>${k(h.signedIn.email)}</strong></span><button type="button" class="link" data-act="signout">Sign out</button>`;return}const v=(M=t.config.user)==null?void 0:M.email;d.innerHTML=`<span class="who">${h.mode==="required"?"Sign in to report a bug here.":v?`Reporting as <strong>${k(v)}</strong>.`:"Reporting anonymously — sign in and we can tell you what happens next."}</span><button type="button" class="link" data-act="signin">Sign in</button>`;return}if(b==="email"){d.innerHTML=`
|
|
1189
1236
|
<p class="why">Sign in with any email address — we'll send you a code.
|
|
1190
|
-
It's how you hear back about this report${
|
|
1237
|
+
It's how you hear back about this report${h.mode==="required"?", and this project asks for it":""}.</p>
|
|
1191
1238
|
<div class="row">
|
|
1192
|
-
<input type="email" data-fld="email" value="${k(
|
|
1239
|
+
<input type="email" data-fld="email" value="${k(g)}"
|
|
1193
1240
|
placeholder="you@example.com" autocomplete="email" spellcheck="false"
|
|
1194
|
-
aria-label="Your email address" ${
|
|
1195
|
-
<button type="button" class="primary" data-act="code" ${
|
|
1196
|
-
${
|
|
1241
|
+
aria-label="Your email address" ${n?"disabled":""} />
|
|
1242
|
+
<button type="button" class="primary" data-act="code" ${n?"disabled":""}>
|
|
1243
|
+
${n?"Sending…":"Send code"}
|
|
1197
1244
|
</button>
|
|
1198
1245
|
</div>
|
|
1199
|
-
${
|
|
1200
|
-
${
|
|
1201
|
-
<p class="why">We sent a code to <strong>${k(
|
|
1246
|
+
${m}
|
|
1247
|
+
${h.mode==="optional"?'<div class="after"><button type="button" class="link" data-act="skip">Not now</button></div>':""}`;return}d.innerHTML=`
|
|
1248
|
+
<p class="why">We sent a code to <strong>${k(g)}</strong>. It expires in ten minutes.</p>
|
|
1202
1249
|
<div class="row">
|
|
1203
|
-
<input type="text" class="code" data-fld="code" value="${k(
|
|
1250
|
+
<input type="text" class="code" data-fld="code" value="${k($)}"
|
|
1204
1251
|
placeholder="123456" inputmode="numeric" autocomplete="one-time-code"
|
|
1205
|
-
maxlength="8" aria-label="The code we emailed you" ${
|
|
1206
|
-
<button type="button" class="primary" data-act="confirm" ${
|
|
1207
|
-
${
|
|
1252
|
+
maxlength="8" aria-label="The code we emailed you" ${n?"disabled":""} />
|
|
1253
|
+
<button type="button" class="primary" data-act="confirm" ${n?"disabled":""}>
|
|
1254
|
+
${n?"Checking…":"Sign in"}
|
|
1208
1255
|
</button>
|
|
1209
1256
|
</div>
|
|
1210
|
-
${
|
|
1257
|
+
${m}
|
|
1211
1258
|
<div class="after">
|
|
1212
|
-
<button type="button" class="link" data-act="resend" ${
|
|
1213
|
-
<button type="button" class="link" data-act="signin-back" ${
|
|
1214
|
-
</div>`}function
|
|
1259
|
+
<button type="button" class="link" data-act="resend" ${n?"disabled":""}>Send it again</button>
|
|
1260
|
+
<button type="button" class="link" data-act="signin-back" ${n?"disabled":""}>Use another address</button>
|
|
1261
|
+
</div>`}function i({focus:m=!1}={}){var v;if(o(),L(),!m||n)return;const M=d.querySelector("[data-fld]");M&&(M.focus(),(v=M.setSelectionRange)==null||v.call(M,M.value.length,M.value.length))}d.addEventListener("input",m=>{const M=m.target.closest("[data-fld]");M&&(M.dataset.fld==="email"?g=M.value:$=M.value)}),d.addEventListener("keydown",m=>{m.key!=="Enter"||!m.target.closest("[data-fld]")||(m.preventDefault(),b==="email"?l():r())});async function l({resent:m=!1}={}){const M=g.trim();if(!M){p="Enter the address to send the code to.",i({focus:!0});return}n=!0,p="",i();try{await t.signIn(M),g=M,m||($=""),b="code"}catch(v){p=v.message}finally{n=!1,i({focus:!0})}}async function r(){const m=$.trim();if(!m){p="Enter the code we emailed you.",i({focus:!0});return}n=!0,p="",i();try{const M=await t.confirmSignIn(g.trim(),m);h.signedIn=M,b="idle",$="",a(""),e.offerCall()}catch(M){p=M.message}finally{n=!1,i({focus:b!=="idle"})}}d.addEventListener("click",async m=>{const M=m.target.closest("button[data-act]");if(!M)return;const v=M.dataset.act;if(v==="signin"){b="email",p="",i({focus:!0});return}if(v==="skip"){b="idle",p="",i();return}if(v==="signin-back"){b="email",p="",$="",i({focus:!0});return}if(v==="code"){l();return}if(v==="resend"){l({resent:!0});return}if(v==="confirm"){r();return}if(v==="signout"){n=!0,i();try{await t.signOut()}finally{h.signedIn=null,n=!1,b=h.mode==="required"?"email":"idle",i({focus:b!=="idle"})}}});async function S({announce:m=!1}={}){const M=await t.loginState();h={mode:M.mode,signedIn:M.signedIn},t.lastLoginMode=M.mode,y()&&b==="idle"&&(b="email"),h.signedIn&&(b="idle"),m&&M.signedOutReason&&a(M.signedOutReason,"info"),i()}S({announce:!0}).catch(()=>{});function E(){h.mode!=="off"&&S().catch(()=>{})}e.mustSignIn=y,e.recheckSignIn=E}const It=/Did this answer your question\?/i;function Ce(e){const t=e||[];if(!t.length)return"";let a=null,s=null;return t.map(c=>{var g,$,n,p;const u=_(c.at),f=u&&u!==a?`<div class="day-sep" role="separator">${k(ct(c.at))}</div>`:"";if(f&&(a=u,s=null),!c.from)return s=null,f+Dt(c);const d={from:c.from,author:(g=c.reply)==null?void 0:g.author,automated:($=c.reply)==null?void 0:$.automated,body:(n=c.reply)==null?void 0:n.body,at:c.at,attachments:(p=c.reply)==null?void 0:p.attachments},h=Rt(d),b=s&&s.who===h&&Math.abs(new Date(c.at).getTime()-new Date(s.at).getTime())<5*6e4;return s={who:h,at:c.at},f+ze(d,b?"cont":"")}).join("")}function Rt(e){return e.from==="reporter"?"me":e.automated?"assistant":`team:${e.author||""}`}function Dt(e){const t=ve(e.at);return`
|
|
1215
1262
|
<div class="sys k-${k(e.kind)}">
|
|
1216
1263
|
<span class="dot" aria-hidden="true"></span>${k(e.summary||"")}${t?`
|
|
1217
1264
|
<span class="t">· ${k(t)}</span>`:""}
|
|
1218
|
-
</div>`}function ze(e,t=""){const a=e.from==="reporter",
|
|
1265
|
+
</div>`}function ze(e,t=""){const a=e.from==="reporter",s=e.body||"",c=e.attachments||[],u=!a&&!!e.automated,f=s?`<span class="msg-text">${k(s)}</span>`:"",d=c.length?`<div class="att">${c.map(Vt).join("")}</div>`:"";let h="",b="";if(u)h='<span class="msg-who auto">Assistant <span class="tag">AI</span></span>',b='<span class="av bot orb" aria-hidden="true"></span>';else if(!a){const $=e.author||"Support team";h=`<span class="msg-who">${k($)}</span>`,b=`<span class="av" aria-hidden="true">${k(st($))}</span>`}t.includes("cont")&&(h="");const g=u&&/it goes to the same person/i.test(s)?`<div class="quick" role="group" aria-label="Answer">
|
|
1219
1266
|
<button type="button" data-quick="Yes, this is the problem">${O}That's right</button>
|
|
1220
1267
|
<button type="button" data-quick="No, that is not the problem">That's not it</button>
|
|
1221
|
-
</div>`:
|
|
1268
|
+
</div>`:u&&It.test(s)?`<div class="quick" role="group" aria-label="Did this answer your question?">
|
|
1222
1269
|
<button type="button" data-quick="Yes, that answers it">${O}Yes, that answers it</button>
|
|
1223
1270
|
<button type="button" data-quick="No, I still need help">No, I still need help</button>
|
|
1224
1271
|
</div>`:"";return`
|
|
1225
|
-
<div class="msg-row ${a?"mine":"theirs"} ${
|
|
1226
|
-
${
|
|
1227
|
-
${
|
|
1228
|
-
<div class="bubble ${
|
|
1229
|
-
${
|
|
1230
|
-
<span class="msg-when">${k(
|
|
1231
|
-
</div>`}function
|
|
1272
|
+
<div class="msg-row ${a?"mine":"theirs"} ${u?"auto":""} ${t}">
|
|
1273
|
+
${b}
|
|
1274
|
+
${h}
|
|
1275
|
+
<div class="bubble ${s?"":"silent"}">${f}${d}</div>
|
|
1276
|
+
${g}
|
|
1277
|
+
<span class="msg-when">${k(ve(e.at)||Z(e.at))}</span>
|
|
1278
|
+
</div>`}function jt(){return`
|
|
1232
1279
|
<div class="typing-row">
|
|
1233
1280
|
<span class="av bot orb" aria-hidden="true"></span>
|
|
1234
1281
|
<span class="msg-who auto">Assistant <span class="tag">AI</span></span>
|
|
1235
1282
|
<div class="bubble typing" role="img" aria-label="The assistant is working on it"><i></i><i></i><i></i></div>
|
|
1236
|
-
</div>`}function
|
|
1283
|
+
</div>`}function Vt(e){const t=k(e.name||"attachment");if(!e.url)return`<span class="file"><span class="nm">${t}</span></span>`;const a=k(e.url);return e.type==="SCREENSHOT"?`<a href="${a}" target="_blank" rel="noopener noreferrer"><img src="${a}" alt="${t}" loading="lazy"></a>`:e.type==="AUDIO"?`<audio controls preload="metadata" src="${a}"></audio>`:e.type==="VIDEO"?`<video controls preload="metadata" src="${a}"></video>`:`
|
|
1237
1284
|
<a class="file" href="${a}" target="_blank" rel="noopener noreferrer" download>
|
|
1238
1285
|
<span class="nm">${t}</span>
|
|
1239
|
-
${e.size?`<span class="sz">${k(
|
|
1240
|
-
</a>`}function
|
|
1286
|
+
${e.size?`<span class="sz">${k(Y(e.size))}</span>`:""}
|
|
1287
|
+
</a>`}function Bt(e,t,a,s){var E;const{client:c,cfg:u}=e,f=document.createElement("div");f.className="composer",f.innerHTML=`
|
|
1241
1288
|
<div class="staged" hidden></div>
|
|
1242
1289
|
<div class="row">
|
|
1243
1290
|
<div class="tools">
|
|
1244
|
-
${
|
|
1245
|
-
<button class="tool" type="button" data-act="attach" title="Attach a file" aria-label="Attach a file">${
|
|
1246
|
-
<button class="tool" type="button" data-act="voice" title="Record a voice note" aria-label="Record a voice note">${
|
|
1291
|
+
${u.attachments===!1?"":`
|
|
1292
|
+
<button class="tool" type="button" data-act="attach" title="Attach a file" aria-label="Attach a file">${be}</button>
|
|
1293
|
+
<button class="tool" type="button" data-act="voice" title="Record a voice note" aria-label="Record a voice note">${ge}</button>`}
|
|
1247
1294
|
<button class="tool" type="button" data-act="livecall" title="Call the team" aria-label="Call the team" hidden>${ee}</button>
|
|
1248
1295
|
</div>
|
|
1249
1296
|
<textarea rows="1" placeholder="Write a reply…" aria-label="Write a reply"></textarea>
|
|
1250
|
-
<button class="send" type="button" data-act="send" title="Send" aria-label="Send" disabled>${
|
|
1297
|
+
<button class="send" type="button" data-act="send" title="Send" aria-label="Send" disabled>${ie}</button>
|
|
1251
1298
|
</div>
|
|
1252
1299
|
<div class="note" hidden></div>
|
|
1253
|
-
<input type="file" hidden multiple accept="${we.join(",")}">`,t.appendChild(
|
|
1254
|
-
<span class="chip ${
|
|
1255
|
-
<span class="nm">${k(
|
|
1256
|
-
<span class="sz">${
|
|
1257
|
-
<button type="button" data-drop="${
|
|
1258
|
-
</span>`).join("");for(const
|
|
1259
|
-
<p class="fr-q">${k(
|
|
1260
|
-
<div class="stars" role="group" aria-label="Rate how this was handled, 1 to 5">${[1,2,3,4,5].map(
|
|
1261
|
-
<button type="button" data-score="${
|
|
1300
|
+
<input type="file" hidden multiple accept="${we.join(",")}">`,t.appendChild(f);const d=f.querySelector(".staged"),h=f.querySelector("textarea"),b=f.querySelector('[data-act="send"]'),g=f.querySelector('[data-act="voice"]'),$=f.querySelector('[data-act="livecall"]'),n=f.querySelector("input[type=file]"),p=f.querySelector(".note"),y=[];let L=null,o=!1;function i(x,m=""){p.hidden=!x,p.className=`note ${m}`,p.textContent=x||""}function l(){const x=y.filter(m=>m.storageKey);b.disabled=o||!h.value.trim()&&!x.length,d.hidden=!y.length,d.innerHTML=y.map((m,M)=>`
|
|
1301
|
+
<span class="chip ${m.storageKey?"":"uploading"}">
|
|
1302
|
+
<span class="nm">${k(m.name)}</span>
|
|
1303
|
+
<span class="sz">${m.storageKey?Y(m.size):"sending…"}</span>
|
|
1304
|
+
<button type="button" data-drop="${M}" aria-label="Remove ${k(m.name)}">${J}</button>
|
|
1305
|
+
</span>`).join("");for(const m of d.querySelectorAll("[data-drop]"))m.addEventListener("click",()=>{y.splice(Number(m.dataset.drop),1),l()})}async function r(x,m,M){const v={name:M,size:x.size,storageKey:null};y.push(v),l();try{const{storageKey:q,mime:C}=await c.uploadAttachment(x,m);v.storageKey=q,v.mime=C}catch(q){y.splice(y.indexOf(v),1),i(q.message||"That file could not be sent.","err")}l()}h.addEventListener("input",()=>{h.style.height="auto",h.style.height=`${Math.min(h.scrollHeight,120)}px`,l()}),h.addEventListener("keydown",x=>{x.key==="Enter"&&!x.shiftKey&&!x.isComposing&&(x.preventDefault(),S())}),(E=f.querySelector('[data-act="attach"]'))==null||E.addEventListener("click",()=>n.click()),n.addEventListener("change",()=>{i("");for(const x of n.files){if(x.size>c.config.maxAttachmentBytes){i(`${x.name} is larger than ${Y(c.config.maxAttachmentBytes)}.`,"err");continue}r(x,x.type,x.name)}n.value=""}),g&&!lt()&&(g.disabled=!0,g.title="This browser cannot record audio"),g==null||g.addEventListener("click",async()=>{if(L){const x=L;L=null,g.classList.remove("recording"),g.innerHTML=ge,i("");const{blob:m,mime:M}=await x.stop();m.size&&r(m,M,"Voice note");return}try{i(""),L=await bt({maxMs:c.config.maxRecordingMs,onTick:x=>i(`Recording — ${te(x)}. Tap the mic to stop.`),onAutoStop:()=>g.click()}),g.classList.add("recording"),g.innerHTML=Ke}catch{L=null,i("The microphone is not available — check the browser permission.","err")}}),c.canCallTeam(s).then(x=>{x&&($.hidden=!1,e.preloadCall())}).catch(()=>{}),$.addEventListener("click",async()=>{$.disabled=!0,i("");try{const x=await c.startLiveCall(s);e.showLiveCall(t,a,x)}catch(x){i(x.message.replace("[BugCatch] ",""),"err")}finally{$.disabled=!1}}),b.addEventListener("click",S),a.addEventListener("click",x=>{var M,v;const m=(v=(M=x.target).closest)==null?void 0:v.call(M,"[data-quick]");!m||o||(h.value=m.dataset.quick,S())});async function S(){var M;const x=h.value.trim(),m=y.filter(v=>v.storageKey);if(!(o||!x&&!m.length)){o=!0,l(),i(""),a.insertAdjacentHTML("beforeend",ze({from:"reporter",body:x,at:new Date().toISOString(),attachments:m.map(v=>({type:"FILE",name:v.name,size:v.size}))},"pending")),U(a,{smooth:!0});try{await c.replyToReport(s,{body:x,attachments:m.map(v=>({storageKey:v.storageKey,mime:v.mime,name:v.name,size:v.size}))}),h.value="",h.style.height="auto",y.length=0,await e.refreshThread(s)}catch(v){(M=a.querySelector(".msg-row.pending"))==null||M.classList.replace("pending","failed"),i(v.message||"That could not be sent — try again.","err")}finally{o=!1,l()}}}l()}function Ae(e){return JSON.stringify(e?[e.score,e.current,e.comment||null]:null)}function pe(e,{client:t,report:a,rating:s,justRated:c=!1,question:u=null,onRated:f=null,onError:d=null}){var o;e.dataset.key=Ae(s);const h=s!=null&&s.current?s.score:0,b=s?s.current?c?"Thanks — the team will see that.":`You rated this ${s.score} out of 5.`:`You rated an earlier fix ${s.score} out of 5. How did this one go?`:u||"How did we do?",g=c&&(s==null?void 0:s.current)&&!s.comment;e.innerHTML=`
|
|
1306
|
+
<p class="fr-q">${k(b)}</p>
|
|
1307
|
+
<div class="stars" role="group" aria-label="Rate how this was handled, 1 to 5">${[1,2,3,4,5].map(i=>`
|
|
1308
|
+
<button type="button" data-score="${i}" aria-pressed="${i===h}" aria-label="${i} out of 5${i===1?", poor":i===5?", great":""}" class="${i<=h?"on":""}">${me}</button>`).join("")}
|
|
1262
1309
|
</div>
|
|
1263
|
-
${
|
|
1264
|
-
${
|
|
1310
|
+
${s!=null&&s.current&&s.comment?`<p class="fr-said">“${k(s.comment)}”</p>`:""}
|
|
1311
|
+
${g?`
|
|
1265
1312
|
<div class="fr-note">
|
|
1266
|
-
<textarea maxlength="2000" aria-label="Add a note to your rating" placeholder="${
|
|
1313
|
+
<textarea maxlength="2000" aria-label="Add a note to your rating" placeholder="${s.score<=2?"What went wrong? (optional)":"Anything to add? (optional)"}"></textarea>
|
|
1267
1314
|
<button type="button" data-act="rating-note">Add note</button>
|
|
1268
1315
|
</div>`:""}
|
|
1269
|
-
${
|
|
1270
|
-
<p class="feedback-status" role="status"></p>`;const
|
|
1316
|
+
${s?"":'<p class="fr-hint">1 is poor, 5 is great.</p>'}
|
|
1317
|
+
<p class="feedback-status" role="status"></p>`;const $=[...e.querySelectorAll("[data-score]")],n=i=>$.forEach(l=>l.classList.toggle("on",Number(l.dataset.score)<=i)),p=i=>e.querySelectorAll("button, textarea").forEach(l=>{l.disabled=i}),y=e.querySelector(".feedback-status");async function L(i,l){var r;p(!0),y.textContent="";try{const S=await t.rate(a.id,{score:i,comment:l});pe(e,{client:t,report:a,rating:S,justRated:!0,question:u,onRated:f,onError:d}),(r=e.querySelector(".fr-note textarea"))==null||r.focus(),f==null||f(S)}catch(S){y.textContent=S.message,p(!1),n(h),d==null||d(S)}}for(const i of $){const l=Number(i.dataset.score);i.addEventListener("mouseenter",()=>n(l)),i.addEventListener("focus",()=>n(l)),i.addEventListener("blur",()=>n(h)),i.addEventListener("click",()=>L(l))}e.querySelector(".stars").addEventListener("mouseleave",()=>n(h)),(o=e.querySelector('[data-act="rating-note"]'))==null||o.addEventListener("click",()=>{var l;const i=e.querySelector(".fr-note textarea").value.trim();if(!i){(l=e.querySelector(".fr-note"))==null||l.remove();return}L(s.score,i)})}const ue=new WeakMap;function Ot(e){return e.rating?` · <span class="rated" aria-label="You rated this ${Number(e.rating)} out of 5">${me}${Number(e.rating)}</span>`:e.ratingAsked?' · <span class="rate-ask">Rate it</span>':""}function Nt(e){var L;const{client:t,scrim:a,close:s}=e;let c=null;function u(o,{callFailed:i=null}={}){if(o!=null&&o.id&&!i){h(o.id,{fresh:!0}).then(l=>{l||f(o,{callFailed:i})});return}f(o,{callFailed:i})}function f(o,{callFailed:i=null}={}){var E;const l=o!=null&&o.id?String(o.id).slice(0,8):null,r=(E=o==null?void 0:o.estimate)!=null&&E.label?String(o.estimate.label):null,S=i?`<p class="eta">${k(i)} Your report is filed, and the team will reply in the chat.</p>`:"";a.querySelector(".panel").innerHTML=`
|
|
1271
1318
|
<div class="done">
|
|
1272
1319
|
<div class="tick">${O}</div>
|
|
1273
1320
|
<h3>Thanks — that's on its way.</h3>
|
|
1274
1321
|
<p>${l?`Filed as <code>${k(l)}</code>.`:"The team has what they need to reproduce it."}</p>
|
|
1275
|
-
${
|
|
1276
|
-
${
|
|
1277
|
-
</div>`,setTimeout(
|
|
1278
|
-
${
|
|
1279
|
-
<div class="history" aria-busy="true">${
|
|
1280
|
-
<button class="row" type="button" data-report="${k(
|
|
1281
|
-
<span class="row-ico" aria-hidden="true">${
|
|
1322
|
+
${S}
|
|
1323
|
+
${r?`<p class="eta">Reports like this usually take <strong>${k(r)}</strong>. We'll let you know when it moves.</p>`:""}
|
|
1324
|
+
</div>`,setTimeout(s,S?6e3:r?4e3:2e3)}async function d(){const o=a.querySelector(".panel");clearTimeout(b),c=null,o.classList.remove("is-chat"),o.innerHTML=`
|
|
1325
|
+
${se({title:"Your reports",sub:"Where each one has got to.",theme:e.themeLabel()})}
|
|
1326
|
+
<div class="history" aria-busy="true">${rt(3)}</div>`,o.querySelector('[data-act="close"]').addEventListener("click",s);let i=[];try{({reports:i}=await t.myReports())}catch{const r=o.querySelector(".history");r&&(r.innerHTML=ce("Couldn't load your reports just now.",W));return}const l=o.querySelector(".history");if(l){l.removeAttribute("aria-busy"),l.innerHTML=i.length?i.map((r,S)=>`
|
|
1327
|
+
<button class="row" type="button" data-report="${k(r.id)}" style="animation-delay:${Math.min(S,8)*30}ms">
|
|
1328
|
+
<span class="row-ico" aria-hidden="true">${Ve}</span>
|
|
1282
1329
|
<span class="who">
|
|
1283
|
-
<span class="ttl">${k(
|
|
1284
|
-
<span class="sub">${k(
|
|
1330
|
+
<span class="ttl">${k(r.title)}</span>
|
|
1331
|
+
<span class="sub">${k(r.reference)} · ${k(Z(r.createdAt))}${Ot(r)}</span>
|
|
1285
1332
|
</span>
|
|
1286
|
-
<span class="pill ${k(String(
|
|
1287
|
-
<span class="chev" aria-hidden="true">${
|
|
1288
|
-
</button>`).join(""):
|
|
1289
|
-
${
|
|
1290
|
-
<div class="history chatting" aria-busy="true"><div class="thread">${
|
|
1333
|
+
<span class="pill ${k(String(r.status).toLowerCase())}">${k(le(r.status))}</span>
|
|
1334
|
+
<span class="chev" aria-hidden="true">${Ze}</span>
|
|
1335
|
+
</button>`).join(""):ce("You haven't reported anything yet.",Ge);for(const r of l.querySelectorAll("[data-report]"))r.addEventListener("click",()=>h(r.dataset.report))}}async function h(o,{fresh:i=!1}={}){var m;const l=a.querySelector(".panel");clearTimeout(b),l.classList.add("is-chat"),l.innerHTML=`
|
|
1336
|
+
${se({back:!0,title:i?"Looking into it":"Your report",sub:i?"It may ask you a question here.":"Updates, and a way to reply.",theme:e.themeLabel()})}
|
|
1337
|
+
<div class="history chatting" aria-busy="true"><div class="thread">${it()}</div></div>`,l.querySelector('[data-act="close"]').addEventListener("click",s),l.querySelector('[data-act="back"]').addEventListener("click",d);let r=null;try{r=await t.myReport(o)}catch{r=null}const S=l.querySelector(".history");if(!S||!l.querySelector('[data-act="back"]'))return!1;if(!r)return i?(l.classList.remove("is-chat"),!1):(S.removeAttribute("aria-busy"),S.innerHTML=ce("Couldn't load that report just now.",W),!1);c=o,t.markReportRead(o);const E=Ce(r.timeline);S.classList.add("chatting"),S.removeAttribute("aria-busy"),S.innerHTML=`
|
|
1291
1338
|
<div class="report-head">
|
|
1292
|
-
<span class="ttl">${k(
|
|
1293
|
-
<span class="sub">${k(
|
|
1294
|
-
<span class="pill ${k(String(
|
|
1295
|
-
${(
|
|
1339
|
+
<span class="ttl">${k(r.title)}</span>
|
|
1340
|
+
<span class="sub">${k(r.reference)} · ${k(r.project||"")}</span>
|
|
1341
|
+
<span class="pill ${k(String(r.status).toLowerCase())}">${k(le(r.status))}</span>
|
|
1342
|
+
${(m=r.estimate)!=null&&m.label?`<span class="eta-line">Usually takes ${k(String(r.estimate.label))}</span>`:""}
|
|
1296
1343
|
</div>
|
|
1297
|
-
<div class="thread" role="log" aria-live="polite" aria-label="Conversation">${
|
|
1298
|
-
<div class="as-body${
|
|
1344
|
+
<div class="thread" role="log" aria-live="polite" aria-label="Conversation">${E}</div>`;const x=S.querySelector(".thread");return ue.set(x,E),U(x),$(S,r),n(S,r),r.canReply&&Bt(e,S,x,o),g(S,r,o),U(x),!0}let b=null;function g(o,i,l){var B,T,I;clearTimeout(b);const r=i.assistant,S=o.querySelector(".thread");let E=o.querySelector(".assistant");if(!r){E==null||E.remove(),(B=S==null?void 0:S.querySelector(".typing-row"))==null||B.remove();return}const x=(E==null?void 0:E.dataset.phase)||null;E||(E=document.createElement("div"),E.setAttribute("role","status"),E.setAttribute("aria-live","polite"),(T=o.querySelector(".report-head"))==null||T.after(E)),E.className=`assistant ${k(r.phase)}`,E.dataset.phase=r.phase;const m=r.steps||[],M=m.filter(H=>H.state==="done").length,v=m.some(H=>H.state==="active")?.5:0,q=m.length?Math.round((M+v)/m.length*100):0,C=`
|
|
1345
|
+
<div class="as-body${x&&x!==r.phase?" entering":""}">
|
|
1299
1346
|
<div class="as-top">
|
|
1300
|
-
<span class="as-orb${
|
|
1347
|
+
<span class="as-orb${r.phase==="calling"||r.phase==="resolved"?"":" orb"}" aria-hidden="true">${r.phase==="calling"?ee:r.phase==="resolved"?O:""}</span>
|
|
1301
1348
|
<div class="as-text">
|
|
1302
|
-
<div class="as-title">${k(
|
|
1303
|
-
<div class="as-detail">${k(
|
|
1349
|
+
<div class="as-title">${k(r.title)}</div>
|
|
1350
|
+
<div class="as-detail">${k(r.detail)}</div>
|
|
1304
1351
|
</div>
|
|
1305
1352
|
</div>
|
|
1306
1353
|
</div>
|
|
1307
|
-
${
|
|
1308
|
-
<div class="as-progress" role="progressbar" aria-label="Progress" aria-valuemin="0" aria-valuemax="100" aria-valuenow="${
|
|
1309
|
-
<ol class="as-steps">${
|
|
1354
|
+
${m.length?`
|
|
1355
|
+
<div class="as-progress" role="progressbar" aria-label="Progress" aria-valuemin="0" aria-valuemax="100" aria-valuenow="${q}"><i style="width:${q}%"></i></div>
|
|
1356
|
+
<ol class="as-steps">${m.map(H=>`<li class="${k(H.state)}"${H.state==="active"?' aria-current="step"':""}><span class="dot"></span><span class="lbl">${k(H.label)}</span></li>`).join("")}</ol>`:""}`,A=JSON.stringify([r.phase,r.title,r.detail,m]);if(E.dataset.key!==A){const H=E.querySelector(".as-progress i"),V=H==null?void 0:H.style.width;E.innerHTML=C,E.dataset.key=A;const N=E.querySelector(".as-progress i");N&&V&&(N.style.width=V,requestAnimationFrame(()=>{N.style.width=`${q}%`}))}if(S){const H=ye(S),V=S.querySelector(".typing-row");r.phase!=="analyzing"?V==null||V.remove():(!V||V!==S.lastElementChild)&&(V==null||V.remove(),S.insertAdjacentHTML("beforeend",jt()),H&&U(S))}r.phase==="analyzing"?b=setTimeout(()=>p(l),3e3):r.phase==="calling"?b=setTimeout(()=>p(l),1e4):r.phase==="needs_info"&&x!=="needs_info"&&((I=o.querySelector(".composer textarea"))==null||I.focus())}function $(o,i){var r,S;if((r=o.querySelector(".fix-verification"))==null||r.remove(),!i.resolvedAt||!["RESOLVED","CLOSED"].includes(i.status))return;const l=document.createElement("div");l.className="fix-verification",i.verification?l.textContent=i.verification==="CONFIRMED"?"You confirmed that this fix works.":"Your feedback was recorded.":(l.innerHTML='<p>Does the fix work for you?</p><textarea maxlength="4000" aria-label="Fix feedback" placeholder="What happens when you try again? (optional)"></textarea><button type="button" data-result="CONFIRMED">It works now</button> <button type="button" data-result="STILL_HAPPENING">Still happening</button><p class="feedback-status" role="status"></p>',l.querySelectorAll("[data-result]").forEach(E=>{E.onclick=async()=>{l.querySelectorAll("button").forEach(x=>{x.disabled=!0});try{await t.verifyFix(i.id,{result:E.dataset.result,resolvedAt:i.resolvedAt,note:l.querySelector("textarea").value}),await h(i.id)}catch(x){l.querySelector(".feedback-status").textContent=x.message,l.querySelectorAll("button").forEach(m=>{m.disabled=!1})}}})),(S=o.querySelector(".report-head"))==null||S.after(l)}function n(o,i){var S;let l=o.querySelector(".fix-rating");if(!["RESOLVED","CLOSED"].includes(i.status)||!i.ratingAsked){l==null||l.remove();return}l&&l.dataset.key===Ae(i.rating)||(l||(l=document.createElement("div"),l.className="fix-rating",(S=o.querySelector(".fix-verification")||o.querySelector(".report-head"))==null||S.after(l)),pe(l,{client:t,report:i,rating:i.rating||null}))}async function p(o){const i=a.querySelector(".history.chatting"),l=i==null?void 0:i.querySelector(".thread");if(!l||c!==o)return;let r=null;try{r=await t.myReport(o)}catch{}if(e.closed||!r||c!==o)return;$(i,r),n(i,r);const S=ye(l),E=Ce(r.timeline);ue.get(l)!==E&&(l.innerHTML=E,ue.set(l,E)),g(i,r,o),S&&U(l);const x=i.querySelector(".report-head .pill");x&&(x.className=`pill ${String(r.status).toLowerCase()}`,x.textContent=le(r.status))}const y=t.on("update",o=>{!c||(o==null?void 0:o.bugId)!==c||(t.markReportRead(c),p(c))});e.onDestroy(()=>{y(),clearTimeout(b)}),(L=a.querySelector('[data-act="history"]'))==null||L.addEventListener("click",d),e.succeed=u,e.refreshThread=p,e.openReportId=()=>c}const He="bugcatch.rateLater",Ft=50;function Ie(){try{const e=JSON.parse(window.localStorage.getItem(He)||"[]");return Array.isArray(e)?e:[]}catch{return[]}}function Wt(e){try{const t=Ie().filter(a=>a!==e);t.push(e),window.localStorage.setItem(He,JSON.stringify(t.slice(-Ft)))}catch{}}function Pt(e,t=Ie()){const a=new Set(t),s=(e||[]).filter(u=>u.ratingDue==="require"||u.ratingDue==="ask"&&!a.has(u.id));if(!s.length)return null;const c=u=>new Date(u.resolvedAt||u.updatedAt||0).getTime()||0;return s.reduce((u,f)=>c(f)>c(u)?f:u)}function Kt(e){const{client:t,rateDue:a,compose:s,picks:c,known:u,callBtn:f,titleInput:d,scrim:h}=e;let b=!1;e.mustRate=()=>b;function g(y){b=y;for(const L of[s,c,u])L.classList.toggle("held",y),L.inert=y;y?f.hidden=!0:e.callOffered()&&!e.mustSignIn()&&(f.hidden=!1),e.refreshSendState()}function $(){b&&g(!1)}function n(){a.hidden=!0,a.replaceChildren(),$(),d.focus()}function p(y){var l;const L=y.ratingDue==="require",o=y.resolvedAt?Z(y.resolvedAt):"",i=y.status==="CLOSED"?"closed":"fixed";if(a.hidden=!1,a.classList.toggle("is-required",L),a.innerHTML=`
|
|
1310
1357
|
<div class="rd-head">
|
|
1311
|
-
<span class="rd-eyebrow">${
|
|
1312
|
-
${
|
|
1358
|
+
<span class="rd-eyebrow">${L?"Before you report something new":`Your report was ${i}`}</span>
|
|
1359
|
+
${L?"":'<button type="button" class="link rd-later" data-act="rate-later">Not now</button>'}
|
|
1313
1360
|
</div>
|
|
1314
1361
|
<p class="rd-report">
|
|
1315
1362
|
<span class="rd-ico" aria-hidden="true">${O}</span>
|
|
1316
|
-
<span class="rd-ttl">${k(
|
|
1317
|
-
<span class="rd-sub">${k(
|
|
1363
|
+
<span class="rd-ttl">${k(y.title)}</span>
|
|
1364
|
+
<span class="rd-sub">${k(y.reference)}${o?` · ${i} ${k(o)}`:""}</span>
|
|
1318
1365
|
</p>
|
|
1319
|
-
<div class="rd-stars"></div>`,(l=a.querySelector('[data-act="rate-later"]'))==null||l.addEventListener("click",()=>{
|
|
1320
|
-
|
|
1321
|
-
|
|
1366
|
+
<div class="rd-stars"></div>`,(l=a.querySelector('[data-act="rate-later"]'))==null||l.addEventListener("click",()=>{Wt(y.id),n()}),pe(a.querySelector(".rd-stars"),{client:t,report:y,rating:null,question:L?"How did we handle it? Rate it to send a new one.":"How did we do?",onRated:()=>{var r;a.querySelector(".rd-eyebrow").textContent=`Your report was ${i}`,(r=a.querySelector('[data-act="skip"]'))==null||r.remove(),a.classList.remove("is-required"),$()},onError:()=>{if(!b||a.querySelector('[data-act="skip"]'))return;const r=document.createElement("button");r.type="button",r.className="link rd-later",r.dataset.act="skip",r.textContent="Skip for now",r.addEventListener("click",n),a.querySelector(".rd-head").append(r)}}),L){g(!0);const r=h.getRootNode().activeElement;(!r||!a.contains(r))&&a.focus()}}t.hasReports()&&t.myReports().then(({reports:y})=>{if(e.closed)return;const L=Pt(y);L&&p(L)}).catch(()=>{})}const Yt=["idea","praise","confusing","other"],_t=4e3,Re={idea:{label:"Idea",icon:et},praise:{label:"Praise",icon:tt},confusing:{label:"Confusing",icon:at},other:{label:"Other",icon:nt}},De=[{score:1,word:"Terrible",mouth:"M7.8 17.2c1.1-2 2.5-2.9 4.2-2.9s3.1.9 4.2 2.9M8 8l2.4 1.2M16 8l-2.4 1.2"},{score:2,word:"Not great",mouth:"M8.6 16c1-.8 2.1-1.2 3.4-1.2s2.4.4 3.4 1.2"},{score:3,word:"Okay",mouth:"M8.8 15.2h6.4"},{score:4,word:"Good",mouth:"M8.6 14.4c1 .9 2.1 1.4 3.4 1.4s2.4-.5 3.4-1.4"},{score:5,word:"Great",mouth:"M7.8 13.2h8.4a4.2 4.2 0 0 1-8.4 0z"}];function Ut(e){return`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9.2"/><path d="M9 9.9h.01M15 9.9h.01" stroke-width="2.6"/><path d="${e}"/></svg>`}function Zt(){return`
|
|
1367
|
+
<div class="feedback fb-only">
|
|
1368
|
+
<div class="field">
|
|
1369
|
+
<label for="bc-fb-msg">What's on your mind?</label>
|
|
1370
|
+
<textarea id="bc-fb-msg" maxlength="${_t}" aria-describedby="bc-fb-err"
|
|
1371
|
+
placeholder="An idea, something you like, or something that confused you."></textarea>
|
|
1372
|
+
<p class="field-err" id="bc-fb-err" hidden></p>
|
|
1373
|
+
</div>
|
|
1374
|
+
<div class="field">
|
|
1375
|
+
<label id="bc-fb-kind-l">What kind is it? <span class="opt">(optional)</span></label>
|
|
1376
|
+
<div class="kinds" role="group" aria-labelledby="bc-fb-kind-l">
|
|
1377
|
+
${Yt.map(e=>`
|
|
1378
|
+
<button class="tool" type="button" data-kind="${e}" aria-pressed="false">${Re[e].icon}${Re[e].label}</button>
|
|
1379
|
+
`).join("")}
|
|
1380
|
+
</div>
|
|
1381
|
+
</div>
|
|
1382
|
+
<div class="field">
|
|
1383
|
+
<div class="field-head">
|
|
1384
|
+
<label id="bc-fb-score-l">How's your experience so far? <span class="opt">(optional)</span></label>
|
|
1385
|
+
<span class="count face-word" aria-hidden="true"></span>
|
|
1386
|
+
</div>
|
|
1387
|
+
<div class="faces" role="group" aria-labelledby="bc-fb-score-l">
|
|
1388
|
+
${De.map(e=>`
|
|
1389
|
+
<button class="face" type="button" data-score="${e.score}" aria-pressed="false"
|
|
1390
|
+
aria-label="${e.word}" title="${e.word}">${Ut(e.mouth)}</button>
|
|
1391
|
+
`).join("")}
|
|
1392
|
+
</div>
|
|
1393
|
+
</div>
|
|
1394
|
+
<!-- Who it is from: an address to write back to when the page knows
|
|
1395
|
+
none, and a line saying which one when it does. -->
|
|
1396
|
+
<div class="field fb-who"></div>
|
|
1397
|
+
</div>`}function Gt(e){var v,q;const{client:t,cfg:a,scrim:s,$:c,say:u,close:f}=e,d=c(".feedback"),h=c("#bc-fb-msg"),b=c("#bc-fb-err"),g=c('[data-act="send-feedback"]'),$=c(".face-word");let n=null,p=null,y=!1,L=!1;const o=c(".fb-who"),i=((v=t.signedInAs())==null?void 0:v.email)||((q=a.user)==null?void 0:q.email)||null;i?o.innerHTML=`<p class="fb-as">Sent as <strong>${k(i)}</strong></p>`:o.innerHTML=`
|
|
1398
|
+
<label for="bc-fb-email">Your email <span class="opt">(optional — only if you'd like a reply)</span></label>
|
|
1399
|
+
<input id="bc-fb-email" type="email" autocomplete="email" placeholder="you@example.com" />`;const l=c("#bc-fb-email"),r=`bugcatch.feedbackDraft:${a.projectId||""}`,S=a.drafts!==!1;if(S)try{h.value=localStorage.getItem(r)||""}catch{}let E;function x(){if(clearTimeout(E),!!S)try{h.value.trim()?localStorage.setItem(r,h.value):localStorage.removeItem(r)}catch{}}h.addEventListener("input",()=>{h.value.trim()&&m(""),clearTimeout(E),E=setTimeout(x,250)}),e.onDestroy(()=>{L||x()}),d.querySelectorAll("[data-kind]").forEach(C=>{C.addEventListener("click",()=>{n=n===C.dataset.kind?null:C.dataset.kind,d.querySelectorAll("[data-kind]").forEach(A=>A.setAttribute("aria-pressed",String(A.dataset.kind===n)))})}),d.querySelectorAll("[data-score]").forEach(C=>{C.addEventListener("click",()=>{const A=Number(C.dataset.score);p=p===A?null:A,d.querySelectorAll("[data-score]").forEach(B=>B.setAttribute("aria-pressed",String(Number(B.dataset.score)===p))),$.textContent=p?De[p-1].word:""})});function m(C){b.hidden=!C,b.innerHTML=C?`${W}<span>${k(C)}</span>`:"",h.classList.toggle("invalid",!!C),h.setAttribute("aria-invalid",String(!!C))}g.addEventListener("click",async()=>{if(y)return;if(!h.value.trim()){m("Write a few words — a sentence is plenty."),h.focus();return}y=!0,e.sending=!0,u("");const C=g.innerHTML;g.disabled=!0,g.innerHTML='<span class="spinner" aria-hidden="true"></span>Sending…';try{const A=await t.feedback({message:h.value,kind:n,score:p,...l&&l.value.trim()?{email:l.value.trim()}:{}});if(A!=null&&A.cancelled)throw Object.assign(new Error(""),{quiet:!0});if(L=!0,clearTimeout(E),S)try{localStorage.removeItem(r)}catch{}M()}catch(A){y=!1,e.sending=!1,g.disabled=!1,g.innerHTML=C,A.quiet||u(String(A.message||"That did not send. Please try again.").replace("[BugCatch] ",""))}});function M(){e.sending=!1,s.querySelector(".panel").innerHTML=`
|
|
1400
|
+
<div class="done">
|
|
1401
|
+
<div class="tick">${O}</div>
|
|
1402
|
+
<h3>Thanks — that's with the team.</h3>
|
|
1403
|
+
<p>Everything sent here is read by the people who build this.</p>
|
|
1404
|
+
</div>`,setTimeout(f,2600)}e.focusFeedback=()=>h.focus()}const oe={report:{title:"Report a bug",sub:"We attach the page details for you."},feedback:{title:"Give feedback",sub:"The team reads every note."}};function Xt({root:e,host:t,dock:a,client:s,onClose:c,preloadCall:u=()=>{},themeControls:f=null,mode:d="report"}){Jt(e);const h=s.config,b=()=>(f==null?void 0:f.label())||"",g=h.feedback!==!1;let $=g&&d==="feedback"?"feedback":"report";const n=document.createElement("div");n.className=`scrim ${a.classList.contains("at-left")?"at-left":"at-right"} ${a.classList.contains("at-top")?"at-top":"at-bottom"}`,n.style.setProperty("--bc-dock-h",`${Math.round(a.getBoundingClientRect().height)}px`),n.innerHTML=`
|
|
1405
|
+
<div class="panel" role="dialog" aria-modal="true" aria-labelledby="bc-h" data-mode="${$}">
|
|
1406
|
+
${se({id:"bc-h",title:oe[$].title,sub:oe[$].sub,theme:b()})}
|
|
1407
|
+
${g?`
|
|
1408
|
+
<div class="modes" role="group" aria-label="What would you like to do?">
|
|
1409
|
+
<button type="button" data-mode="report" aria-pressed="${$==="report"}">${_e}Report a bug</button>
|
|
1410
|
+
<button type="button" data-mode="feedback" aria-pressed="${$==="feedback"}">${Je}Give feedback</button>
|
|
1411
|
+
</div>`:""}
|
|
1322
1412
|
<div class="body">
|
|
1323
1413
|
<div class="slot" role="alert"></div>
|
|
1324
1414
|
<!-- A settled report still waiting for its rating. Drawn only when the
|
|
1325
1415
|
project asks for one here; see rate-due.js. -->
|
|
1326
|
-
<div class="rate-due fix-rating" tabindex="-1" hidden></div>
|
|
1416
|
+
<div class="rate-due fix-rating bug-only" tabindex="-1" hidden></div>
|
|
1327
1417
|
<!-- What the project's team is telling visitors. Drawn only when it
|
|
1328
1418
|
has published something. -->
|
|
1329
1419
|
<div class="notices" hidden></div>
|
|
1330
|
-
<div class="whoami" hidden></div>
|
|
1420
|
+
<div class="whoami bug-only" hidden></div>
|
|
1331
1421
|
<!-- The questions the assistant can answer from their account and
|
|
1332
1422
|
close by itself. Drawn only when the project offers any. -->
|
|
1333
|
-
<div class="picks" hidden></div>
|
|
1334
|
-
<div class="known" hidden></div>
|
|
1335
|
-
${
|
|
1423
|
+
<div class="picks bug-only" hidden></div>
|
|
1424
|
+
<div class="known bug-only" hidden></div>
|
|
1425
|
+
${wt(h)}
|
|
1426
|
+
${g?Zt():""}
|
|
1336
1427
|
</div>
|
|
1337
1428
|
<div class="foot">
|
|
1338
|
-
<span class="note" aria-live="polite"></span>
|
|
1339
|
-
${
|
|
1429
|
+
<span class="note bug-only" aria-live="polite"></span>
|
|
1430
|
+
${s.hasReports()?'<button class="quiet" type="button" data-act="history">Your reports</button>':""}
|
|
1340
1431
|
<span class="spacer"></span>
|
|
1341
1432
|
<!-- Hidden until the API confirms this project can take a call, which
|
|
1342
1433
|
most cannot. Drawn here rather than as a second launcher because it
|
|
1343
1434
|
is the same errand as Send report — the difference is only whether
|
|
1344
1435
|
the reporter would rather say it than type it. -->
|
|
1345
|
-
<button class="ghost" type="button" data-act="call" hidden>${ee}Talk to the team</button>
|
|
1346
|
-
<button class="primary" type="button" data-act="send">Send report ${
|
|
1436
|
+
<button class="ghost bug-only" type="button" data-act="call" hidden>${ee}Talk to the team</button>
|
|
1437
|
+
<button class="primary bug-only" type="button" data-act="send">Send report ${ie}</button>
|
|
1438
|
+
${g?`<button class="primary fb-only" type="button" data-act="send-feedback">Send feedback ${ie}</button>`:""}
|
|
1347
1439
|
</div>
|
|
1348
1440
|
<div class="powered">Powered by
|
|
1349
|
-
<a class="brand-credit" href="https://bugcatch.sphoro.com" target="_blank" rel="noopener noreferrer" aria-label="BugCatch">${
|
|
1441
|
+
<a class="brand-credit" href="https://bugcatch.sphoro.com" target="_blank" rel="noopener noreferrer" aria-label="BugCatch">${Xe}</a>
|
|
1350
1442
|
</div>
|
|
1351
|
-
</div>`;const
|
|
1443
|
+
</div>`;const p=v=>n.querySelector(v),y=p(".slot"),L=[],o={client:s,cfg:h,root:e,host:t,dock:a,scrim:n,$:p,titleInput:p("#bc-title"),descInput:p("#bc-desc"),compose:p(".compose"),sendBtn:p('[data-act="send"]'),callBtn:p('[data-act="call"]'),historyBtn:p('[data-act="history"]'),note:p(".foot .note"),whoami:p(".whoami"),refsBox:p(".refs"),notices:p(".notices"),known:p(".known"),picks:p(".picks"),rateDue:p(".rate-due"),sending:!1,closed:!1,say:M,close:x,preloadCall:u,themeLabel:b,onDestroy:v=>{L.push(v)},refreshSendState:null,isRecording:null,stopRecording:null,holdForReference:null,answeredReference:null,pickedIssue:null,offerCall:null,callOffered:null,showLiveCall:null,mustSignIn:null,recheckSignIn:null,mustRate:()=>!1,focusFeedback:()=>{},succeed:null,refreshThread:null,openReportId:null};xt(o),Lt(o),qt(o),Ct(o),zt(o),At(o),Ht(o),Nt(o),Kt(o),g&&Gt(o);function i(v,{focus:q=!0}={}){const C=v==="feedback"&&p(".modes")?"feedback":"report",A=n.querySelector(".panel");o.closed||o.sending||!A||!n.querySelector(".modes")||C==="feedback"&&o.isRecording()||($=C,A.dataset.mode=C,A.querySelector("#bc-h").textContent=oe[C].title,A.querySelector(".head .titles p").textContent=oe[C].sub,n.querySelectorAll(".modes [data-mode]").forEach(B=>{B.setAttribute("aria-pressed",String(B.dataset.mode===C))}),M(""),q&&(C==="feedback"?o.focusFeedback():o.titleInput.focus()))}n.querySelectorAll(".modes [data-mode]").forEach(v=>{v.addEventListener("click",()=>i(v.dataset.mode))}),g&&s.feedbackEnabled().then(v=>{var C,A,B;if(v||o.closed||o.sending)return;i("report",{focus:$==="feedback"}),(C=n.querySelector(".modes"))==null||C.remove(),(A=n.querySelector(".feedback"))==null||A.remove(),(B=n.querySelector('[data-act="send-feedback"]'))==null||B.remove()});const l=document.activeElement,r=document.documentElement.style,S=r.overflow;r.overflow="hidden";function E(){o.closed||(L.forEach(v=>v()),o.closed=!0,r.overflow=S,document.removeEventListener("keydown",m,!0),n.remove(),a.hidden=!1,t.style.opacity="",c==null||c())}function x(){var v;if(!o.closed){n.classList.add("closing"),setTimeout(E,160);try{(v=l==null?void 0:l.focus)==null||v.call(l)}catch{}}}function m(v){if(v.key==="Escape"){if(v.stopPropagation(),o.isRecording()){o.stopRecording({keep:!1});return}o.sending||x();return}if(v.key!=="Tab"||o.isRecording())return;const q=[...n.querySelectorAll("button:not(:disabled), input:not([hidden]), textarea, select, [href]")].filter(T=>T.offsetParent!==null||T===document.activeElement);if(!q.length)return;const C=q[0],A=q[q.length-1],B=n.getRootNode().activeElement;v.shiftKey&&B===C?(v.preventDefault(),A.focus()):!v.shiftKey&&B===A&&(v.preventDefault(),C.focus())}document.addEventListener("keydown",m,!0),n.addEventListener("click",v=>{v.target===n&&!o.sending&&x()}),p('[data-act="close"]').addEventListener("click",x),n.addEventListener("click",v=>{const q=v.target.closest('[data-act="theme"]');if(!q||!f)return;const C=f.cycle();q.title=`Theme: ${C.label}`,q.setAttribute("aria-label",`Theme: ${C.label}. Change theme`)});function M(v,q="err"){y.innerHTML=v?`<div class="msg ${q}">${q==="err"?W:""}<span>${k(v)}</span></div>`:""}return e.appendChild(n),o.refreshSendState(),$==="feedback"?o.focusFeedback():o.titleInput.focus(),{destroy:E,close:x,setMode:i}}function Jt(e){if(e.querySelector("style[data-panel]"))return;const t=document.createElement("style");t.setAttribute("data-panel",""),t.textContent=ot;const a=e.querySelector("style");a?a.after(t):e.prepend(t)}const ea=Object.freeze(Object.defineProperty({__proto__:null,openPanel:Xt},Symbol.toStringTag,{value:"Module"})),ta="0.21.0",je="__bugcatchChunks",aa=e=>`${e}@${ta}`;function na(e,t){const a=window[je]||(window[je]={});a[aa(e)]=t}na("panel",ea)})();
|
|
1352
1444
|
//# sourceMappingURL=bugcatch-panel.umd.js.map
|