@diegotsi/flint-react 0.5.1 → 1.0.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/dist/index.cjs +618 -667
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +38 -8
- package/dist/index.d.ts +38 -8
- package/dist/index.js +603 -662
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
// src/FlintWidget.tsx
|
|
2
|
-
import { useState as useState3, useEffect as useEffect3, useRef as useRef3, useCallback as useCallback2 } from "react";
|
|
3
|
-
import { I18nextProvider, useTranslation as useTranslation2 } from "react-i18next";
|
|
4
|
-
|
|
5
1
|
// src/FlintModal.tsx
|
|
6
|
-
import {
|
|
2
|
+
import { useCallback, useEffect as useEffect2, useRef as useRef2, useState as useState2 } from "react";
|
|
7
3
|
import { useTranslation } from "react-i18next";
|
|
8
4
|
|
|
5
|
+
// src/api.ts
|
|
6
|
+
import { submitReplay, submitReport } from "@flint/core";
|
|
7
|
+
|
|
9
8
|
// src/ScreenAnnotator.tsx
|
|
10
|
-
import { useEffect, useRef, useState } from "react";
|
|
11
9
|
import { domToCanvas } from "modern-screenshot";
|
|
10
|
+
import { useEffect, useRef, useState } from "react";
|
|
12
11
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
13
12
|
function normalizeRect(startX, startY, endX, endY) {
|
|
14
13
|
return {
|
|
@@ -53,9 +52,7 @@ function ScreenAnnotator({ zIndex, onCapture, onCancel }) {
|
|
|
53
52
|
const dpr = window.devicePixelRatio ?? 1;
|
|
54
53
|
const vw = window.innerWidth;
|
|
55
54
|
const vh = window.innerHeight;
|
|
56
|
-
await new Promise(
|
|
57
|
-
(resolve) => requestAnimationFrame(() => requestAnimationFrame(() => resolve()))
|
|
58
|
-
);
|
|
55
|
+
await new Promise((resolve) => requestAnimationFrame(() => requestAnimationFrame(() => resolve())));
|
|
59
56
|
try {
|
|
60
57
|
const fullCanvas = await domToCanvas(document.documentElement, {
|
|
61
58
|
scale: dpr,
|
|
@@ -70,17 +67,7 @@ function ScreenAnnotator({ zIndex, onCapture, onCancel }) {
|
|
|
70
67
|
canvas.width = vw * dpr;
|
|
71
68
|
canvas.height = vh * dpr;
|
|
72
69
|
const ctx = canvas.getContext("2d");
|
|
73
|
-
ctx.drawImage(
|
|
74
|
-
fullCanvas,
|
|
75
|
-
0,
|
|
76
|
-
0,
|
|
77
|
-
vw * dpr,
|
|
78
|
-
vh * dpr,
|
|
79
|
-
0,
|
|
80
|
-
0,
|
|
81
|
-
vw * dpr,
|
|
82
|
-
vh * dpr
|
|
83
|
-
);
|
|
70
|
+
ctx.drawImage(fullCanvas, 0, 0, vw * dpr, vh * dpr, 0, 0, vw * dpr, vh * dpr);
|
|
84
71
|
ctx.fillStyle = "rgba(255,200,0,0.25)";
|
|
85
72
|
ctx.fillRect(finalRect.x * dpr, finalRect.y * dpr, finalRect.w * dpr, finalRect.h * dpr);
|
|
86
73
|
ctx.strokeStyle = "#f97316";
|
|
@@ -118,123 +105,50 @@ function ScreenAnnotator({ zIndex, onCapture, onCancel }) {
|
|
|
118
105
|
pointerEvents: isCapturing ? "none" : "auto"
|
|
119
106
|
},
|
|
120
107
|
children: [
|
|
121
|
-
!isCapturing && /* @__PURE__ */ jsx(
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
108
|
+
!isCapturing && /* @__PURE__ */ jsx(
|
|
109
|
+
"div",
|
|
110
|
+
{
|
|
111
|
+
style: {
|
|
112
|
+
position: "absolute",
|
|
113
|
+
top: 16,
|
|
114
|
+
left: "50%",
|
|
115
|
+
transform: "translateX(-50%)",
|
|
116
|
+
background: "rgba(0,0,0,0.75)",
|
|
117
|
+
color: "#fff",
|
|
118
|
+
padding: "8px 18px",
|
|
119
|
+
borderRadius: 8,
|
|
120
|
+
fontSize: 14,
|
|
121
|
+
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',
|
|
122
|
+
pointerEvents: "none",
|
|
123
|
+
whiteSpace: "nowrap",
|
|
124
|
+
backdropFilter: "blur(4px)"
|
|
125
|
+
},
|
|
126
|
+
children: "Drag to highlight the problem area \xA0\xB7\xA0 Esc to cancel"
|
|
127
|
+
}
|
|
128
|
+
),
|
|
129
|
+
rect && phase === "selecting" && /* @__PURE__ */ jsx(
|
|
130
|
+
"div",
|
|
131
|
+
{
|
|
132
|
+
style: {
|
|
133
|
+
position: "absolute",
|
|
134
|
+
left: rect.x,
|
|
135
|
+
top: rect.y,
|
|
136
|
+
width: rect.w,
|
|
137
|
+
height: rect.h,
|
|
138
|
+
background: "rgba(255,200,0,0.2)",
|
|
139
|
+
border: "2px dashed #f97316",
|
|
140
|
+
boxSizing: "border-box",
|
|
141
|
+
pointerEvents: "none"
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
)
|
|
147
145
|
]
|
|
148
146
|
}
|
|
149
147
|
);
|
|
150
148
|
}
|
|
151
149
|
|
|
152
|
-
// src/api.ts
|
|
153
|
-
import { gzipSync } from "fflate";
|
|
154
|
-
async function submitReport(serverUrl, projectKey, payload, screenshot) {
|
|
155
|
-
const url = `${serverUrl.replace(/\/$/, "")}/api/v1/bug-reports`;
|
|
156
|
-
let body;
|
|
157
|
-
let headers = {
|
|
158
|
-
"x-project-key": projectKey
|
|
159
|
-
};
|
|
160
|
-
if (screenshot) {
|
|
161
|
-
const form = new FormData();
|
|
162
|
-
form.append("reporterId", payload.reporterId);
|
|
163
|
-
form.append("reporterName", payload.reporterName);
|
|
164
|
-
form.append("description", payload.description);
|
|
165
|
-
if (payload.expectedBehavior) form.append("expectedBehavior", payload.expectedBehavior);
|
|
166
|
-
if (payload.stepsToReproduce) form.append("stepsToReproduce", JSON.stringify(payload.stepsToReproduce));
|
|
167
|
-
if (payload.externalReplayUrl) form.append("externalReplayUrl", payload.externalReplayUrl);
|
|
168
|
-
if (payload.additionalContext) form.append("additionalContext", payload.additionalContext);
|
|
169
|
-
form.append("severity", payload.severity);
|
|
170
|
-
if (payload.url) form.append("url", payload.url);
|
|
171
|
-
if (payload.meta) form.append("meta", JSON.stringify(payload.meta));
|
|
172
|
-
form.append("screenshot", screenshot);
|
|
173
|
-
body = form;
|
|
174
|
-
} else {
|
|
175
|
-
body = JSON.stringify(payload);
|
|
176
|
-
headers["Content-Type"] = "application/json";
|
|
177
|
-
}
|
|
178
|
-
const res = await fetch(url, { method: "POST", headers, body });
|
|
179
|
-
if (!res.ok) {
|
|
180
|
-
const err = await res.json().catch(() => ({ error: "Unknown error" }));
|
|
181
|
-
throw new Error(err.error ?? `HTTP ${res.status}`);
|
|
182
|
-
}
|
|
183
|
-
return res.json();
|
|
184
|
-
}
|
|
185
|
-
async function submitReplay(serverUrl, projectKey, reportId, events) {
|
|
186
|
-
const json = JSON.stringify(events);
|
|
187
|
-
const encoded = new TextEncoder().encode(json);
|
|
188
|
-
const compressed = gzipSync(encoded);
|
|
189
|
-
const url = `${serverUrl.replace(/\/$/, "")}/api/v1/bug-reports/${reportId}/replay`;
|
|
190
|
-
await fetch(url, {
|
|
191
|
-
method: "POST",
|
|
192
|
-
headers: {
|
|
193
|
-
"x-project-key": projectKey,
|
|
194
|
-
"Content-Type": "application/octet-stream"
|
|
195
|
-
},
|
|
196
|
-
body: compressed.buffer
|
|
197
|
-
});
|
|
198
|
-
}
|
|
199
|
-
|
|
200
150
|
// src/theme.ts
|
|
201
|
-
|
|
202
|
-
background: "rgba(255,255,255,0.90)",
|
|
203
|
-
backgroundSecondary: "rgba(249,250,251,0.75)",
|
|
204
|
-
accent: "#2563eb",
|
|
205
|
-
accentHover: "#1d4ed8",
|
|
206
|
-
text: "#111827",
|
|
207
|
-
textMuted: "#6b7280",
|
|
208
|
-
border: "rgba(255,255,255,0.9)",
|
|
209
|
-
shadow: "0 32px 80px rgba(0,0,0,0.18), 0 8px 32px rgba(0,0,0,0.1), 0 0 0 1px rgba(0,0,0,0.04)",
|
|
210
|
-
buttonText: "#ffffff",
|
|
211
|
-
backdropFilter: "blur(32px) saturate(1.8)"
|
|
212
|
-
};
|
|
213
|
-
var dark = {
|
|
214
|
-
background: "rgba(15,20,35,0.88)",
|
|
215
|
-
backgroundSecondary: "rgba(5,8,18,0.65)",
|
|
216
|
-
accent: "#f97316",
|
|
217
|
-
accentHover: "#ea6c0a",
|
|
218
|
-
text: "#dde3ef",
|
|
219
|
-
textMuted: "#6b7a93",
|
|
220
|
-
border: "rgba(255,255,255,0.08)",
|
|
221
|
-
shadow: "0 24px 60px rgba(0,0,0,0.6), 0 0 0 1px rgba(255,255,255,0.04)",
|
|
222
|
-
buttonText: "#ffffff",
|
|
223
|
-
backdropFilter: "blur(32px) saturate(1.6)"
|
|
224
|
-
};
|
|
225
|
-
function resolveTheme(theme) {
|
|
226
|
-
if (theme === "dark") return dark;
|
|
227
|
-
if (theme === "light") return light;
|
|
228
|
-
const override = theme;
|
|
229
|
-
return {
|
|
230
|
-
...light,
|
|
231
|
-
background: override.background ?? light.background,
|
|
232
|
-
accent: override.accent ?? light.accent,
|
|
233
|
-
accentHover: override.accent ?? light.accentHover,
|
|
234
|
-
text: override.text ?? light.text,
|
|
235
|
-
border: override.border ?? light.border
|
|
236
|
-
};
|
|
237
|
-
}
|
|
151
|
+
import { resolveTheme } from "@flint/core";
|
|
238
152
|
|
|
239
153
|
// src/FlintModal.tsx
|
|
240
154
|
import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
@@ -294,7 +208,12 @@ function FlintModal({
|
|
|
294
208
|
getNetworkErrors,
|
|
295
209
|
getReplayEvents,
|
|
296
210
|
getExternalReplayUrl,
|
|
297
|
-
initialSelection = ""
|
|
211
|
+
initialSelection = "",
|
|
212
|
+
enableScreenshot = true,
|
|
213
|
+
statusPageUrl,
|
|
214
|
+
onBeforeSubmit,
|
|
215
|
+
onSuccess,
|
|
216
|
+
onError
|
|
298
217
|
}) {
|
|
299
218
|
const { t } = useTranslation();
|
|
300
219
|
const colors = resolveTheme(theme);
|
|
@@ -354,33 +273,40 @@ function FlintModal({
|
|
|
354
273
|
lang: textLang
|
|
355
274
|
};
|
|
356
275
|
}
|
|
276
|
+
const payload = {
|
|
277
|
+
reporterId: user?.id ?? "anonymous",
|
|
278
|
+
reporterName: user?.name ?? "Anonymous",
|
|
279
|
+
reporterEmail: user?.email,
|
|
280
|
+
description: isText ? `[Text issue] "${textOriginal.trim()}" \u2192 "${textSuggested.trim()}"` : description.trim(),
|
|
281
|
+
expectedBehavior: !isText ? expectedBehavior.trim() || void 0 : void 0,
|
|
282
|
+
externalReplayUrl: getExternalReplayUrl() || void 0,
|
|
283
|
+
severity: isText ? "P3" : severity,
|
|
284
|
+
url: window.location.href,
|
|
285
|
+
meta: collectedMeta,
|
|
286
|
+
label: isText ? "TEXT" : void 0
|
|
287
|
+
};
|
|
288
|
+
if (onBeforeSubmit) {
|
|
289
|
+
const proceed = await onBeforeSubmit(payload);
|
|
290
|
+
if (!proceed) {
|
|
291
|
+
setStatus("idle");
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
357
295
|
try {
|
|
358
|
-
const res = await submitReport(
|
|
359
|
-
serverUrl,
|
|
360
|
-
projectKey,
|
|
361
|
-
{
|
|
362
|
-
reporterId: user?.id ?? "anonymous",
|
|
363
|
-
reporterName: user?.name ?? "Anonymous",
|
|
364
|
-
description: isText ? `[Text issue] "${textOriginal.trim()}" \u2192 "${textSuggested.trim()}"` : description.trim(),
|
|
365
|
-
expectedBehavior: !isText ? expectedBehavior.trim() || void 0 : void 0,
|
|
366
|
-
externalReplayUrl: getExternalReplayUrl() || void 0,
|
|
367
|
-
severity: isText ? "P3" : severity,
|
|
368
|
-
url: window.location.href,
|
|
369
|
-
meta: collectedMeta,
|
|
370
|
-
label: isText ? "TEXT" : void 0
|
|
371
|
-
},
|
|
372
|
-
!isText ? screenshot ?? void 0 : void 0
|
|
373
|
-
);
|
|
296
|
+
const res = await submitReport(serverUrl, projectKey, payload, !isText ? screenshot ?? void 0 : void 0);
|
|
374
297
|
setResult(res);
|
|
375
298
|
setStatus("success");
|
|
299
|
+
onSuccess?.(res);
|
|
376
300
|
const events = getReplayEvents();
|
|
377
301
|
if (events.length > 0) {
|
|
378
302
|
submitReplay(serverUrl, projectKey, res.id, events).catch(() => {
|
|
379
303
|
});
|
|
380
304
|
}
|
|
381
305
|
} catch (err) {
|
|
382
|
-
|
|
306
|
+
const error = err instanceof Error ? err : new Error(t("errorLabel"));
|
|
307
|
+
setErrorMsg(error.message);
|
|
383
308
|
setStatus("error");
|
|
309
|
+
onError?.(error);
|
|
384
310
|
}
|
|
385
311
|
};
|
|
386
312
|
const inputBorder = isDark ? "rgba(255,255,255,0.1)" : "rgba(0,0,0,0.1)";
|
|
@@ -430,157 +356,249 @@ function FlintModal({
|
|
|
430
356
|
const isSuccess = status === "success";
|
|
431
357
|
const ringBorder = isSuccess ? "3px solid #22c55e" : `3px solid ${isDark ? "rgba(255,255,255,0.08)" : "rgba(0,0,0,0.08)"}`;
|
|
432
358
|
const ringTopColor = isSuccess ? "#22c55e" : colors.accent;
|
|
433
|
-
return /* @__PURE__ */ jsx2("div", { style: overlayStyle, children: /* @__PURE__ */ jsxs2(
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
359
|
+
return /* @__PURE__ */ jsx2("div", { style: overlayStyle, children: /* @__PURE__ */ jsxs2(
|
|
360
|
+
"div",
|
|
361
|
+
{
|
|
362
|
+
style: modalStyle,
|
|
363
|
+
role: "dialog",
|
|
364
|
+
"aria-modal": "true",
|
|
365
|
+
"aria-label": isSuccess ? t("successTitle") : t("sending"),
|
|
366
|
+
children: [
|
|
367
|
+
/* @__PURE__ */ jsx2(ModalHeader, { colors, inputBorder, showClose: false, onClose }),
|
|
368
|
+
/* @__PURE__ */ jsxs2(
|
|
369
|
+
"div",
|
|
370
|
+
{
|
|
371
|
+
style: {
|
|
372
|
+
padding: "40px 32px 48px",
|
|
373
|
+
textAlign: "center",
|
|
374
|
+
display: "flex",
|
|
375
|
+
flexDirection: "column",
|
|
376
|
+
alignItems: "center"
|
|
377
|
+
},
|
|
378
|
+
children: [
|
|
379
|
+
/* @__PURE__ */ jsxs2("div", { style: { position: "relative", width: 80, height: 80, marginBottom: 28 }, children: [
|
|
380
|
+
/* @__PURE__ */ jsx2(
|
|
381
|
+
"div",
|
|
382
|
+
{
|
|
383
|
+
style: {
|
|
384
|
+
position: "absolute",
|
|
385
|
+
inset: -10,
|
|
386
|
+
borderRadius: "50%",
|
|
387
|
+
border: `1.5px solid ${colors.accent}`,
|
|
388
|
+
animation: "_flint_ripple 1.8s ease-out infinite",
|
|
389
|
+
opacity: isSuccess ? 0 : 1,
|
|
390
|
+
transition: "opacity 0.3s ease"
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
),
|
|
394
|
+
/* @__PURE__ */ jsx2(
|
|
395
|
+
"div",
|
|
396
|
+
{
|
|
397
|
+
style: {
|
|
398
|
+
position: "absolute",
|
|
399
|
+
inset: -10,
|
|
400
|
+
borderRadius: "50%",
|
|
401
|
+
border: `1.5px solid ${colors.accent}`,
|
|
402
|
+
animation: "_flint_ripple 1.8s ease-out infinite 0.6s",
|
|
403
|
+
opacity: isSuccess ? 0 : 1,
|
|
404
|
+
transition: "opacity 0.3s ease"
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
),
|
|
408
|
+
/* @__PURE__ */ jsx2(
|
|
409
|
+
"div",
|
|
410
|
+
{
|
|
411
|
+
style: {
|
|
412
|
+
position: "absolute",
|
|
413
|
+
inset: 0,
|
|
414
|
+
borderRadius: "50%",
|
|
415
|
+
border: ringBorder,
|
|
416
|
+
borderTopColor: ringTopColor,
|
|
417
|
+
animation: isSuccess ? "none" : "_flint_spin 0.85s linear infinite",
|
|
418
|
+
transition: "border-color 0.45s ease, border-top-color 0.45s ease"
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
),
|
|
422
|
+
/* @__PURE__ */ jsxs2("div", { style: { position: "absolute", inset: 14, borderRadius: "50%" }, children: [
|
|
423
|
+
/* @__PURE__ */ jsx2(
|
|
424
|
+
"div",
|
|
425
|
+
{
|
|
426
|
+
style: {
|
|
427
|
+
position: "absolute",
|
|
428
|
+
inset: 0,
|
|
429
|
+
borderRadius: "50%",
|
|
430
|
+
background: `linear-gradient(135deg, ${colors.accent}30, ${colors.accentHover}50)`,
|
|
431
|
+
display: "flex",
|
|
432
|
+
alignItems: "center",
|
|
433
|
+
justifyContent: "center",
|
|
434
|
+
animation: isSuccess ? "none" : "_flint_pulse 2s ease-in-out infinite",
|
|
435
|
+
opacity: isSuccess ? 0 : 1,
|
|
436
|
+
transition: "opacity 0.3s ease"
|
|
437
|
+
},
|
|
438
|
+
children: /* @__PURE__ */ jsx2(SparkIcon, { color: colors.accent, size: 20 })
|
|
439
|
+
}
|
|
440
|
+
),
|
|
441
|
+
/* @__PURE__ */ jsx2(
|
|
442
|
+
"div",
|
|
443
|
+
{
|
|
444
|
+
style: {
|
|
445
|
+
position: "absolute",
|
|
446
|
+
inset: 0,
|
|
447
|
+
borderRadius: "50%",
|
|
448
|
+
background: "rgba(34,197,94,0.15)",
|
|
449
|
+
display: "flex",
|
|
450
|
+
alignItems: "center",
|
|
451
|
+
justifyContent: "center",
|
|
452
|
+
opacity: isSuccess ? 1 : 0,
|
|
453
|
+
transform: isSuccess ? "scale(1)" : "scale(0.65)",
|
|
454
|
+
transition: "opacity 0.35s ease 0.2s, transform 0.4s cubic-bezier(0.16,1,0.3,1) 0.2s"
|
|
455
|
+
},
|
|
456
|
+
children: /* @__PURE__ */ jsx2(CheckIcon, { size: 20 })
|
|
457
|
+
}
|
|
458
|
+
)
|
|
459
|
+
] })
|
|
460
|
+
] }),
|
|
461
|
+
/* @__PURE__ */ jsxs2("div", { style: { position: "relative", height: 26, width: "100%", marginBottom: 10 }, children: [
|
|
462
|
+
/* @__PURE__ */ jsx2(
|
|
463
|
+
"div",
|
|
464
|
+
{
|
|
465
|
+
style: {
|
|
466
|
+
position: "absolute",
|
|
467
|
+
inset: 0,
|
|
468
|
+
display: "flex",
|
|
469
|
+
alignItems: "center",
|
|
470
|
+
justifyContent: "center",
|
|
471
|
+
fontSize: 19,
|
|
472
|
+
fontWeight: 700,
|
|
473
|
+
color: colors.text,
|
|
474
|
+
letterSpacing: "-0.02em",
|
|
475
|
+
opacity: isSuccess ? 0 : 1,
|
|
476
|
+
transition: "opacity 0.25s ease",
|
|
477
|
+
pointerEvents: "none"
|
|
478
|
+
},
|
|
479
|
+
children: t("sending")
|
|
480
|
+
}
|
|
481
|
+
),
|
|
482
|
+
/* @__PURE__ */ jsx2(
|
|
483
|
+
"div",
|
|
484
|
+
{
|
|
485
|
+
style: {
|
|
486
|
+
position: "absolute",
|
|
487
|
+
inset: 0,
|
|
488
|
+
display: "flex",
|
|
489
|
+
alignItems: "center",
|
|
490
|
+
justifyContent: "center",
|
|
491
|
+
fontSize: 19,
|
|
492
|
+
fontWeight: 700,
|
|
493
|
+
color: colors.text,
|
|
494
|
+
letterSpacing: "-0.02em",
|
|
495
|
+
opacity: isSuccess ? 1 : 0,
|
|
496
|
+
transform: isSuccess ? "translateY(0)" : "translateY(6px)",
|
|
497
|
+
transition: "opacity 0.35s ease 0.25s, transform 0.35s ease 0.25s",
|
|
498
|
+
pointerEvents: isSuccess ? "auto" : "none"
|
|
499
|
+
},
|
|
500
|
+
children: t("successTitle")
|
|
501
|
+
}
|
|
502
|
+
)
|
|
503
|
+
] }),
|
|
504
|
+
/* @__PURE__ */ jsxs2("div", { style: { position: "relative", minHeight: 76, width: "100%" }, children: [
|
|
505
|
+
/* @__PURE__ */ jsxs2(
|
|
506
|
+
"div",
|
|
507
|
+
{
|
|
508
|
+
style: {
|
|
509
|
+
position: "absolute",
|
|
510
|
+
inset: 0,
|
|
511
|
+
display: "flex",
|
|
512
|
+
alignItems: "center",
|
|
513
|
+
justifyContent: "center",
|
|
514
|
+
gap: 6,
|
|
515
|
+
color: colors.textMuted,
|
|
516
|
+
fontSize: 15,
|
|
517
|
+
opacity: isSuccess ? 0 : 1,
|
|
518
|
+
transition: "opacity 0.2s ease",
|
|
519
|
+
pointerEvents: "none"
|
|
520
|
+
},
|
|
521
|
+
children: [
|
|
522
|
+
/* @__PURE__ */ jsx2("span", { children: t("capturingContext") }),
|
|
523
|
+
/* @__PURE__ */ jsx2(SendingDots, { color: colors.accent })
|
|
524
|
+
]
|
|
525
|
+
}
|
|
526
|
+
),
|
|
527
|
+
/* @__PURE__ */ jsxs2(
|
|
528
|
+
"div",
|
|
529
|
+
{
|
|
530
|
+
style: {
|
|
531
|
+
position: "absolute",
|
|
532
|
+
inset: 0,
|
|
533
|
+
display: "flex",
|
|
534
|
+
flexDirection: "column",
|
|
535
|
+
alignItems: "center",
|
|
536
|
+
gap: 10,
|
|
537
|
+
opacity: isSuccess ? 1 : 0,
|
|
538
|
+
transform: isSuccess ? "translateY(0)" : "translateY(8px)",
|
|
539
|
+
transition: "opacity 0.35s ease 0.35s, transform 0.35s ease 0.35s",
|
|
540
|
+
pointerEvents: isSuccess ? "auto" : "none"
|
|
541
|
+
},
|
|
542
|
+
children: [
|
|
543
|
+
/* @__PURE__ */ jsx2("p", { style: { fontSize: 15, color: colors.textMuted, margin: 0 }, children: result ? `ID: ${result.id}` : "" }),
|
|
544
|
+
statusPageUrl && user?.id && /* @__PURE__ */ jsxs2(
|
|
545
|
+
"a",
|
|
546
|
+
{
|
|
547
|
+
href: `${statusPageUrl}/status?project_key=${encodeURIComponent(projectKey)}&reporter_id=${encodeURIComponent(user.id)}&server_url=${encodeURIComponent(serverUrl)}`,
|
|
548
|
+
target: "_blank",
|
|
549
|
+
rel: "noreferrer",
|
|
550
|
+
style: {
|
|
551
|
+
fontSize: 14,
|
|
552
|
+
color: colors.accent,
|
|
553
|
+
textDecoration: "none",
|
|
554
|
+
fontWeight: 600,
|
|
555
|
+
animation: "_flint_success_up 0.35s ease 0.4s both"
|
|
556
|
+
},
|
|
557
|
+
children: [
|
|
558
|
+
"\u{1F4CB}",
|
|
559
|
+
" Track your bugs ",
|
|
560
|
+
"\u2192"
|
|
561
|
+
]
|
|
562
|
+
}
|
|
563
|
+
),
|
|
564
|
+
/* @__PURE__ */ jsx2(
|
|
565
|
+
"button",
|
|
566
|
+
{
|
|
567
|
+
onClick: onClose,
|
|
568
|
+
style: {
|
|
569
|
+
width: "100%",
|
|
570
|
+
padding: "13px 20px",
|
|
571
|
+
borderRadius: 12,
|
|
572
|
+
border: "none",
|
|
573
|
+
background: `linear-gradient(135deg, ${colors.accent}, ${colors.accentHover})`,
|
|
574
|
+
color: colors.buttonText,
|
|
575
|
+
fontSize: 17,
|
|
576
|
+
fontWeight: 700,
|
|
577
|
+
cursor: "pointer",
|
|
578
|
+
letterSpacing: "-0.01em",
|
|
579
|
+
boxShadow: accentGlow,
|
|
580
|
+
fontFamily: "inherit",
|
|
581
|
+
display: "flex",
|
|
582
|
+
alignItems: "center",
|
|
583
|
+
justifyContent: "center",
|
|
584
|
+
gap: 8
|
|
585
|
+
},
|
|
586
|
+
children: t("close")
|
|
587
|
+
}
|
|
588
|
+
)
|
|
589
|
+
]
|
|
590
|
+
}
|
|
591
|
+
)
|
|
592
|
+
] })
|
|
593
|
+
]
|
|
594
|
+
}
|
|
595
|
+
)
|
|
596
|
+
]
|
|
597
|
+
}
|
|
598
|
+
) });
|
|
581
599
|
}
|
|
582
600
|
return /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
583
|
-
annotating && /* @__PURE__ */ jsx2(
|
|
601
|
+
enableScreenshot && annotating && /* @__PURE__ */ jsx2(
|
|
584
602
|
ScreenAnnotator,
|
|
585
603
|
{
|
|
586
604
|
zIndex: zIndex + 1,
|
|
@@ -604,37 +622,43 @@ function FlintModal({
|
|
|
604
622
|
}
|
|
605
623
|
),
|
|
606
624
|
/* @__PURE__ */ jsxs2("form", { onSubmit: handleSubmit, style: { padding: "20px 24px 24px" }, children: [
|
|
607
|
-
/* @__PURE__ */ jsx2(
|
|
608
|
-
|
|
609
|
-
gap: 4,
|
|
610
|
-
marginBottom: 20,
|
|
611
|
-
background: colors.backgroundSecondary,
|
|
612
|
-
borderRadius: 12,
|
|
613
|
-
padding: 4,
|
|
614
|
-
border: `1px solid ${inputBorder}`
|
|
615
|
-
}, children: ["bug", "text"].map((m) => /* @__PURE__ */ jsx2(
|
|
616
|
-
"button",
|
|
625
|
+
/* @__PURE__ */ jsx2(
|
|
626
|
+
"div",
|
|
617
627
|
{
|
|
618
|
-
type: "button",
|
|
619
|
-
onClick: () => setMode(m),
|
|
620
628
|
style: {
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
fontFamily: "inherit",
|
|
629
|
-
transition: "background 0.15s, color 0.15s",
|
|
630
|
-
background: mode === m ? `linear-gradient(135deg, ${colors.accent}, ${colors.accentHover})` : "transparent",
|
|
631
|
-
color: mode === m ? colors.buttonText : colors.textMuted,
|
|
632
|
-
boxShadow: mode === m ? `0 2px 8px ${colors.accent}30` : "none"
|
|
629
|
+
display: "flex",
|
|
630
|
+
gap: 4,
|
|
631
|
+
marginBottom: 20,
|
|
632
|
+
background: colors.backgroundSecondary,
|
|
633
|
+
borderRadius: 12,
|
|
634
|
+
padding: 4,
|
|
635
|
+
border: `1px solid ${inputBorder}`
|
|
633
636
|
},
|
|
634
|
-
children:
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
637
|
+
children: ["bug", "text"].map((m) => /* @__PURE__ */ jsx2(
|
|
638
|
+
"button",
|
|
639
|
+
{
|
|
640
|
+
type: "button",
|
|
641
|
+
onClick: () => setMode(m),
|
|
642
|
+
style: {
|
|
643
|
+
flex: 1,
|
|
644
|
+
padding: "8px 10px",
|
|
645
|
+
borderRadius: 9,
|
|
646
|
+
border: "none",
|
|
647
|
+
cursor: "pointer",
|
|
648
|
+
fontSize: 13,
|
|
649
|
+
fontWeight: mode === m ? 700 : 500,
|
|
650
|
+
fontFamily: "inherit",
|
|
651
|
+
transition: "background 0.15s, color 0.15s",
|
|
652
|
+
background: mode === m ? `linear-gradient(135deg, ${colors.accent}, ${colors.accentHover})` : "transparent",
|
|
653
|
+
color: mode === m ? colors.buttonText : colors.textMuted,
|
|
654
|
+
boxShadow: mode === m ? `0 2px 8px ${colors.accent}30` : "none"
|
|
655
|
+
},
|
|
656
|
+
children: m === "bug" ? "\u{1F41B} Bug" : "\u{1F524} Text / Translation"
|
|
657
|
+
},
|
|
658
|
+
m
|
|
659
|
+
))
|
|
660
|
+
}
|
|
661
|
+
),
|
|
638
662
|
mode === "text" && /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
639
663
|
/* @__PURE__ */ jsxs2("div", { style: { marginBottom: 14 }, children: [
|
|
640
664
|
/* @__PURE__ */ jsx2(FieldLabel, { colors, htmlFor: "flint-text-original", children: "Original text" }),
|
|
@@ -731,7 +755,7 @@ function FlintModal({
|
|
|
731
755
|
}
|
|
732
756
|
)
|
|
733
757
|
] }),
|
|
734
|
-
/* @__PURE__ */ jsxs2("div", { style: { marginBottom: 20, display: mode === "text" ? "none" : void 0 }, children: [
|
|
758
|
+
/* @__PURE__ */ jsxs2("div", { style: { marginBottom: 20, display: mode === "text" || !enableScreenshot ? "none" : void 0 }, children: [
|
|
735
759
|
/* @__PURE__ */ jsx2(FieldLabel, { colors, children: t("screenshotLabel") }),
|
|
736
760
|
screenshot ? /* @__PURE__ */ jsxs2("div", { style: { display: "flex", alignItems: "center", gap: 10 }, children: [
|
|
737
761
|
/* @__PURE__ */ jsx2(
|
|
@@ -742,7 +766,20 @@ function FlintModal({
|
|
|
742
766
|
style: { height: 60, borderRadius: 8, objectFit: "cover", border: `1px solid ${inputBorder}` }
|
|
743
767
|
}
|
|
744
768
|
),
|
|
745
|
-
/* @__PURE__ */ jsx2(
|
|
769
|
+
/* @__PURE__ */ jsx2(
|
|
770
|
+
"span",
|
|
771
|
+
{
|
|
772
|
+
style: {
|
|
773
|
+
fontSize: 13,
|
|
774
|
+
color: colors.textMuted,
|
|
775
|
+
flex: 1,
|
|
776
|
+
overflow: "hidden",
|
|
777
|
+
textOverflow: "ellipsis",
|
|
778
|
+
whiteSpace: "nowrap"
|
|
779
|
+
},
|
|
780
|
+
children: screenshot.name
|
|
781
|
+
}
|
|
782
|
+
),
|
|
746
783
|
/* @__PURE__ */ jsx2(
|
|
747
784
|
"button",
|
|
748
785
|
{
|
|
@@ -829,31 +866,43 @@ function FlintModal({
|
|
|
829
866
|
}
|
|
830
867
|
)
|
|
831
868
|
] }),
|
|
832
|
-
/* @__PURE__ */ jsxs2(
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
869
|
+
/* @__PURE__ */ jsxs2(
|
|
870
|
+
"div",
|
|
871
|
+
{
|
|
872
|
+
style: {
|
|
873
|
+
display: "flex",
|
|
874
|
+
alignItems: "center",
|
|
875
|
+
gap: 8,
|
|
876
|
+
padding: "9px 12px",
|
|
877
|
+
borderRadius: 10,
|
|
878
|
+
background: isDark ? "rgba(255,255,255,0.04)" : "rgba(0,77,240,0.04)",
|
|
879
|
+
border: `1px solid ${isDark ? "rgba(255,255,255,0.08)" : "rgba(0,77,240,0.1)"}`,
|
|
880
|
+
marginBottom: 16
|
|
881
|
+
},
|
|
882
|
+
children: [
|
|
883
|
+
/* @__PURE__ */ jsx2("span", { style: { fontSize: 16 }, children: "\u{1F3A5}" }),
|
|
884
|
+
/* @__PURE__ */ jsx2("span", { style: { fontSize: 14, color: colors.textMuted, lineHeight: 1.4 }, children: t("replayInfo") })
|
|
885
|
+
]
|
|
886
|
+
}
|
|
887
|
+
),
|
|
888
|
+
status === "error" && /* @__PURE__ */ jsxs2(
|
|
889
|
+
"div",
|
|
890
|
+
{
|
|
891
|
+
style: {
|
|
892
|
+
padding: "10px 13px",
|
|
893
|
+
borderRadius: 10,
|
|
894
|
+
background: "rgba(239,68,68,0.08)",
|
|
895
|
+
border: "1px solid rgba(239,68,68,0.2)",
|
|
896
|
+
color: "#f87171",
|
|
897
|
+
fontSize: 14,
|
|
898
|
+
marginBottom: 16
|
|
899
|
+
},
|
|
900
|
+
children: [
|
|
901
|
+
"\u26A0\uFE0F ",
|
|
902
|
+
errorMsg || t("errorLabel")
|
|
903
|
+
]
|
|
904
|
+
}
|
|
905
|
+
),
|
|
857
906
|
/* @__PURE__ */ jsxs2(
|
|
858
907
|
"button",
|
|
859
908
|
{
|
|
@@ -914,49 +963,68 @@ function ModalHeader({
|
|
|
914
963
|
titleId,
|
|
915
964
|
title
|
|
916
965
|
}) {
|
|
917
|
-
return /* @__PURE__ */ jsxs2(
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
966
|
+
return /* @__PURE__ */ jsxs2(
|
|
967
|
+
"div",
|
|
968
|
+
{
|
|
969
|
+
style: {
|
|
970
|
+
display: "flex",
|
|
971
|
+
alignItems: "center",
|
|
972
|
+
gap: 10,
|
|
973
|
+
padding: "16px 20px 14px",
|
|
974
|
+
borderBottom: `1px solid ${inputBorder}`
|
|
975
|
+
},
|
|
976
|
+
children: [
|
|
977
|
+
/* @__PURE__ */ jsx2(
|
|
978
|
+
"div",
|
|
979
|
+
{
|
|
980
|
+
style: {
|
|
981
|
+
width: 28,
|
|
982
|
+
height: 28,
|
|
983
|
+
borderRadius: 8,
|
|
984
|
+
background: `linear-gradient(135deg, ${colors.accent}20, ${colors.accentHover}35)`,
|
|
985
|
+
border: `1px solid ${colors.accent}30`,
|
|
986
|
+
display: "flex",
|
|
987
|
+
alignItems: "center",
|
|
988
|
+
justifyContent: "center",
|
|
989
|
+
flexShrink: 0
|
|
990
|
+
},
|
|
991
|
+
children: /* @__PURE__ */ jsx2(SparkIcon, { color: colors.accent, size: 13 })
|
|
992
|
+
}
|
|
993
|
+
),
|
|
994
|
+
titleId && title ? /* @__PURE__ */ jsx2(
|
|
995
|
+
"h2",
|
|
996
|
+
{
|
|
997
|
+
id: titleId,
|
|
998
|
+
style: { margin: 0, fontSize: 16, fontWeight: 600, color: colors.text, letterSpacing: "-0.01em", flex: 1 },
|
|
999
|
+
children: title
|
|
1000
|
+
}
|
|
1001
|
+
) : /* @__PURE__ */ jsx2("span", { style: { flex: 1, fontSize: 15, fontWeight: 600, color: colors.textMuted }, children: "Flint" }),
|
|
1002
|
+
showClose && /* @__PURE__ */ jsx2(
|
|
1003
|
+
"button",
|
|
1004
|
+
{
|
|
1005
|
+
onClick: onClose,
|
|
1006
|
+
"aria-label": "Close",
|
|
1007
|
+
style: {
|
|
1008
|
+
background: "none",
|
|
1009
|
+
border: "none",
|
|
1010
|
+
cursor: "pointer",
|
|
1011
|
+
padding: 4,
|
|
1012
|
+
color: colors.textMuted,
|
|
1013
|
+
fontSize: 22,
|
|
1014
|
+
lineHeight: 1,
|
|
1015
|
+
borderRadius: 6,
|
|
1016
|
+
display: "flex",
|
|
1017
|
+
alignItems: "center",
|
|
1018
|
+
justifyContent: "center",
|
|
1019
|
+
opacity: 0.6,
|
|
1020
|
+
fontFamily: "inherit"
|
|
1021
|
+
},
|
|
1022
|
+
children: "\xD7"
|
|
1023
|
+
}
|
|
1024
|
+
)
|
|
1025
|
+
]
|
|
1026
|
+
}
|
|
1027
|
+
);
|
|
960
1028
|
}
|
|
961
1029
|
function FieldLabel({
|
|
962
1030
|
children,
|
|
@@ -1018,19 +1086,71 @@ function SeverityButton({ sev, label, selected, hint, color, accent, border, bg,
|
|
|
1018
1086
|
},
|
|
1019
1087
|
children: [
|
|
1020
1088
|
/* @__PURE__ */ jsx2("span", { style: { width: 8, height: 8, borderRadius: "50%", background: color, display: "block" } }),
|
|
1021
|
-
/* @__PURE__ */ jsx2(
|
|
1089
|
+
/* @__PURE__ */ jsx2(
|
|
1090
|
+
"span",
|
|
1091
|
+
{
|
|
1092
|
+
style: {
|
|
1093
|
+
fontSize: 13,
|
|
1094
|
+
fontWeight: selected ? 700 : 500,
|
|
1095
|
+
color: selected ? accent : text,
|
|
1096
|
+
letterSpacing: "0.02em"
|
|
1097
|
+
},
|
|
1098
|
+
children: sev
|
|
1099
|
+
}
|
|
1100
|
+
),
|
|
1022
1101
|
/* @__PURE__ */ jsx2("span", { style: { fontSize: 11, color: selected ? accent : text, opacity: 0.6, letterSpacing: "0.02em" }, children: label })
|
|
1023
1102
|
]
|
|
1024
1103
|
}
|
|
1025
1104
|
);
|
|
1026
1105
|
}
|
|
1027
1106
|
function SparkIcon({ color = "currentColor", size = 14 }) {
|
|
1028
|
-
return /* @__PURE__ */ jsx2(
|
|
1107
|
+
return /* @__PURE__ */ jsx2(
|
|
1108
|
+
"svg",
|
|
1109
|
+
{
|
|
1110
|
+
width: size,
|
|
1111
|
+
height: size,
|
|
1112
|
+
viewBox: "0 0 24 24",
|
|
1113
|
+
fill: "none",
|
|
1114
|
+
stroke: color,
|
|
1115
|
+
strokeWidth: "2.2",
|
|
1116
|
+
strokeLinecap: "round",
|
|
1117
|
+
strokeLinejoin: "round",
|
|
1118
|
+
"aria-hidden": "true",
|
|
1119
|
+
children: /* @__PURE__ */ jsx2("path", { d: "M13 2L3 14h9l-1 8 10-12h-9l1-8z" })
|
|
1120
|
+
}
|
|
1121
|
+
);
|
|
1029
1122
|
}
|
|
1030
1123
|
function CheckIcon({ size = 20 }) {
|
|
1031
|
-
return /* @__PURE__ */ jsx2(
|
|
1124
|
+
return /* @__PURE__ */ jsx2(
|
|
1125
|
+
"svg",
|
|
1126
|
+
{
|
|
1127
|
+
width: size,
|
|
1128
|
+
height: size,
|
|
1129
|
+
viewBox: "0 0 24 24",
|
|
1130
|
+
fill: "none",
|
|
1131
|
+
stroke: "#22c55e",
|
|
1132
|
+
strokeWidth: "2.5",
|
|
1133
|
+
strokeLinecap: "round",
|
|
1134
|
+
strokeLinejoin: "round",
|
|
1135
|
+
"aria-hidden": "true",
|
|
1136
|
+
children: /* @__PURE__ */ jsx2("polyline", { points: "20 6 9 17 4 12" })
|
|
1137
|
+
}
|
|
1138
|
+
);
|
|
1032
1139
|
}
|
|
1033
1140
|
|
|
1141
|
+
// src/FlintWidget.tsx
|
|
1142
|
+
import { useCallback as useCallback2, useEffect as useEffect3, useRef as useRef3, useState as useState3 } from "react";
|
|
1143
|
+
import { I18nextProvider, useTranslation as useTranslation2 } from "react-i18next";
|
|
1144
|
+
|
|
1145
|
+
// src/collectors/console.ts
|
|
1146
|
+
import { createConsoleCollector } from "@flint/core";
|
|
1147
|
+
|
|
1148
|
+
// src/collectors/environment.ts
|
|
1149
|
+
import { collectEnvironment } from "@flint/core";
|
|
1150
|
+
|
|
1151
|
+
// src/collectors/network.ts
|
|
1152
|
+
import { createNetworkCollector } from "@flint/core";
|
|
1153
|
+
|
|
1034
1154
|
// src/i18n/index.ts
|
|
1035
1155
|
import { createInstance } from "i18next";
|
|
1036
1156
|
import { initReactI18next } from "react-i18next";
|
|
@@ -1080,251 +1200,15 @@ widgetI18n.use(initReactI18next).init({
|
|
|
1080
1200
|
});
|
|
1081
1201
|
var i18n_default = widgetI18n;
|
|
1082
1202
|
|
|
1083
|
-
// src/collectors/environment.ts
|
|
1084
|
-
function collectEnvironment() {
|
|
1085
|
-
const ua = navigator.userAgent;
|
|
1086
|
-
let browser = "Unknown";
|
|
1087
|
-
const chromeM = ua.match(/Chrome\/(\d+)/);
|
|
1088
|
-
const firefoxM = ua.match(/Firefox\/(\d+)/);
|
|
1089
|
-
const edgeM = ua.match(/Edg\/(\d+)/);
|
|
1090
|
-
const safariM = ua.match(/Version\/(\d+)/);
|
|
1091
|
-
const operaM = ua.match(/OPR\/(\d+)/);
|
|
1092
|
-
if (operaM) {
|
|
1093
|
-
browser = `Opera ${operaM[1]}`;
|
|
1094
|
-
} else if (edgeM) {
|
|
1095
|
-
browser = `Edge ${edgeM[1]}`;
|
|
1096
|
-
} else if (chromeM && !/Edg|OPR/.test(ua)) {
|
|
1097
|
-
browser = `Chrome ${chromeM[1]}`;
|
|
1098
|
-
} else if (firefoxM) {
|
|
1099
|
-
browser = `Firefox ${firefoxM[1]}`;
|
|
1100
|
-
} else if (safariM && /Safari\//.test(ua)) {
|
|
1101
|
-
browser = `Safari ${safariM[1]}`;
|
|
1102
|
-
}
|
|
1103
|
-
let os = "Unknown";
|
|
1104
|
-
const macM = ua.match(/Mac OS X (\d+[._]\d+)/);
|
|
1105
|
-
const winM = ua.match(/Windows NT (\d+\.\d+)/);
|
|
1106
|
-
const androidM = ua.match(/Android (\d+)/);
|
|
1107
|
-
const iosM = ua.match(/iPhone OS (\d+[._]\d+)/);
|
|
1108
|
-
if (macM) {
|
|
1109
|
-
os = `macOS ${macM[1].replace("_", ".")}`;
|
|
1110
|
-
} else if (winM) {
|
|
1111
|
-
const winMap = {
|
|
1112
|
-
"10.0": "10/11",
|
|
1113
|
-
"6.3": "8.1",
|
|
1114
|
-
"6.2": "8",
|
|
1115
|
-
"6.1": "7"
|
|
1116
|
-
};
|
|
1117
|
-
os = `Windows ${winMap[winM[1]] ?? winM[1]}`;
|
|
1118
|
-
} else if (androidM) {
|
|
1119
|
-
os = `Android ${androidM[1]}`;
|
|
1120
|
-
} else if (iosM) {
|
|
1121
|
-
os = `iOS ${iosM[1].replace(/_/g, ".")}`;
|
|
1122
|
-
} else if (/Linux/.test(ua)) {
|
|
1123
|
-
os = "Linux";
|
|
1124
|
-
}
|
|
1125
|
-
return {
|
|
1126
|
-
browser,
|
|
1127
|
-
os,
|
|
1128
|
-
viewport: `${window.innerWidth}x${window.innerHeight}`,
|
|
1129
|
-
screen: `${screen.width}x${screen.height}`,
|
|
1130
|
-
language: navigator.language,
|
|
1131
|
-
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
1132
|
-
online: navigator.onLine
|
|
1133
|
-
};
|
|
1134
|
-
}
|
|
1135
|
-
|
|
1136
|
-
// src/collectors/console.ts
|
|
1137
|
-
var MAX_ENTRIES = 50;
|
|
1138
|
-
function createConsoleCollector() {
|
|
1139
|
-
const entries = [];
|
|
1140
|
-
let active = false;
|
|
1141
|
-
const originals = {
|
|
1142
|
-
log: console.log.bind(console),
|
|
1143
|
-
warn: console.warn.bind(console),
|
|
1144
|
-
error: console.error.bind(console)
|
|
1145
|
-
};
|
|
1146
|
-
let origOnerror = null;
|
|
1147
|
-
let origUnhandled = null;
|
|
1148
|
-
function push(level, args) {
|
|
1149
|
-
let str;
|
|
1150
|
-
try {
|
|
1151
|
-
str = args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ");
|
|
1152
|
-
} catch {
|
|
1153
|
-
str = String(args[0]);
|
|
1154
|
-
}
|
|
1155
|
-
if (str.length > 500) str = str.slice(0, 500) + "\u2026";
|
|
1156
|
-
entries.push({ level, args: str, timestamp: Date.now() });
|
|
1157
|
-
if (entries.length > MAX_ENTRIES) entries.shift();
|
|
1158
|
-
}
|
|
1159
|
-
return {
|
|
1160
|
-
start() {
|
|
1161
|
-
if (active) return;
|
|
1162
|
-
active = true;
|
|
1163
|
-
console.log = (...args) => {
|
|
1164
|
-
push("log", args);
|
|
1165
|
-
originals.log(...args);
|
|
1166
|
-
};
|
|
1167
|
-
console.warn = (...args) => {
|
|
1168
|
-
push("warn", args);
|
|
1169
|
-
originals.warn(...args);
|
|
1170
|
-
};
|
|
1171
|
-
console.error = (...args) => {
|
|
1172
|
-
push("error", args);
|
|
1173
|
-
originals.error(...args);
|
|
1174
|
-
};
|
|
1175
|
-
origOnerror = window.onerror;
|
|
1176
|
-
window.onerror = (msg, src, line, col, err) => {
|
|
1177
|
-
push("error", [err?.message ?? String(msg), `${src}:${line}:${col}`]);
|
|
1178
|
-
if (typeof origOnerror === "function")
|
|
1179
|
-
return origOnerror(msg, src, line, col, err);
|
|
1180
|
-
return false;
|
|
1181
|
-
};
|
|
1182
|
-
origUnhandled = window.onunhandledrejection;
|
|
1183
|
-
window.onunhandledrejection = (event) => {
|
|
1184
|
-
const reason = event.reason instanceof Error ? event.reason.message : JSON.stringify(event.reason);
|
|
1185
|
-
push("error", ["UnhandledRejection:", reason]);
|
|
1186
|
-
if (typeof origUnhandled === "function")
|
|
1187
|
-
origUnhandled.call(window, event);
|
|
1188
|
-
};
|
|
1189
|
-
},
|
|
1190
|
-
stop() {
|
|
1191
|
-
if (!active) return;
|
|
1192
|
-
active = false;
|
|
1193
|
-
console.log = originals.log;
|
|
1194
|
-
console.warn = originals.warn;
|
|
1195
|
-
console.error = originals.error;
|
|
1196
|
-
window.onerror = origOnerror;
|
|
1197
|
-
window.onunhandledrejection = origUnhandled;
|
|
1198
|
-
},
|
|
1199
|
-
getEntries() {
|
|
1200
|
-
return [...entries];
|
|
1201
|
-
}
|
|
1202
|
-
};
|
|
1203
|
-
}
|
|
1204
|
-
|
|
1205
|
-
// src/collectors/network.ts
|
|
1206
|
-
var MAX_ENTRIES2 = 20;
|
|
1207
|
-
var BLOCKED_HOSTS = /* @__PURE__ */ new Set([
|
|
1208
|
-
"browser-intake-datadoghq.com",
|
|
1209
|
-
"rum.browser-intake-datadoghq.com",
|
|
1210
|
-
"logs.browser-intake-datadoghq.com",
|
|
1211
|
-
"session-replay.browser-intake-datadoghq.com"
|
|
1212
|
-
]);
|
|
1213
|
-
function isBlockedUrl(url, extra) {
|
|
1214
|
-
try {
|
|
1215
|
-
const host = new URL(url, location.href).hostname;
|
|
1216
|
-
const all = [...BLOCKED_HOSTS, ...extra];
|
|
1217
|
-
return all.some((b) => host === b || host.endsWith("." + b));
|
|
1218
|
-
} catch {
|
|
1219
|
-
return false;
|
|
1220
|
-
}
|
|
1221
|
-
}
|
|
1222
|
-
function truncateUrl(url) {
|
|
1223
|
-
try {
|
|
1224
|
-
const u = new URL(url, location.href);
|
|
1225
|
-
const base = `${u.origin}${u.pathname}`;
|
|
1226
|
-
return base.length > 200 ? base.slice(0, 200) + "\u2026" : base;
|
|
1227
|
-
} catch {
|
|
1228
|
-
return url.length > 200 ? url.slice(0, 200) + "\u2026" : url;
|
|
1229
|
-
}
|
|
1230
|
-
}
|
|
1231
|
-
function createNetworkCollector(extraBlockedHosts = []) {
|
|
1232
|
-
const entries = [];
|
|
1233
|
-
const blocked = new Set(extraBlockedHosts);
|
|
1234
|
-
let origFetch = null;
|
|
1235
|
-
let origXHROpen = null;
|
|
1236
|
-
let active = false;
|
|
1237
|
-
function push(entry) {
|
|
1238
|
-
entries.push(entry);
|
|
1239
|
-
if (entries.length > MAX_ENTRIES2) entries.shift();
|
|
1240
|
-
}
|
|
1241
|
-
return {
|
|
1242
|
-
start() {
|
|
1243
|
-
if (active) return;
|
|
1244
|
-
active = true;
|
|
1245
|
-
origFetch = window.fetch;
|
|
1246
|
-
window.fetch = async (input, init) => {
|
|
1247
|
-
const method = (init?.method ?? "GET").toUpperCase();
|
|
1248
|
-
const url = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
|
|
1249
|
-
const startTime = Date.now();
|
|
1250
|
-
const res = await origFetch.call(window, input, init);
|
|
1251
|
-
if (!isBlockedUrl(url, blocked)) {
|
|
1252
|
-
push({
|
|
1253
|
-
method,
|
|
1254
|
-
url: truncateUrl(url),
|
|
1255
|
-
status: res.status,
|
|
1256
|
-
duration: Date.now() - startTime,
|
|
1257
|
-
timestamp: startTime
|
|
1258
|
-
});
|
|
1259
|
-
}
|
|
1260
|
-
return res;
|
|
1261
|
-
};
|
|
1262
|
-
origXHROpen = XMLHttpRequest.prototype.open;
|
|
1263
|
-
XMLHttpRequest.prototype.open = function(method, url, async, username, password) {
|
|
1264
|
-
const startTime = Date.now();
|
|
1265
|
-
const urlStr = typeof url === "string" ? url : url.href;
|
|
1266
|
-
this.addEventListener("load", () => {
|
|
1267
|
-
if (!isBlockedUrl(urlStr, blocked)) {
|
|
1268
|
-
push({
|
|
1269
|
-
method: method.toUpperCase(),
|
|
1270
|
-
url: truncateUrl(urlStr),
|
|
1271
|
-
status: this.status,
|
|
1272
|
-
duration: Date.now() - startTime,
|
|
1273
|
-
timestamp: startTime
|
|
1274
|
-
});
|
|
1275
|
-
}
|
|
1276
|
-
});
|
|
1277
|
-
return origXHROpen.apply(this, [
|
|
1278
|
-
method,
|
|
1279
|
-
url,
|
|
1280
|
-
async ?? true,
|
|
1281
|
-
username,
|
|
1282
|
-
password
|
|
1283
|
-
]);
|
|
1284
|
-
};
|
|
1285
|
-
},
|
|
1286
|
-
stop() {
|
|
1287
|
-
if (!active) return;
|
|
1288
|
-
active = false;
|
|
1289
|
-
if (origFetch) window.fetch = origFetch;
|
|
1290
|
-
if (origXHROpen) XMLHttpRequest.prototype.open = origXHROpen;
|
|
1291
|
-
},
|
|
1292
|
-
getEntries() {
|
|
1293
|
-
return [...entries];
|
|
1294
|
-
}
|
|
1295
|
-
};
|
|
1296
|
-
}
|
|
1297
|
-
|
|
1298
1203
|
// src/store.ts
|
|
1204
|
+
import { getSnapshot, subscribe } from "@flint/core";
|
|
1299
1205
|
import { useSyncExternalStore } from "react";
|
|
1300
|
-
|
|
1301
|
-
var listeners = /* @__PURE__ */ new Set();
|
|
1302
|
-
function emit() {
|
|
1303
|
-
listeners.forEach((fn) => fn());
|
|
1304
|
-
}
|
|
1305
|
-
function subscribeStore(fn) {
|
|
1306
|
-
listeners.add(fn);
|
|
1307
|
-
return () => listeners.delete(fn);
|
|
1308
|
-
}
|
|
1309
|
-
function getSnapshot() {
|
|
1310
|
-
return state;
|
|
1311
|
-
}
|
|
1206
|
+
import { flint as flint2 } from "@flint/core";
|
|
1312
1207
|
function useFlintStore() {
|
|
1313
|
-
return useSyncExternalStore(
|
|
1208
|
+
return useSyncExternalStore(subscribe, getSnapshot);
|
|
1314
1209
|
}
|
|
1315
|
-
var flint = {
|
|
1316
|
-
setUser(user) {
|
|
1317
|
-
state = { ...state, user: user ?? void 0 };
|
|
1318
|
-
emit();
|
|
1319
|
-
},
|
|
1320
|
-
setSessionReplay(url) {
|
|
1321
|
-
state = { ...state, sessionReplay: url };
|
|
1322
|
-
emit();
|
|
1323
|
-
}
|
|
1324
|
-
};
|
|
1325
1210
|
|
|
1326
1211
|
// src/FlintWidget.tsx
|
|
1327
|
-
import { record } from "rrweb";
|
|
1328
1212
|
import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1329
1213
|
var REPLAY_WINDOW_MS = 6e4;
|
|
1330
1214
|
function FlintWidget(props) {
|
|
@@ -1342,14 +1226,40 @@ function WidgetContent({
|
|
|
1342
1226
|
extraFields,
|
|
1343
1227
|
buttonLabel,
|
|
1344
1228
|
theme = "dark",
|
|
1345
|
-
zIndex = 9999
|
|
1229
|
+
zIndex = 9999,
|
|
1230
|
+
statusPageUrl,
|
|
1231
|
+
datadogSite,
|
|
1232
|
+
enableReplay = true,
|
|
1233
|
+
enableScreenshot = true,
|
|
1234
|
+
enableConsole = true,
|
|
1235
|
+
enableNetwork = true,
|
|
1236
|
+
onBeforeSubmit,
|
|
1237
|
+
onSuccess,
|
|
1238
|
+
onError,
|
|
1239
|
+
onOpen,
|
|
1240
|
+
onClose
|
|
1346
1241
|
}) {
|
|
1347
1242
|
const globalState = useFlintStore();
|
|
1348
1243
|
const resolvedUser = user ?? globalState.user;
|
|
1349
1244
|
const resolvedSessionReplay = extraFields?.sessionReplay ?? globalState.sessionReplay;
|
|
1350
1245
|
const getExternalReplayUrl = () => {
|
|
1351
1246
|
const src = resolvedSessionReplay;
|
|
1352
|
-
|
|
1247
|
+
const explicit = typeof src === "function" ? src() : src;
|
|
1248
|
+
if (explicit) return explicit;
|
|
1249
|
+
if (datadogSite) {
|
|
1250
|
+
try {
|
|
1251
|
+
const ddRum = window.DD_RUM;
|
|
1252
|
+
const ctx = ddRum?.getInternalContext?.();
|
|
1253
|
+
if (ctx?.session_id) {
|
|
1254
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
1255
|
+
const fromTs = now - 30;
|
|
1256
|
+
const toTs = now + 5;
|
|
1257
|
+
return `https://${datadogSite}/rum/replay/sessions/${ctx.session_id}?from_ts=${fromTs}&to_ts=${toTs}&tab=replay&live=false`;
|
|
1258
|
+
}
|
|
1259
|
+
} catch {
|
|
1260
|
+
}
|
|
1261
|
+
}
|
|
1262
|
+
return void 0;
|
|
1353
1263
|
};
|
|
1354
1264
|
const { t } = useTranslation2();
|
|
1355
1265
|
const [open, setOpen] = useState3(false);
|
|
@@ -1396,16 +1306,17 @@ function WidgetContent({
|
|
|
1396
1306
|
pendingSelection.current = text;
|
|
1397
1307
|
setSelectionTooltip(null);
|
|
1398
1308
|
setOpen(true);
|
|
1309
|
+
onOpen?.();
|
|
1399
1310
|
};
|
|
1400
1311
|
const consoleCollector = useRef3(null);
|
|
1401
1312
|
const networkCollector = useRef3(null);
|
|
1402
1313
|
const replayEvents = useRef3([]);
|
|
1403
1314
|
const stopReplay = useRef3(null);
|
|
1404
|
-
if (!consoleCollector.current) {
|
|
1315
|
+
if (enableConsole && !consoleCollector.current) {
|
|
1405
1316
|
consoleCollector.current = createConsoleCollector();
|
|
1406
1317
|
consoleCollector.current.start();
|
|
1407
1318
|
}
|
|
1408
|
-
if (!networkCollector.current) {
|
|
1319
|
+
if (enableNetwork && !networkCollector.current) {
|
|
1409
1320
|
const flintHost = (() => {
|
|
1410
1321
|
try {
|
|
1411
1322
|
return new URL(serverUrl).hostname;
|
|
@@ -1417,22 +1328,29 @@ function WidgetContent({
|
|
|
1417
1328
|
networkCollector.current.start();
|
|
1418
1329
|
}
|
|
1419
1330
|
useEffect3(() => {
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1331
|
+
let cancelled = false;
|
|
1332
|
+
if (enableReplay) {
|
|
1333
|
+
import("rrweb").then(({ record }) => {
|
|
1334
|
+
if (cancelled) return;
|
|
1335
|
+
const stopFn = record({
|
|
1336
|
+
emit(event) {
|
|
1337
|
+
replayEvents.current.push(event);
|
|
1338
|
+
const cutoff = Date.now() - REPLAY_WINDOW_MS;
|
|
1339
|
+
while (replayEvents.current.length > 0 && replayEvents.current[0].timestamp < cutoff) {
|
|
1340
|
+
replayEvents.current.shift();
|
|
1341
|
+
}
|
|
1342
|
+
}
|
|
1343
|
+
});
|
|
1344
|
+
stopReplay.current = stopFn ?? null;
|
|
1345
|
+
});
|
|
1346
|
+
}
|
|
1430
1347
|
return () => {
|
|
1348
|
+
cancelled = true;
|
|
1431
1349
|
consoleCollector.current?.stop();
|
|
1432
1350
|
networkCollector.current?.stop();
|
|
1433
1351
|
stopReplay.current?.();
|
|
1434
1352
|
};
|
|
1435
|
-
}, []);
|
|
1353
|
+
}, [enableReplay]);
|
|
1436
1354
|
const label = buttonLabel ?? t("buttonLabel");
|
|
1437
1355
|
return /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
1438
1356
|
/* @__PURE__ */ jsxs3(
|
|
@@ -1442,7 +1360,10 @@ function WidgetContent({
|
|
|
1442
1360
|
onMouseDown: () => {
|
|
1443
1361
|
pendingSelection.current = window.getSelection()?.toString().trim() ?? "";
|
|
1444
1362
|
},
|
|
1445
|
-
onClick: () =>
|
|
1363
|
+
onClick: () => {
|
|
1364
|
+
setOpen(true);
|
|
1365
|
+
onOpen?.();
|
|
1366
|
+
},
|
|
1446
1367
|
onMouseEnter: () => setHovered(true),
|
|
1447
1368
|
onMouseLeave: () => setHovered(false),
|
|
1448
1369
|
"aria-label": label,
|
|
@@ -1523,6 +1444,7 @@ function WidgetContent({
|
|
|
1523
1444
|
zIndex,
|
|
1524
1445
|
onClose: () => {
|
|
1525
1446
|
setOpen(false);
|
|
1447
|
+
onClose?.();
|
|
1526
1448
|
pendingSelection.current = "";
|
|
1527
1449
|
},
|
|
1528
1450
|
getEnvironment: collectEnvironment,
|
|
@@ -1530,18 +1452,37 @@ function WidgetContent({
|
|
|
1530
1452
|
getNetworkErrors: () => networkCollector.current?.getEntries() ?? [],
|
|
1531
1453
|
getReplayEvents: () => [...replayEvents.current],
|
|
1532
1454
|
getExternalReplayUrl,
|
|
1533
|
-
initialSelection: pendingSelection.current
|
|
1455
|
+
initialSelection: pendingSelection.current,
|
|
1456
|
+
enableScreenshot,
|
|
1457
|
+
statusPageUrl,
|
|
1458
|
+
onBeforeSubmit,
|
|
1459
|
+
onSuccess,
|
|
1460
|
+
onError
|
|
1534
1461
|
}
|
|
1535
1462
|
)
|
|
1536
1463
|
] });
|
|
1537
1464
|
}
|
|
1538
1465
|
function TextIcon() {
|
|
1539
|
-
return /* @__PURE__ */ jsxs3(
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1466
|
+
return /* @__PURE__ */ jsxs3(
|
|
1467
|
+
"svg",
|
|
1468
|
+
{
|
|
1469
|
+
width: "12",
|
|
1470
|
+
height: "12",
|
|
1471
|
+
viewBox: "0 0 24 24",
|
|
1472
|
+
fill: "none",
|
|
1473
|
+
stroke: "currentColor",
|
|
1474
|
+
strokeWidth: "2.2",
|
|
1475
|
+
strokeLinecap: "round",
|
|
1476
|
+
strokeLinejoin: "round",
|
|
1477
|
+
"aria-hidden": "true",
|
|
1478
|
+
children: [
|
|
1479
|
+
/* @__PURE__ */ jsx3("path", { d: "M17 10H3" }),
|
|
1480
|
+
/* @__PURE__ */ jsx3("path", { d: "M21 6H3" }),
|
|
1481
|
+
/* @__PURE__ */ jsx3("path", { d: "M21 14H3" }),
|
|
1482
|
+
/* @__PURE__ */ jsx3("path", { d: "M17 18H3" })
|
|
1483
|
+
]
|
|
1484
|
+
}
|
|
1485
|
+
);
|
|
1545
1486
|
}
|
|
1546
1487
|
function SparkIcon2() {
|
|
1547
1488
|
return /* @__PURE__ */ jsx3(
|
|
@@ -1563,6 +1504,6 @@ function SparkIcon2() {
|
|
|
1563
1504
|
export {
|
|
1564
1505
|
FlintModal,
|
|
1565
1506
|
FlintWidget,
|
|
1566
|
-
flint
|
|
1507
|
+
flint2 as flint
|
|
1567
1508
|
};
|
|
1568
1509
|
//# sourceMappingURL=index.js.map
|