@q9labsai/chalk-react 4.1.15 → 4.1.16
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 +23 -1
- package/THIRD_PARTY_NOTICES.md +29 -0
- package/dist/bindings/hooks.d.ts +4 -1
- package/dist/bindings/hooks.d.ts.map +1 -1
- package/dist/{chunk-4X3NFZGL.js → chunk-C7PNVYDZ.js} +9679 -10020
- package/dist/chunk-FFPNO2MY.js +131 -0
- package/dist/chunk-HZ43I4OS.js +138 -0
- package/dist/chunk-RMOJ5DLX.js +1421 -0
- package/dist/chunk-S6OVGZD5.js +3164 -0
- package/dist/chunk-VLAZKVNN.js +182 -0
- package/dist/components/atomic/Avatar.d.ts +4 -0
- package/dist/components/atomic/Avatar.d.ts.map +1 -1
- package/dist/components/atomic/ClassicAvatar.d.ts +1 -1
- package/dist/components/atomic/ClassicAvatar.d.ts.map +1 -1
- package/dist/components/atomic/ClassicReactionBubble.d.ts +2 -1
- package/dist/components/atomic/ClassicReactionBubble.d.ts.map +1 -1
- package/dist/components/atomic/ReactionBubble.d.ts +5 -2
- package/dist/components/atomic/ReactionBubble.d.ts.map +1 -1
- package/dist/components/audio-output/AudioOutput.d.ts +3 -1
- package/dist/components/audio-output/AudioOutput.d.ts.map +1 -1
- package/dist/components/chalk/Chalk.d.ts +3 -1
- package/dist/components/chalk/Chalk.d.ts.map +1 -1
- package/dist/components/composite/ChatPanel.d.ts +24 -1
- package/dist/components/composite/ChatPanel.d.ts.map +1 -1
- package/dist/components/composite/ClassicChatPanel.d.ts +23 -0
- package/dist/components/composite/ClassicChatPanel.d.ts.map +1 -1
- package/dist/components/composite/ClassicMessageBubble.d.ts.map +1 -1
- package/dist/components/composite/ClassicSettingsDialog.d.ts +1 -35
- package/dist/components/composite/ClassicSettingsDialog.d.ts.map +1 -1
- package/dist/components/composite/MessageBubble.d.ts +7 -1
- package/dist/components/composite/MessageBubble.d.ts.map +1 -1
- package/dist/components/composite/ReactionsOverlay.d.ts +13 -0
- package/dist/components/composite/ReactionsOverlay.d.ts.map +1 -1
- package/dist/components/composite/ScreenShareView.d.ts +8 -0
- package/dist/components/composite/ScreenShareView.d.ts.map +1 -1
- package/dist/components/composite/SettingsDialog.d.ts +2 -84
- package/dist/components/composite/SettingsDialog.d.ts.map +1 -1
- package/dist/components/composite/chat-panel-model.d.ts +17 -0
- package/dist/components/composite/chat-panel-model.d.ts.map +1 -1
- package/dist/components/composite/chat-upload-file.d.ts +8 -0
- package/dist/components/composite/chat-upload-file.d.ts.map +1 -0
- package/dist/components/composite/reaction-float.d.ts +2 -0
- package/dist/components/composite/reaction-float.d.ts.map +1 -1
- package/dist/components/composite/settings-dialog-behavior.d.ts +645 -0
- package/dist/components/composite/settings-dialog-behavior.d.ts.map +1 -0
- package/dist/components/composite/use-chat-attachment-previews.d.ts +10 -0
- package/dist/components/composite/use-chat-attachment-previews.d.ts.map +1 -0
- package/dist/components/control-bar/ClassicControlBar.d.ts +2 -1
- package/dist/components/control-bar/ClassicControlBar.d.ts.map +1 -1
- package/dist/components/control-bar/ControlBar.d.ts +8 -26
- package/dist/components/control-bar/ControlBar.d.ts.map +1 -1
- package/dist/components/control-bar/control-bar-behavior.d.ts +123 -0
- package/dist/components/control-bar/control-bar-behavior.d.ts.map +1 -0
- package/dist/components/device-popover/ClassicDevicePopover.d.ts +1 -1
- package/dist/components/device-popover/ClassicDevicePopover.d.ts.map +1 -1
- package/dist/components/device-popover/DevicePopover.d.ts +1 -0
- package/dist/components/device-popover/DevicePopover.d.ts.map +1 -1
- package/dist/components/entrance/Entrance.d.ts +2 -1
- package/dist/components/entrance/Entrance.d.ts.map +1 -1
- package/dist/components/entrance/EntranceDeviceControls.d.ts.map +1 -1
- package/dist/components/feedback/FeedbackDialog.d.ts +12 -0
- package/dist/components/feedback/FeedbackDialog.d.ts.map +1 -0
- package/dist/components/index.d.ts +8 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +31 -6
- package/dist/components/invite-dialog/ClassicInviteDialog.d.ts.map +1 -1
- package/dist/components/invite-dialog/InviteDialog.d.ts.map +1 -1
- package/dist/components/lazy.d.ts +2 -2
- package/dist/components/lazy.d.ts.map +1 -1
- package/dist/components/offline-actions/OfflineActions.d.ts +17 -0
- package/dist/components/offline-actions/OfflineActions.d.ts.map +1 -0
- package/dist/components/offline-actions/OfflineActionsSetting.d.ts +4 -0
- package/dist/components/offline-actions/OfflineActionsSetting.d.ts.map +1 -0
- package/dist/components/offline-actions/offline-actions-policy.d.ts +4 -0
- package/dist/components/offline-actions/offline-actions-policy.d.ts.map +1 -0
- package/dist/components/participant-tile/ParticipantTile.d.ts +7 -1
- package/dist/components/participant-tile/ParticipantTile.d.ts.map +1 -1
- package/dist/components/participant-tile/TileShell.d.ts +3 -1
- package/dist/components/participant-tile/TileShell.d.ts.map +1 -1
- package/dist/components/participants-panel/ParticipantsPanel.d.ts.map +1 -1
- package/dist/components/reconnecting-overlay/ClassicReconnectingOverlay.d.ts.map +1 -1
- package/dist/components/reconnecting-overlay/ReconnectingNotice.d.ts +6 -0
- package/dist/components/reconnecting-overlay/ReconnectingNotice.d.ts.map +1 -0
- package/dist/components/reconnecting-overlay/ReconnectingOverlay.d.ts +3 -0
- package/dist/components/reconnecting-overlay/ReconnectingOverlay.d.ts.map +1 -1
- package/dist/components/recording-history/RecordingHistoryPanel.d.ts +62 -0
- package/dist/components/recording-history/RecordingHistoryPanel.d.ts.map +1 -0
- package/dist/components/space-header/LayoutMenu.d.ts +1 -499
- package/dist/components/space-header/LayoutMenu.d.ts.map +1 -1
- package/dist/components/space-info-dialog/SpaceInfoContent.d.ts.map +1 -1
- package/dist/components/space-view/ClassicSpaceView.d.ts +1 -1
- package/dist/components/space-view/ClassicSpaceView.d.ts.map +1 -1
- package/dist/components/space-view/RecordingSpaceView.d.ts +26 -0
- package/dist/components/space-view/RecordingSpaceView.d.ts.map +1 -0
- package/dist/components/space-view/SpaceDrawer.d.ts +3 -2
- package/dist/components/space-view/SpaceDrawer.d.ts.map +1 -1
- package/dist/components/space-view/SpacePresentation.d.ts +27 -0
- package/dist/components/space-view/SpacePresentation.d.ts.map +1 -0
- package/dist/components/space-view/SpaceStage.d.ts.map +1 -1
- package/dist/components/space-view/SpaceView.d.ts +2 -0
- package/dist/components/space-view/SpaceView.d.ts.map +1 -1
- package/dist/components/stage/Stage.d.ts +22 -2
- package/dist/components/stage/Stage.d.ts.map +1 -1
- package/dist/components/stage/StageContentTile.d.ts +5 -0
- package/dist/components/stage/StageContentTile.d.ts.map +1 -1
- package/dist/components/stage/StagePager.d.ts +2 -1
- package/dist/components/stage/StagePager.d.ts.map +1 -1
- package/dist/components/stage/stage-items.d.ts +0 -1
- package/dist/components/stage/stage-items.d.ts.map +1 -1
- package/dist/components/transcript-panel/ClassicTranscriptPanel.d.ts +1 -1
- package/dist/components/transcript-panel/ClassicTranscriptPanel.d.ts.map +1 -1
- package/dist/components/transcript-panel/TranscriptPanel.d.ts +2 -25
- package/dist/components/transcript-panel/TranscriptPanel.d.ts.map +1 -1
- package/dist/components/transcript-panel/transcript-panel-behavior.d.ts +84 -0
- package/dist/components/transcript-panel/transcript-panel-behavior.d.ts.map +1 -0
- package/dist/components/whiteboard-view/RecordingWhiteboardView.d.ts +23 -0
- package/dist/components/whiteboard-view/RecordingWhiteboardView.d.ts.map +1 -0
- package/dist/components/whiteboard-view/recording-whiteboard-state.d.ts +31 -0
- package/dist/components/whiteboard-view/recording-whiteboard-state.d.ts.map +1 -0
- package/dist/headless.d.ts +8 -0
- package/dist/headless.d.ts.map +1 -0
- package/dist/headless.js +28 -0
- package/dist/index.d.ts +9 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +32 -4
- package/dist/internal/useWhiteboardSceneSubscription.d.ts.map +1 -1
- package/dist/public-surface.contract.d.ts +2 -2
- package/dist/public-surface.contract.d.ts.map +1 -1
- package/dist/selectors/space-selectors.d.ts.map +1 -1
- package/dist/test-support/index.d.ts +20 -0
- package/dist/test-support/index.d.ts.map +1 -0
- package/dist/test-support/index.js +508 -0
- package/dist/test-support/preview-client.d.ts +5 -0
- package/dist/test-support/preview-client.d.ts.map +1 -1
- package/dist/test-support/preview-feedback.d.ts +3 -0
- package/dist/test-support/preview-feedback.d.ts.map +1 -0
- package/dist/utils/animated-icon-renderer.d.ts +6 -0
- package/dist/utils/animated-icon-renderer.d.ts.map +1 -0
- package/dist/utils/animated-icon-runtime.d.ts +19 -0
- package/dist/utils/animated-icon-runtime.d.ts.map +1 -0
- package/dist/utils/animated-icons/arrow-left-02.d.ts +11 -0
- package/dist/utils/animated-icons/arrow-left-02.d.ts.map +1 -0
- package/dist/utils/animated-icons/cancel-01.d.ts +11 -0
- package/dist/utils/animated-icons/cancel-01.d.ts.map +1 -0
- package/dist/utils/animated-icons/clock-01.d.ts +11 -0
- package/dist/utils/animated-icons/clock-01.d.ts.map +1 -0
- package/dist/utils/animated-icons/copy-01.d.ts +13 -0
- package/dist/utils/animated-icons/copy-01.d.ts.map +1 -0
- package/dist/utils/animated-icons/crown.d.ts +11 -0
- package/dist/utils/animated-icons/crown.d.ts.map +1 -0
- package/dist/utils/animated-icons/download-01.d.ts +11 -0
- package/dist/utils/animated-icons/download-01.d.ts.map +1 -0
- package/dist/utils/animated-icons/edit-02.d.ts +11 -0
- package/dist/utils/animated-icons/edit-02.d.ts.map +1 -0
- package/dist/utils/animated-icons/home-01.d.ts +11 -0
- package/dist/utils/animated-icons/home-01.d.ts.map +1 -0
- package/dist/utils/animated-icons/image-01.d.ts +13 -0
- package/dist/utils/animated-icons/image-01.d.ts.map +1 -0
- package/dist/utils/animated-icons/index.d.ts +85 -0
- package/dist/utils/animated-icons/index.d.ts.map +1 -0
- package/dist/utils/animated-icons/information-circle.d.ts +11 -0
- package/dist/utils/animated-icons/information-circle.d.ts.map +1 -0
- package/dist/utils/animated-icons/link-01.d.ts +11 -0
- package/dist/utils/animated-icons/link-01.d.ts.map +1 -0
- package/dist/utils/animated-icons/mail-01.d.ts +11 -0
- package/dist/utils/animated-icons/mail-01.d.ts.map +1 -0
- package/dist/utils/animated-icons/maximize-screen.d.ts +11 -0
- package/dist/utils/animated-icons/maximize-screen.d.ts.map +1 -0
- package/dist/utils/animated-icons/message-01.d.ts +11 -0
- package/dist/utils/animated-icons/message-01.d.ts.map +1 -0
- package/dist/utils/animated-icons/mic-01.d.ts +11 -0
- package/dist/utils/animated-icons/mic-01.d.ts.map +1 -0
- package/dist/utils/animated-icons/moon-02.d.ts +11 -0
- package/dist/utils/animated-icons/moon-02.d.ts.map +1 -0
- package/dist/utils/animated-icons/more-horizontal.d.ts +11 -0
- package/dist/utils/animated-icons/more-horizontal.d.ts.map +1 -0
- package/dist/utils/animated-icons/more-vertical.d.ts +11 -0
- package/dist/utils/animated-icons/more-vertical.d.ts.map +1 -0
- package/dist/utils/animated-icons/pause.d.ts +11 -0
- package/dist/utils/animated-icons/pause.d.ts.map +1 -0
- package/dist/utils/animated-icons/pin.d.ts +11 -0
- package/dist/utils/animated-icons/pin.d.ts.map +1 -0
- package/dist/utils/animated-icons/play.d.ts +11 -0
- package/dist/utils/animated-icons/play.d.ts.map +1 -0
- package/dist/utils/animated-icons/plus-sign.d.ts +11 -0
- package/dist/utils/animated-icons/plus-sign.d.ts.map +1 -0
- package/dist/utils/animated-icons/qr-code-01.d.ts +11 -0
- package/dist/utils/animated-icons/qr-code-01.d.ts.map +1 -0
- package/dist/utils/animated-icons/refresh.d.ts +11 -0
- package/dist/utils/animated-icons/refresh.d.ts.map +1 -0
- package/dist/utils/animated-icons/search-01.d.ts +11 -0
- package/dist/utils/animated-icons/search-01.d.ts.map +1 -0
- package/dist/utils/animated-icons/sent.d.ts +11 -0
- package/dist/utils/animated-icons/sent.d.ts.map +1 -0
- package/dist/utils/animated-icons/settings-01.d.ts +11 -0
- package/dist/utils/animated-icons/settings-01.d.ts.map +1 -0
- package/dist/utils/animated-icons/share-08.d.ts +11 -0
- package/dist/utils/animated-icons/share-08.d.ts.map +1 -0
- package/dist/utils/animated-icons/shield-02.d.ts +11 -0
- package/dist/utils/animated-icons/shield-02.d.ts.map +1 -0
- package/dist/utils/animated-icons/smile.d.ts +11 -0
- package/dist/utils/animated-icons/smile.d.ts.map +1 -0
- package/dist/utils/animated-icons/sparkles.d.ts +11 -0
- package/dist/utils/animated-icons/sparkles.d.ts.map +1 -0
- package/dist/utils/animated-icons/star.d.ts +11 -0
- package/dist/utils/animated-icons/star.d.ts.map +1 -0
- package/dist/utils/animated-icons/thumbs-up.d.ts +11 -0
- package/dist/utils/animated-icons/thumbs-up.d.ts.map +1 -0
- package/dist/utils/animated-icons/upload-01.d.ts +11 -0
- package/dist/utils/animated-icons/upload-01.d.ts.map +1 -0
- package/dist/utils/animated-icons/user-add-01.d.ts +11 -0
- package/dist/utils/animated-icons/user-add-01.d.ts.map +1 -0
- package/dist/utils/animated-icons/user-group.d.ts +11 -0
- package/dist/utils/animated-icons/user-group.d.ts.map +1 -0
- package/dist/utils/animated-icons/user-remove-01.d.ts +11 -0
- package/dist/utils/animated-icons/user-remove-01.d.ts.map +1 -0
- package/dist/utils/animated-icons/video-01.d.ts +11 -0
- package/dist/utils/animated-icons/video-01.d.ts.map +1 -0
- package/dist/utils/animated-icons/volume-high.d.ts +11 -0
- package/dist/utils/animated-icons/volume-high.d.ts.map +1 -0
- package/dist/utils/animated-icons/volume-mute-01.d.ts +11 -0
- package/dist/utils/animated-icons/volume-mute-01.d.ts.map +1 -0
- package/dist/utils/animated-icons/zoom-in-area.d.ts +11 -0
- package/dist/utils/animated-icons/zoom-in-area.d.ts.map +1 -0
- package/dist/utils/animated-icons/zoom-out-area.d.ts +11 -0
- package/dist/utils/animated-icons/zoom-out-area.d.ts.map +1 -0
- package/dist/utils/feedback.d.ts +5 -0
- package/dist/utils/feedback.d.ts.map +1 -0
- package/dist/utils/icons.d.ts +42 -42
- package/dist/utils/icons.d.ts.map +1 -1
- package/dist/utils/index.d.ts +5 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +297 -1
- package/package.json +25 -8
- package/dist/chunk-A3L7BOCE.js +0 -210
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
// src/utils/feedback.ts
|
|
2
|
+
import { domToJpeg } from "modern-screenshot";
|
|
3
|
+
var MAX_SCREENSHOT_BYTES = 450 * 1024;
|
|
4
|
+
var MAX_SCREENSHOT_WIDTH = 1920;
|
|
5
|
+
var MAX_SCREENSHOT_HEIGHT = 1080;
|
|
6
|
+
var SAFE_COOKIE_NAMES = /* @__PURE__ */ new Set(["chalk_theme", "chalk_sidebar_state", "account", "csrf", "__Host-chalk_account", "chalk_account_local", "__Host-chalk_csrf", "chalk_csrf_local"]);
|
|
7
|
+
var ACCOUNT_COOKIE_NAMES = ["account", "__Host-chalk_account", "chalk_account_local"];
|
|
8
|
+
var CSRF_COOKIE_NAMES = ["csrf", "__Host-chalk_csrf", "chalk_csrf_local"];
|
|
9
|
+
function collectBrowserFeedbackEvidence() {
|
|
10
|
+
const tenantHint = readTenantHint();
|
|
11
|
+
const telemetry = readTelemetrySummary();
|
|
12
|
+
const dashboardRequests = readDashboardRequests();
|
|
13
|
+
return {
|
|
14
|
+
sdk: { client: "@q9labsai/chalk-client", react: "@q9labsai/chalk-react" },
|
|
15
|
+
platform: { kind: "web", ...browserMetadata() },
|
|
16
|
+
local_state: {
|
|
17
|
+
...tenantHint ? { tenant_hint: tenantHint } : {},
|
|
18
|
+
...telemetry ? { telemetry } : {},
|
|
19
|
+
...dashboardRequests.length > 0 ? { dashboard_requests: dashboardRequests } : {}
|
|
20
|
+
},
|
|
21
|
+
cookies: readFeedbackCookies()
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
async function captureFeedbackScreenshot(root) {
|
|
25
|
+
if (!root || typeof window === "undefined") return { state: "unavailable", failure_code: "unsupported" };
|
|
26
|
+
try {
|
|
27
|
+
const bounds = root.getBoundingClientRect();
|
|
28
|
+
const width = Math.round(bounds.width);
|
|
29
|
+
const height = Math.round(bounds.height);
|
|
30
|
+
if (width <= 0 || height <= 0) return { state: "unavailable", failure_code: "unsupported" };
|
|
31
|
+
const dataUrl = await domToJpeg(root, {
|
|
32
|
+
quality: 0.78,
|
|
33
|
+
width: Math.min(width, MAX_SCREENSHOT_WIDTH),
|
|
34
|
+
height: Math.min(height, MAX_SCREENSHOT_HEIGHT),
|
|
35
|
+
filter: (node) => !(node instanceof Element && Boolean(node.closest("[data-chalk-feedback-private], [data-chalk-host-content]")))
|
|
36
|
+
});
|
|
37
|
+
const separator = dataUrl.indexOf(",");
|
|
38
|
+
if (separator < 0) return { state: "unavailable", failure_code: "capture_failed" };
|
|
39
|
+
const encoded = dataUrl.slice(separator + 1);
|
|
40
|
+
if (encoded.length * 0.75 > MAX_SCREENSHOT_BYTES) return { state: "unavailable", failure_code: "too_large" };
|
|
41
|
+
return {
|
|
42
|
+
state: "captured",
|
|
43
|
+
mime_type: "image/jpeg",
|
|
44
|
+
width: Math.min(width, MAX_SCREENSHOT_WIDTH),
|
|
45
|
+
height: Math.min(height, MAX_SCREENSHOT_HEIGHT),
|
|
46
|
+
captured_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
47
|
+
data_base64: encoded
|
|
48
|
+
};
|
|
49
|
+
} catch {
|
|
50
|
+
return { state: "unavailable", failure_code: "capture_failed" };
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function browserMetadata() {
|
|
54
|
+
if (typeof navigator === "undefined") return {};
|
|
55
|
+
return {
|
|
56
|
+
browser_name: browserName(navigator.userAgent),
|
|
57
|
+
device_class: typeof window !== "undefined" && window.matchMedia?.("(pointer: coarse)").matches ? "phone" : "desktop"
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
function browserName(userAgent) {
|
|
61
|
+
if (/edg\//iu.test(userAgent)) return "Edge";
|
|
62
|
+
if (/firefox\//iu.test(userAgent)) return "Firefox";
|
|
63
|
+
if (/chrome\//iu.test(userAgent)) return "Chrome";
|
|
64
|
+
if (/safari\//iu.test(userAgent)) return "Safari";
|
|
65
|
+
return void 0;
|
|
66
|
+
}
|
|
67
|
+
function readTenantHint() {
|
|
68
|
+
try {
|
|
69
|
+
const value = window.localStorage.getItem("chalk.tenant-hint") ?? void 0;
|
|
70
|
+
return value && /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/iu.test(value) ? value : void 0;
|
|
71
|
+
} catch {
|
|
72
|
+
return void 0;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
function readTelemetrySummary() {
|
|
76
|
+
try {
|
|
77
|
+
let pendingCount = 0;
|
|
78
|
+
let found = false;
|
|
79
|
+
for (let index = 0; index < window.localStorage.length; index += 1) {
|
|
80
|
+
const key = window.localStorage.key(index);
|
|
81
|
+
if (key !== "chalk.web.telemetry.v1" && !key?.startsWith("chalk.web.telemetry.v1.")) continue;
|
|
82
|
+
const raw = key ? window.localStorage.getItem(key) : null;
|
|
83
|
+
if (!raw) continue;
|
|
84
|
+
const value = JSON.parse(raw);
|
|
85
|
+
if (!Array.isArray(value)) continue;
|
|
86
|
+
found = true;
|
|
87
|
+
pendingCount = Math.min(500, pendingCount + value.length);
|
|
88
|
+
}
|
|
89
|
+
return found ? { storage_key: "chalk.web.telemetry.v1", pending_count: pendingCount } : void 0;
|
|
90
|
+
} catch {
|
|
91
|
+
return void 0;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
function readDashboardRequests() {
|
|
95
|
+
try {
|
|
96
|
+
const requests = [];
|
|
97
|
+
for (let index = 0; index < window.localStorage.length; index += 1) {
|
|
98
|
+
const key = window.localStorage.key(index);
|
|
99
|
+
if (!key?.startsWith("chalk.dashboard-request.")) continue;
|
|
100
|
+
const action = key.slice("chalk.dashboard-request.".length);
|
|
101
|
+
if (!/^[a-z][a-z0-9_-]{0,63}$/u.test(action)) continue;
|
|
102
|
+
requests.push({ action, pending: true });
|
|
103
|
+
}
|
|
104
|
+
return requests.slice(0, 32);
|
|
105
|
+
} catch {
|
|
106
|
+
return [];
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
function readFeedbackCookies() {
|
|
110
|
+
if (typeof document === "undefined") return {};
|
|
111
|
+
const values = /* @__PURE__ */ new Map();
|
|
112
|
+
for (const item of document.cookie.split(";")) {
|
|
113
|
+
const separator = item.indexOf("=");
|
|
114
|
+
if (separator < 0) continue;
|
|
115
|
+
const name = item.slice(0, separator).trim();
|
|
116
|
+
if (SAFE_COOKIE_NAMES.has(name)) values.set(name, item.slice(separator + 1));
|
|
117
|
+
}
|
|
118
|
+
const theme = values.get("chalk_theme");
|
|
119
|
+
const sidebarState = values.get("chalk_sidebar_state");
|
|
120
|
+
return {
|
|
121
|
+
...theme === "light" || theme === "dark" || theme === "system" ? { theme } : {},
|
|
122
|
+
...sidebarState === "true" || sidebarState === "false" ? { sidebar_state: sidebarState === "true" } : {},
|
|
123
|
+
account_present: ACCOUNT_COOKIE_NAMES.some((name) => values.has(name)),
|
|
124
|
+
csrf_present: CSRF_COOKIE_NAMES.some((name) => values.has(name))
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export {
|
|
129
|
+
collectBrowserFeedbackEvidence,
|
|
130
|
+
captureFeedbackScreenshot
|
|
131
|
+
};
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
// src/components/whiteboard-view/recording-whiteboard-state.ts
|
|
2
|
+
var RECORDING_WHITEBOARD_STATE_KEYS = ["schemaVersion", "sceneId", "revision", "appState", "elements"];
|
|
3
|
+
var RECORDING_WHITEBOARD_APP_STATE_KEYS = ["view_background_color"];
|
|
4
|
+
var WHITEBOARD_WIRE_ELEMENT_KEYS = ["id", "type", "version", "version_nonce", "index", "is_deleted", "payload"];
|
|
5
|
+
var MAX_VIEW_BACKGROUND_COLOR_BYTES = 64;
|
|
6
|
+
var EXCALIDRAW_FILE_MIME_TYPES = /* @__PURE__ */ new Set(["image/svg+xml", "image/png", "image/jpeg", "image/gif", "image/webp", "image/bmp", "image/x-icon", "image/avif", "image/jfif", "application/octet-stream"]);
|
|
7
|
+
function parseRecordingWhiteboardStateV1(value) {
|
|
8
|
+
if (!isRecordingWhiteboardStateInput(value)) throw invalidState();
|
|
9
|
+
if (value.schemaVersion !== "recording_whiteboard_state.v1" || !isNonEmptyString(value.sceneId) || !isNonNegativeSafeInteger(value.revision)) throw invalidState();
|
|
10
|
+
const appState = parseRecordingWhiteboardAppState(value.appState);
|
|
11
|
+
if (!Array.isArray(value.elements) || !value.elements.every(isWhiteboardWireElement)) throw invalidState();
|
|
12
|
+
if (!isCanonicalElementOrder(value.elements)) throw new TypeError("recording whiteboard elements are not in canonical order");
|
|
13
|
+
return Object.freeze({
|
|
14
|
+
schemaVersion: value.schemaVersion,
|
|
15
|
+
sceneId: value.sceneId,
|
|
16
|
+
revision: value.revision,
|
|
17
|
+
appState,
|
|
18
|
+
elements: Object.freeze([...value.elements])
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
function recordingWhiteboardFileIds(state) {
|
|
22
|
+
const ids = /* @__PURE__ */ new Set();
|
|
23
|
+
for (const element of state.elements) {
|
|
24
|
+
if (element.is_deleted) continue;
|
|
25
|
+
const fileId = element.payload.fileId;
|
|
26
|
+
if (isNonEmptyString(fileId)) ids.add(fileId);
|
|
27
|
+
}
|
|
28
|
+
return Object.freeze([...ids].sort());
|
|
29
|
+
}
|
|
30
|
+
function recordingWhiteboardFileAssetId(fileId) {
|
|
31
|
+
if (!isNonEmptyString(fileId)) throw new TypeError("recording whiteboard file id is invalid");
|
|
32
|
+
return `whiteboard_file:${fileId}`;
|
|
33
|
+
}
|
|
34
|
+
function recordingWhiteboardSceneAppState(state, defaultViewBackgroundColor) {
|
|
35
|
+
return Object.freeze({ viewBackgroundColor: state.appState.view_background_color ?? defaultViewBackgroundColor });
|
|
36
|
+
}
|
|
37
|
+
function recordingWhiteboardBinaryFile({ fileId, mimeType, dataURL, createdAtMs = 0 }) {
|
|
38
|
+
if (!isRecordingWhiteboardFileId(fileId) || !isNonNegativeSafeInteger(createdAtMs)) throw new TypeError("recording whiteboard file is invalid");
|
|
39
|
+
const normalizedMimeType = normalizedFileMimeType(mimeType);
|
|
40
|
+
if (!isRecordingWhiteboardDataURL(dataURL, normalizedMimeType)) throw new TypeError("recording whiteboard file data URL is invalid");
|
|
41
|
+
return Object.freeze({ id: fileId, mimeType: normalizedMimeType, dataURL, created: createdAtMs });
|
|
42
|
+
}
|
|
43
|
+
async function loadRecordingWhiteboardFiles(state, resolve) {
|
|
44
|
+
const pairs = await Promise.all(
|
|
45
|
+
recordingWhiteboardFileIds(state).map(async (fileId) => {
|
|
46
|
+
const source = await resolve(Object.freeze({ fileId, assetId: recordingWhiteboardFileAssetId(fileId) }));
|
|
47
|
+
return [fileId, recordingWhiteboardBinaryFile({ fileId, ...source })];
|
|
48
|
+
})
|
|
49
|
+
);
|
|
50
|
+
const files = {};
|
|
51
|
+
for (const [fileId, file] of pairs) files[fileId] = file;
|
|
52
|
+
return Object.freeze(files);
|
|
53
|
+
}
|
|
54
|
+
function isRecordingWhiteboardStateInput(value) {
|
|
55
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
56
|
+
return hasExactKeys(value, RECORDING_WHITEBOARD_STATE_KEYS);
|
|
57
|
+
}
|
|
58
|
+
function isWhiteboardWireElement(value) {
|
|
59
|
+
if (!isWhiteboardWireElementInput(value)) return false;
|
|
60
|
+
return isNonEmptyString(value.id) && isNonEmptyString(value.type) && isNonNegativeSafeInteger(value.version) && isNonNegativeSafeInteger(value.version_nonce) && isNonEmptyString(value.index) && typeof value.is_deleted === "boolean" && isWhiteboardElementPayload(value.payload);
|
|
61
|
+
}
|
|
62
|
+
function isWhiteboardWireElementInput(value) {
|
|
63
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
64
|
+
return hasExactKeys(value, WHITEBOARD_WIRE_ELEMENT_KEYS);
|
|
65
|
+
}
|
|
66
|
+
function hasExactKeys(value, keys) {
|
|
67
|
+
const actual = Object.keys(value);
|
|
68
|
+
return actual.length === keys.length && keys.every((key) => Object.hasOwn(value, key));
|
|
69
|
+
}
|
|
70
|
+
function isCanonicalElementOrder(elements) {
|
|
71
|
+
let previous;
|
|
72
|
+
for (const current of elements) {
|
|
73
|
+
if (previous === void 0) {
|
|
74
|
+
previous = current;
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
if (previous.index > current.index || previous.index === current.index && previous.id > current.id) return false;
|
|
78
|
+
previous = current;
|
|
79
|
+
}
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
function parseRecordingWhiteboardAppState(value) {
|
|
83
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) throw invalidState();
|
|
84
|
+
const keys = Object.keys(value);
|
|
85
|
+
if (keys.length === 0) return Object.freeze({});
|
|
86
|
+
if (!hasExactKeys(value, RECORDING_WHITEBOARD_APP_STATE_KEYS) || !("view_background_color" in value) || !isViewBackgroundColor(value.view_background_color)) throw invalidState();
|
|
87
|
+
return Object.freeze({ view_background_color: value.view_background_color });
|
|
88
|
+
}
|
|
89
|
+
function isNonEmptyString(value) {
|
|
90
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
91
|
+
}
|
|
92
|
+
function isNonNegativeSafeInteger(value) {
|
|
93
|
+
return typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
|
|
94
|
+
}
|
|
95
|
+
function normalizedFileMimeType(value) {
|
|
96
|
+
const [rawMimeType] = value.split(";", 1);
|
|
97
|
+
const mimeType = rawMimeType?.trim().toLowerCase();
|
|
98
|
+
if (!mimeType || !isRecordingWhiteboardFileMimeType(mimeType)) throw new TypeError("recording whiteboard file MIME type is unsupported");
|
|
99
|
+
return mimeType;
|
|
100
|
+
}
|
|
101
|
+
function isRecordingWhiteboardDataURL(value, mimeType) {
|
|
102
|
+
if (!value.startsWith("data:") || !value.includes(",")) return false;
|
|
103
|
+
const encodedMimeType = value.slice(5, value.indexOf(",")).split(";", 1)[0]?.trim().toLowerCase();
|
|
104
|
+
return encodedMimeType === mimeType;
|
|
105
|
+
}
|
|
106
|
+
function isRecordingWhiteboardFileId(value) {
|
|
107
|
+
return isNonEmptyString(value);
|
|
108
|
+
}
|
|
109
|
+
function isRecordingWhiteboardFileMimeType(value) {
|
|
110
|
+
return EXCALIDRAW_FILE_MIME_TYPES.has(value);
|
|
111
|
+
}
|
|
112
|
+
function isViewBackgroundColor(value) {
|
|
113
|
+
return typeof value === "string" && new TextEncoder().encode(value).byteLength <= MAX_VIEW_BACKGROUND_COLOR_BYTES;
|
|
114
|
+
}
|
|
115
|
+
function isWhiteboardElementPayload(value) {
|
|
116
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
117
|
+
return Object.values(value).every((item) => isWhiteboardJsonValue(item, 0));
|
|
118
|
+
}
|
|
119
|
+
function isWhiteboardJsonValue(value, depth) {
|
|
120
|
+
if (depth > 16) return false;
|
|
121
|
+
if (value === null || typeof value === "boolean" || typeof value === "string") return true;
|
|
122
|
+
if (typeof value === "number") return Number.isFinite(value);
|
|
123
|
+
if (Array.isArray(value)) return value.every((item) => isWhiteboardJsonValue(item, depth + 1));
|
|
124
|
+
if (typeof value !== "object") return false;
|
|
125
|
+
return Object.values(value).every((item) => isWhiteboardJsonValue(item, depth + 1));
|
|
126
|
+
}
|
|
127
|
+
function invalidState() {
|
|
128
|
+
return new TypeError("recording whiteboard state is invalid");
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export {
|
|
132
|
+
parseRecordingWhiteboardStateV1,
|
|
133
|
+
recordingWhiteboardFileIds,
|
|
134
|
+
recordingWhiteboardFileAssetId,
|
|
135
|
+
recordingWhiteboardSceneAppState,
|
|
136
|
+
recordingWhiteboardBinaryFile,
|
|
137
|
+
loadRecordingWhiteboardFiles
|
|
138
|
+
};
|