@nivaro/react 0.3.41 → 0.3.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/dist/components/LayoutForm.js +100 -98
  2. package/dist/full.css +1 -1
  3. package/dist/hooks/useSessionRecorder.js +1 -1
  4. package/dist/index.d.ts +644 -15
  5. package/dist/index.js +814 -775
  6. package/dist/shared/components/ActivityEntry.js +154 -0
  7. package/dist/shared/components/AudienceConfirmPanel.js +98 -0
  8. package/dist/shared/components/BackgroundRunOffer.js +43 -31
  9. package/dist/shared/components/BroadcastView.js +225 -204
  10. package/dist/shared/components/CollectionBrowserView.js +3924 -3584
  11. package/dist/shared/components/ConfigHistory.js +153 -0
  12. package/dist/shared/components/ConfigReadBack.js +65 -0
  13. package/dist/shared/components/DataTable.js +379 -346
  14. package/dist/shared/components/ForceReloadBanner.js +47 -40
  15. package/dist/shared/components/IdleReloadWatcher.js +69 -0
  16. package/dist/shared/components/ItemEditForm.js +4041 -3853
  17. package/dist/shared/components/MyWorkView.js +278 -213
  18. package/dist/shared/components/NotificationBell.js +130 -121
  19. package/dist/shared/components/ProfileView.js +776 -1003
  20. package/dist/shared/components/RecentRecordsRail.js +34 -16
  21. package/dist/shared/components/RecordReadView.js +500 -477
  22. package/dist/shared/components/Skeletons.js +199 -0
  23. package/dist/shared/components/SlowNotice.js +63 -0
  24. package/dist/shared/components/Term.js +23 -0
  25. package/dist/shared/components/WidgetSlot.js +350 -353
  26. package/dist/shared/components/access/PermissionSummary.js +106 -0
  27. package/dist/shared/components/bulk/BulkActionButtons.js +76 -73
  28. package/dist/shared/components/chat/ChatPanel.js +902 -886
  29. package/dist/shared/components/chat/MemberPaging.js +70 -0
  30. package/dist/shared/components/chat/RoomParts.js +147 -117
  31. package/dist/shared/components/chat/ScreenClip.js +73 -69
  32. package/dist/shared/components/chat/chat-core.js +449 -396
  33. package/dist/shared/components/chat/huddle/huddle-store.js +48 -43
  34. package/dist/shared/components/help-videos/api.js +2 -5
  35. package/dist/shared/components/help-videos/viewer/HelpVideoMatchChip.js +79 -0
  36. package/dist/shared/components/help-videos/viewer/matchChip.js +50 -0
  37. package/dist/shared/components/imports/CollectionImportPanel.js +139 -133
  38. package/dist/shared/components/imports/RunDetailSheet.js +222 -227
  39. package/dist/shared/components/integrations/console/ErrorExplanation.js +121 -0
  40. package/dist/shared/components/integrations/console/PartnerDetail.js +175 -174
  41. package/dist/shared/components/integrations/console/SubmissionRow.js +36 -34
  42. package/dist/shared/components/integrations/console/drill/SubmissionDrill.js +50 -48
  43. package/dist/shared/components/item-edit/FieldComments.js +212 -0
  44. package/dist/shared/components/item-edit/FieldRow.js +340 -336
  45. package/dist/shared/components/item-edit/RecordHeaderActions.js +23 -22
  46. package/dist/shared/components/item-edit/RelationCombobox.js +231 -222
  47. package/dist/shared/components/item-edit/RuleHiddenNotes.js +55 -0
  48. package/dist/shared/components/item-edit/field-comments-context.js +6 -0
  49. package/dist/shared/components/item-edit/field-sources.js +33 -0
  50. package/dist/shared/components/item-edit/rule-hidden.js +30 -0
  51. package/dist/shared/components/layout-editor/HistoryPanel.js +113 -96
  52. package/dist/shared/components/layout-editor/editors/cascade-filters.js +170 -145
  53. package/dist/shared/components/layout-editor/inspector/Breadcrumb.js +22 -18
  54. package/dist/shared/components/layout-editor/inspector/GroupInspector.js +177 -159
  55. package/dist/shared/components/layout-editor/inspector/PickerTab.js +35 -34
  56. package/dist/shared/components/layout-editor/inspector/RulesTab.js +124 -111
  57. package/dist/shared/components/layout-editor/inspector/kit.js +292 -277
  58. package/dist/shared/components/layout-editor/parity-keys.json.js +1 -1
  59. package/dist/shared/components/list/CopyListLinkButton.js +41 -0
  60. package/dist/shared/components/list/InlineEdit.js +363 -0
  61. package/dist/shared/components/notifications/NotificationCenterView.js +213 -181
  62. package/dist/shared/components/notifications/NotificationDetailBits.js +205 -82
  63. package/dist/shared/components/notifications/NotificationRulesEditor.js +515 -0
  64. package/dist/shared/components/notifications/TestMyRules.js +137 -0
  65. package/dist/shared/components/notifications/changes-lines.js +24 -0
  66. package/dist/shared/components/notifications/why-lines.js +64 -0
  67. package/dist/shared/components/panels/CommentPanel.js +316 -281
  68. package/dist/shared/components/panels/LegalHoldBanner.js +38 -0
  69. package/dist/shared/components/panels/PipelinePanel.js +201 -196
  70. package/dist/shared/components/panels/RevisionsPanel.js +496 -479
  71. package/dist/shared/components/pipeline/PipelineEditorView.js +1587 -1560
  72. package/dist/shared/components/pipeline/PipelineStateOwners.js +116 -103
  73. package/dist/shared/components/profile/PersonDidPanel.js +188 -0
  74. package/dist/shared/components/profile/PersonProfile.js +57 -52
  75. package/dist/shared/components/queue/QueueWorklist.js +1526 -1365
  76. package/dist/shared/hooks/useSlowReason.js +39 -0
  77. package/dist/shared/lib/activity-sentence.js +670 -0
  78. package/dist/shared/lib/config-sentences.js +418 -0
  79. package/dist/shared/lib/core-glossary.js +229 -0
  80. package/dist/shared/lib/error-hints.js +159 -0
  81. package/dist/shared/lib/error-message.js +105 -0
  82. package/dist/shared/lib/error-toast.js +22 -0
  83. package/dist/shared/lib/field-comments.js +25 -0
  84. package/dist/shared/lib/filter-sentence.js +261 -0
  85. package/dist/shared/lib/glossary.js +55 -48
  86. package/dist/shared/lib/idle-reload.js +138 -0
  87. package/dist/shared/lib/layout-resolve.js +42 -29
  88. package/dist/shared/lib/list-inline-edit.js +190 -0
  89. package/dist/shared/lib/list-link.js +147 -0
  90. package/dist/shared/lib/prefetch.js +259 -106
  91. package/dist/shared/lib/record-ref.js +72 -0
  92. package/dist/shared/lib/reload-holds.js +25 -0
  93. package/dist/shared/lib/safe-error.js +52 -24
  94. package/dist/shared/lib/skeleton-shapes.js +72 -0
  95. package/dist/shared/lib/slow-reason.js +63 -0
  96. package/package.json +1 -1
@@ -1,10 +1,11 @@
1
1
  var S = Object.defineProperty;
2
2
  var w = (h, t, e) => t in h ? S(h, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : h[t] = e;
3
3
  var c = (h, t, e) => w(h, typeof t != "symbol" ? t + "" : t, e);
4
- import { micConstraints as y, loadDevicePrefs as T } from "./huddle-device-prefs.js";
5
- import { huddleLive as M } from "./huddle-live.js";
6
- import { aggregateQuality as b } from "./huddle-quality.js";
7
- import { SfuSession as A, MESH_OVERLAP_MS as L } from "./huddle-sfu.js";
4
+ import { registerReloadHold as y } from "../../../lib/reload-holds.js";
5
+ import { micConstraints as T, loadDevicePrefs as M } from "./huddle-device-prefs.js";
6
+ import { huddleLive as b } from "./huddle-live.js";
7
+ import { aggregateQuality as A } from "./huddle-quality.js";
8
+ import { SfuSession as L, MESH_OVERLAP_MS as O } from "./huddle-sfu.js";
8
9
  const p = {
9
10
  room: null,
10
11
  status: "idle",
@@ -18,13 +19,13 @@ const p = {
18
19
  mode: "mesh",
19
20
  micLabel: null,
20
21
  handAt: null
21
- }, O = 15e3, V = {
22
+ }, V = 15e3, C = {
22
23
  video: { frameRate: 15, width: { ideal: 1920 }, height: { ideal: 1080 } },
23
24
  audio: !1,
24
25
  selfBrowserSurface: "include",
25
26
  surfaceSwitching: "include"
26
27
  };
27
- function C(h, t) {
28
+ function I(h, t) {
28
29
  return h < t;
29
30
  }
30
31
  function g(h, t, e) {
@@ -36,15 +37,15 @@ function g(h, t, e) {
36
37
  }
37
38
  return s;
38
39
  }
39
- function $(h) {
40
+ function F(h) {
40
41
  const t = h.map((e) => e.name || "Someone");
41
42
  return t.length === 0 ? "" : t.length === 1 ? t[0] : t.length === 2 ? `${t[0]} and ${t[1]}` : `${t[0]}, ${t[1]} and ${t.length - 2} other${t.length - 2 === 1 ? "" : "s"}`;
42
43
  }
43
- function q(h) {
44
+ function H(h) {
44
45
  const t = Math.max(0, Math.floor(h / 1e3)), e = Math.floor(t / 60), s = Math.floor(e / 60), i = String(e % 60).padStart(2, "0"), o = String(t % 60).padStart(2, "0");
45
46
  return s ? `${s}:${i}:${o}` : `${e}:${o}`;
46
47
  }
47
- class I {
48
+ class P {
48
49
  constructor() {
49
50
  c(this, "state", p);
50
51
  c(this, "listeners", /* @__PURE__ */ new Set());
@@ -119,7 +120,7 @@ class I {
119
120
  attach(t, e, s) {
120
121
  if (this.fetchIce = e, s && (this.fetchSfu = s), this.transport !== t) {
121
122
  for (const i of this.offs) i();
122
- this.transport = t, M.attach(t), this.offs = [
123
+ this.transport = t, b.attach(t), this.offs = [
123
124
  t.on("huddle:peers", (i) => this.onPeers(i)),
124
125
  t.on(
125
126
  "huddle:joined",
@@ -187,7 +188,7 @@ class I {
187
188
  this.state.room && e && this.leave(), this.linkStats.clear(), this.iceFailed = 0, this.set({ room: t, status: "joining", error: null, startedAt: null });
188
189
  try {
189
190
  this.mic = await navigator.mediaDevices.getUserMedia({
190
- audio: y(T())
191
+ audio: T(M())
191
192
  });
192
193
  } catch (i) {
193
194
  const o = i == null ? void 0 : i.name;
@@ -206,7 +207,7 @@ class I {
206
207
  const t = this.state.room;
207
208
  if (t) {
208
209
  for (const o of this.beforeLeave) o(t);
209
- const i = b([...this.linkStats.values()], this.iceFailed);
210
+ const i = A([...this.linkStats.values()], this.iceFailed);
210
211
  i && this.state.status === "live" && ((e = this.transport) == null || e.emit("huddle:quality", { room: t, ...i })), (s = this.transport) == null || s.emit("huddle:leave", { room: t });
211
212
  }
212
213
  this.teardown();
@@ -228,14 +229,14 @@ class I {
228
229
  if (t.room !== this.state.room) return;
229
230
  const e = !!this.state.self && this.state.self !== t.self;
230
231
  if (e)
231
- for (const [n, f] of this.links) this.closeLink(n, f);
232
+ for (const [n, u] of this.links) this.closeLink(n, u);
232
233
  const s = g([], t.peers, t.self), i = Math.min(Date.now(), ...t.peers.map((n) => n.since).filter(Boolean)), o = t.mode === "sfu" ? "sfu" : "mesh";
233
234
  if (this.set({ status: "live", self: t.self, peers: s, startedAt: i, error: null, mode: o }), o === "sfu") this.enterSfu(e);
234
235
  else for (const n of s) this.link(n.socket);
235
236
  this.ping && clearInterval(this.ping), this.ping = setInterval(() => {
236
237
  var n;
237
238
  this.state.room && ((n = this.transport) == null || n.emit("huddle:ping", { room: this.state.room }));
238
- }, O), (this.state.muted || this.state.sharing) && ((r = this.transport) == null || r.emit("huddle:state", {
239
+ }, V), (this.state.muted || this.state.sharing) && ((r = this.transport) == null || r.emit("huddle:state", {
239
240
  room: t.room,
240
241
  muted: this.state.muted,
241
242
  screen: this.state.sharing
@@ -247,22 +248,22 @@ class I {
247
248
  if (this.setRoster(t.room, t.peers), t.room !== this.state.room || this.state.status !== "live") return;
248
249
  t.mode === "sfu" && this.state.mode !== "sfu" && this.enterSfu(!1);
249
250
  const e = this.state.self, s = g(this.state.peers, t.peers, e);
250
- for (const [n, f] of this.links)
251
- s.some((u) => u.socket === n) || this.closeLink(n, f);
251
+ for (const [n, u] of this.links)
252
+ s.some((f) => f.socket === n) || this.closeLink(n, u);
252
253
  for (const n of [...this.audio.keys()])
253
- s.some((f) => f.socket === n) || this.dropAudio(n);
254
+ s.some((u) => u.socket === n) || this.dropAudio(n);
254
255
  for (const n of [...this.sfuVideo.keys()])
255
- s.some((f) => f.socket === n) || this.sfuVideo.delete(n);
256
+ s.some((u) => u.socket === n) || this.sfuVideo.delete(n);
256
257
  for (const n of s) {
257
258
  if (n.audio || n.video) continue;
258
- const f = this.audio.get(n.socket);
259
- if (this.sfuAudio.has(n.socket) && (f == null ? void 0 : f.srcObject) instanceof MediaStream) {
260
- n.audio = f.srcObject, n.connection = "connected";
259
+ const u = this.audio.get(n.socket);
260
+ if (this.sfuAudio.has(n.socket) && (u == null ? void 0 : u.srcObject) instanceof MediaStream) {
261
+ n.audio = u.srcObject, n.connection = "connected";
261
262
  continue;
262
263
  }
263
- const u = this.links.get(n.socket);
264
- if (u)
265
- for (const m of u.pc.getReceivers()) {
264
+ const f = this.links.get(n.socket);
265
+ if (f)
266
+ for (const m of f.pc.getReceivers()) {
266
267
  if (((o = m.track) == null ? void 0 : o.readyState) !== "live") continue;
267
268
  const a = new MediaStream([m.track]);
268
269
  m.track.kind === "video" ? (r = this.remoteVideo.get(n.socket)) != null && r.size || (n.video = a) : n.audio = a;
@@ -291,8 +292,8 @@ class I {
291
292
  (o = this.sfu) == null || o.disconnect(), this.sfu = null;
292
293
  let i;
293
294
  try {
294
- const f = await this.fetchSfu(e, s);
295
- if (this.state.room !== e || this.state.self !== s || (i = new A(), this.sfu = i, await i.connect(f, {
295
+ const u = await this.fetchSfu(e, s);
296
+ if (this.state.room !== e || this.state.self !== s || (i = new L(), this.sfu = i, await i.connect(u, {
296
297
  onTrack: (a, d, v) => this.onSfuTrack(a, d, v),
297
298
  onTrackEnd: (a, d) => this.onSfuTrackEnd(a, d),
298
299
  onReconnecting: () => {
@@ -306,8 +307,8 @@ class I {
306
307
  }));
307
308
  }
308
309
  }), this.sfu !== i)) return;
309
- const u = (r = this.mic) == null ? void 0 : r.getAudioTracks()[0];
310
- u && await i.publishMic(u), this.state.muted && i.setMicMuted(!0);
310
+ const f = (r = this.mic) == null ? void 0 : r.getAudioTracks()[0];
311
+ f && await i.publishMic(f), this.state.muted && i.setMicMuted(!0);
311
312
  const m = (l = this.state.localScreen) == null ? void 0 : l.getVideoTracks()[0];
312
313
  m && this.state.sharing && await i.publishScreen(m);
313
314
  for (const a of this.exts) (n = a.sfu) == null || n.call(a, i);
@@ -320,7 +321,7 @@ class I {
320
321
  });
321
322
  return;
322
323
  }
323
- this.meshCloseTimer && clearTimeout(this.meshCloseTimer), this.meshCloseTimer = setTimeout(() => this.closeMeshLinks(), L);
324
+ this.meshCloseTimer && clearTimeout(this.meshCloseTimer), this.meshCloseTimer = setTimeout(() => this.closeMeshLinks(), O);
324
325
  }
325
326
  /** The SFU's labelled video for a peer (#2858): camera tile and shared screen, apart. */
326
327
  sfuVideoOf(t) {
@@ -397,7 +398,7 @@ class I {
397
398
  });
398
399
  }
399
400
  async link(t) {
400
- var f, u, m;
401
+ var u, f, m;
401
402
  const e = this.links.get(t);
402
403
  if (e) return e;
403
404
  const s = this.state.self, i = this.state.room;
@@ -406,15 +407,15 @@ class I {
406
407
  if (this.links.has(t)) return this.links.get(t) ?? null;
407
408
  const r = new RTCPeerConnection({ iceServers: o }), l = {
408
409
  pc: r,
409
- polite: C(s, t),
410
+ polite: I(s, t),
410
411
  makingOffer: !1,
411
412
  ignoreOffer: !1,
412
413
  screenSender: null,
413
414
  queue: Promise.resolve()
414
415
  };
415
416
  this.links.set(t, l);
416
- for (const a of ((f = this.mic) == null ? void 0 : f.getAudioTracks()) ?? []) r.addTrack(a, this.mic);
417
- const n = (u = this.state.localScreen) == null ? void 0 : u.getVideoTracks()[0];
417
+ for (const a of ((u = this.mic) == null ? void 0 : u.getAudioTracks()) ?? []) r.addTrack(a, this.mic);
418
+ const n = (f = this.state.localScreen) == null ? void 0 : f.getVideoTracks()[0];
418
419
  n && this.state.localScreen && (l.screenSender = r.addTrack(n, this.state.localScreen));
419
420
  for (const a of this.exts) (m = a.link) == null || m.call(a, t, r);
420
421
  return r.onnegotiationneeded = async () => {
@@ -445,7 +446,7 @@ class I {
445
446
  i.set(e.id, o);
446
447
  const r = () => {
447
448
  var n;
448
- const l = ((n = this.state.peers.find((f) => f.socket === t)) == null ? void 0 : n.cam) ?? null;
449
+ const l = ((n = this.state.peers.find((u) => u.socket === t)) == null ? void 0 : n.cam) ?? null;
449
450
  this.updatePeer(t, this.videoOf(t, l));
450
451
  };
451
452
  s.onended = () => {
@@ -511,7 +512,7 @@ class I {
511
512
  if (this.state.status !== "live" || this.state.sharing) return;
512
513
  let t;
513
514
  try {
514
- t = await navigator.mediaDevices.getDisplayMedia(V);
515
+ t = await navigator.mediaDevices.getDisplayMedia(C);
515
516
  } catch {
516
517
  return;
517
518
  }
@@ -600,8 +601,12 @@ async function k(h, t) {
600
601
  const e = h;
601
602
  typeof e.setSinkId == "function" && await e.setSinkId(t).catch(() => null);
602
603
  }
603
- const N = new I();
604
- function F() {
604
+ const D = new P();
605
+ y("A huddle", () => {
606
+ const h = D.getSnapshot().status;
607
+ return h === "live" || h === "joining";
608
+ });
609
+ function _() {
605
610
  if (typeof navigator > "u" || typeof window > "u")
606
611
  return { audio: !1, screen: !1 };
607
612
  const h = navigator.mediaDevices;
@@ -611,11 +616,11 @@ function F() {
611
616
  };
612
617
  }
613
618
  export {
614
- V as SCREEN_SHARE_OPTIONS,
615
- q as formatElapsed,
616
- N as huddleStore,
617
- F as huddleSupport,
619
+ C as SCREEN_SHARE_OPTIONS,
620
+ H as formatElapsed,
621
+ D as huddleStore,
622
+ _ as huddleSupport,
618
623
  g as mergeRoster,
619
- $ as peerSummary,
620
- C as politeFor
624
+ F as peerSummary,
625
+ I as politeFor
621
626
  };
@@ -66,13 +66,10 @@ function M(s, a = !0) {
66
66
  const e = d();
67
67
  return v([["help-videos", "for"]]), u({
68
68
  queryKey: l.forCtx(s),
69
- enabled: a && !!(s.collection || s.page),
69
+ enabled: a && !!(s.collection || s.page || s.path),
70
70
  staleTime: 6e4,
71
71
  queryFn: () => e.request(
72
- r(
73
- "/help-videos/for",
74
- s
75
- )
72
+ r("/help-videos/for", s)
76
73
  )
77
74
  });
78
75
  }
@@ -0,0 +1,79 @@
1
+ import { jsxs as r, Fragment as C, jsx as t } from "react/jsx-runtime";
2
+ import { PlayCircle as $, X as j } from "lucide-react";
3
+ import { useState as v, useRef as H } from "react";
4
+ import { useHelpVideosFor as V } from "../api.js";
5
+ import { LazyHelpVideoSheet as D } from "./LazyHelpVideoSheet.js";
6
+ import { readDismissed as F, chipVideo as R, chipLabel as L, rememberDismissed as O, chipAllowedOn as P } from "./matchChip.js";
7
+ const x = "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-nvr-cyan motion-reduce:transition-none";
8
+ function W({
9
+ path: o,
10
+ app: s,
11
+ page: d,
12
+ collection: l,
13
+ item: a,
14
+ terms: i,
15
+ className: w
16
+ }) {
17
+ var p, g, b;
18
+ const c = P(o), u = V(
19
+ {
20
+ path: o,
21
+ ...s ? { app: s } : {},
22
+ ...d ? { page: d } : {},
23
+ ...l ? { collection: l } : {},
24
+ ...a != null ? { item: a } : {},
25
+ ...i != null && i.length ? { terms: i.slice(0, 12).join(",") } : {}
26
+ },
27
+ c
28
+ ), [y, k] = v(() => F()), [h, n] = v(null), m = H(null), f = ((p = u.data) == null ? void 0 : p.data) ?? [], e = c ? R(f, (g = u.data) == null ? void 0 : g.best_id, y) : null;
29
+ return /* @__PURE__ */ r(C, { children: [
30
+ e && /* @__PURE__ */ t("div", { className: w, "data-hv-match-chip": !0, "data-nvr-recording-hide": !0, children: /* @__PURE__ */ r("div", { className: "inline-flex h-7 max-w-full items-center rounded-full border border-border bg-card text-[12px] text-foreground shadow-sm", children: [
31
+ /* @__PURE__ */ r(
32
+ "button",
33
+ {
34
+ ref: m,
35
+ type: "button",
36
+ onClick: () => n(e.id),
37
+ title: (b = e.match) != null && b.reason ? `${e.match.reason} — ${e.title}` : e.title,
38
+ className: `flex min-w-0 items-center gap-1.5 rounded-l-full py-1 pl-2.5 pr-1.5 transition-colors hover:bg-muted ${x}`,
39
+ "data-hv-match-play": e.id,
40
+ children: [
41
+ /* @__PURE__ */ t(
42
+ $,
43
+ {
44
+ className: "h-3.5 w-3.5 shrink-0 text-[#2563eb] dark:text-sky-300",
45
+ "aria-hidden": "true"
46
+ }
47
+ ),
48
+ /* @__PURE__ */ t("span", { className: "truncate", children: L(e) })
49
+ ]
50
+ }
51
+ ),
52
+ /* @__PURE__ */ t(
53
+ "button",
54
+ {
55
+ type: "button",
56
+ "aria-label": `Hide the suggestion "${e.title}"`,
57
+ onClick: () => k(O(e.id)),
58
+ className: `flex h-7 w-7 shrink-0 items-center justify-center rounded-r-full text-muted-foreground transition-colors hover:bg-muted hover:text-foreground ${x}`,
59
+ "data-hv-match-dismiss": !0,
60
+ children: /* @__PURE__ */ t(j, { className: "h-3.5 w-3.5", "aria-hidden": "true" })
61
+ }
62
+ )
63
+ ] }) }),
64
+ /* @__PURE__ */ t(
65
+ D,
66
+ {
67
+ videoId: h,
68
+ open: !!h,
69
+ onOpenChange: (N) => !N && n(null),
70
+ upNext: f,
71
+ onPick: n,
72
+ returnFocusRef: m
73
+ }
74
+ )
75
+ ] });
76
+ }
77
+ export {
78
+ W as HelpVideoMatchChip
79
+ };
@@ -0,0 +1,50 @@
1
+ import { isGettingReady as c, formatDuration as a } from "./format.js";
2
+ const o = "nvr_hv_chip_dismissed";
3
+ function l() {
4
+ try {
5
+ return typeof window < "u" ? window.localStorage : null;
6
+ } catch {
7
+ return null;
8
+ }
9
+ }
10
+ function s(t = l()) {
11
+ try {
12
+ const e = t == null ? void 0 : t.getItem(o), r = e ? JSON.parse(e) : [];
13
+ return new Set(
14
+ Array.isArray(r) ? r.filter((n) => typeof n == "string").map((n) => n.toLowerCase()) : []
15
+ );
16
+ } catch {
17
+ return /* @__PURE__ */ new Set();
18
+ }
19
+ }
20
+ function d(t, e = l()) {
21
+ const r = s(e);
22
+ r.delete(t.toLowerCase());
23
+ const n = [...r, t.toLowerCase()].slice(-200);
24
+ try {
25
+ e == null || e.setItem(o, JSON.stringify(n));
26
+ } catch {
27
+ }
28
+ return new Set(n);
29
+ }
30
+ function m(t, e, r) {
31
+ var i;
32
+ if (!e || !(t != null && t.length)) return null;
33
+ const n = t.find((u) => u.id.toLowerCase() === e.toLowerCase());
34
+ return !n || r.has(n.id.toLowerCase()) || (i = n.my_progress) != null && i.completed || c(n) ? null : n;
35
+ }
36
+ function w(t) {
37
+ const e = t.duration_ms != null ? ` (${a(t.duration_ms)})` : "";
38
+ return `Watch: ${t.title}${e}`;
39
+ }
40
+ function p(t) {
41
+ return !/^\/(help-videos|help\/videos)(\/|$)/.test(t);
42
+ }
43
+ export {
44
+ o as CHIP_DISMISSED_KEY,
45
+ p as chipAllowedOn,
46
+ w as chipLabel,
47
+ m as chipVideo,
48
+ s as readDismissed,
49
+ d as rememberDismissed
50
+ };