@prosopo/procaptcha-audio 0.0.0-stage → 0.2.1

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 (68) hide show
  1. package/.turbo/turbo-build$colon$cjs.log +52 -0
  2. package/.turbo/turbo-build$colon$tsc.log +53 -0
  3. package/.turbo/turbo-build.log +54 -0
  4. package/CHANGELOG.md +35 -0
  5. package/LICENSE +201 -0
  6. package/dist/_virtual/_rolldown/runtime.js +3 -0
  7. package/dist/cjs/components/audioPlayer.cjs +275 -0
  8. package/dist/cjs/components/procaptchaAudio.cjs +7 -0
  9. package/dist/cjs/components/procaptchaWidget.cjs +195 -0
  10. package/dist/cjs/index.cjs +8 -0
  11. package/dist/cjs/services/Manager.cjs +218 -0
  12. package/dist/components/audioPlayer.d.ts +18 -0
  13. package/dist/components/audioPlayer.d.ts.map +1 -0
  14. package/dist/components/audioPlayer.js +275 -0
  15. package/dist/components/audioPlayer.js.map +1 -0
  16. package/dist/components/procaptchaAudio.d.ts +7 -0
  17. package/dist/components/procaptchaAudio.d.ts.map +1 -0
  18. package/dist/components/procaptchaAudio.js +6 -0
  19. package/dist/components/procaptchaAudio.js.map +1 -0
  20. package/dist/components/procaptchaWidget.d.ts +7 -0
  21. package/dist/components/procaptchaWidget.d.ts.map +1 -0
  22. package/dist/components/procaptchaWidget.js +195 -0
  23. package/dist/components/procaptchaWidget.js.map +1 -0
  24. package/dist/index.d.ts +4 -0
  25. package/dist/index.d.ts.map +1 -0
  26. package/dist/index.js +5 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/services/Manager.d.ts +10 -0
  29. package/dist/services/Manager.d.ts.map +1 -0
  30. package/dist/services/Manager.js +217 -0
  31. package/dist/services/Manager.js.map +1 -0
  32. package/dist/tests/audioPlayer.unit.test.d.ts +2 -0
  33. package/dist/tests/audioPlayer.unit.test.d.ts.map +1 -0
  34. package/dist/tests/audioPlayer.unit.test.js +341 -0
  35. package/dist/tests/audioPlayer.unit.test.js.map +1 -0
  36. package/dist/tests/domHarness.d.ts +20 -0
  37. package/dist/tests/domHarness.d.ts.map +1 -0
  38. package/dist/tests/domHarness.js +56 -0
  39. package/dist/tests/domHarness.js.map +1 -0
  40. package/dist/tests/manager.unit.test.d.ts +2 -0
  41. package/dist/tests/manager.unit.test.d.ts.map +1 -0
  42. package/dist/tests/manager.unit.test.js +627 -0
  43. package/dist/tests/manager.unit.test.js.map +1 -0
  44. package/dist/tests/managerHarness.d.ts +21 -0
  45. package/dist/tests/managerHarness.d.ts.map +1 -0
  46. package/dist/tests/managerHarness.js +67 -0
  47. package/dist/tests/managerHarness.js.map +1 -0
  48. package/dist/tests/procaptchaAudio.test-d.d.ts +2 -0
  49. package/dist/tests/procaptchaAudio.test-d.d.ts.map +1 -0
  50. package/dist/tests/procaptchaAudio.test-d.js +103 -0
  51. package/dist/tests/procaptchaAudio.test-d.js.map +1 -0
  52. package/dist/tests/procaptchaAudio.unit.test.d.ts +2 -0
  53. package/dist/tests/procaptchaAudio.unit.test.d.ts.map +1 -0
  54. package/dist/tests/procaptchaAudio.unit.test.js +93 -0
  55. package/dist/tests/procaptchaAudio.unit.test.js.map +1 -0
  56. package/dist/tests/procaptchaWidget.unit.test.d.ts +2 -0
  57. package/dist/tests/procaptchaWidget.unit.test.d.ts.map +1 -0
  58. package/dist/tests/procaptchaWidget.unit.test.js +597 -0
  59. package/dist/tests/procaptchaWidget.unit.test.js.map +1 -0
  60. package/dist/tests/setup.d.ts +2 -0
  61. package/dist/tests/setup.d.ts.map +1 -0
  62. package/dist/tests/setup.js +12 -0
  63. package/dist/tests/setup.js.map +1 -0
  64. package/package.json +70 -3
  65. package/vite.cjs.config.ts +22 -0
  66. package/vite.esm.config.ts +20 -0
  67. package/vite.test.config.ts +26 -0
  68. package/README.md +0 -3
@@ -0,0 +1,275 @@
1
+ let _prosopo_procaptcha_common = require("@prosopo/procaptcha-common");
2
+ //#region src/components/audioPlayer.ts
3
+ var CONTAINER_WIDTH = 320;
4
+ var SHAKE_MS = 500;
5
+ var SHAKE_KEYFRAMES = `
6
+ @keyframes prosopo-audio-shake {
7
+ 0%, 100% { transform: translateX(0); }
8
+ 10%, 30%, 50%, 70%, 90% { transform: translateX(-4px); }
9
+ 20%, 40%, 60%, 80% { transform: translateX(4px); }
10
+ }
11
+ `;
12
+ var VISUALLY_HIDDEN = {
13
+ position: "absolute",
14
+ width: "1px",
15
+ height: "1px",
16
+ overflow: "hidden",
17
+ clip: "rect(0 0 0 0)",
18
+ clipPath: "inset(50%)",
19
+ whiteSpace: "nowrap"
20
+ };
21
+ /**
22
+ * The audio challenge. Accessibility is its purpose, so:
23
+ * - every control is a native `<button>` or `<input>`, not a role on a div;
24
+ * - the `<audio>` element is hidden and driven by our buttons, because several
25
+ * browsers' native controls offer the clip as a download;
26
+ * - status changes go to a polite live region, since a screen-reader user
27
+ * cannot see the shake that marks a wrong answer;
28
+ * - nothing autoplays: browsers block audio without a gesture, and a blocked
29
+ * play() looks like a broken widget.
30
+ */
31
+ var mountAudioPlayer = (initialProps) => {
32
+ const teardown = new _prosopo_procaptcha_common.Teardown();
33
+ let props = initialProps;
34
+ let answer = "";
35
+ let playing = false;
36
+ let visible = false;
37
+ let shaking = false;
38
+ let shakeTimer;
39
+ let replays = 0;
40
+ let hasPlayed = false;
41
+ let events = [];
42
+ let startedAt = Date.now();
43
+ const t = (key, options) => props.translator.t(key, options);
44
+ const record = (kind) => {
45
+ events.push({
46
+ kind,
47
+ t: Date.now() - startedAt
48
+ });
49
+ };
50
+ const style = (0, _prosopo_procaptcha_common.createElement)("style", { text: SHAKE_KEYFRAMES });
51
+ const instruction = (0, _prosopo_procaptcha_common.createElement)("p", { style: {
52
+ margin: 0,
53
+ fontSize: "14px"
54
+ } });
55
+ const audio = (0, _prosopo_procaptcha_common.createElement)("audio", {
56
+ attributes: { preload: "auto" },
57
+ style: { display: "none" }
58
+ });
59
+ const playButton = (0, _prosopo_procaptcha_common.createElement)("button", { attributes: { type: "button" } });
60
+ const playRow = (0, _prosopo_procaptcha_common.createElement)("div", {
61
+ style: {
62
+ display: "flex",
63
+ gap: "8px"
64
+ },
65
+ children: [playButton]
66
+ });
67
+ const input = (0, _prosopo_procaptcha_common.createElement)("input", { attributes: {
68
+ type: "text",
69
+ inputmode: "numeric",
70
+ autocomplete: "off",
71
+ autocorrect: "off",
72
+ autocapitalize: "off",
73
+ spellcheck: "false"
74
+ } });
75
+ const submitButton = (0, _prosopo_procaptcha_common.createElement)("button", { attributes: { type: "button" } });
76
+ const announcer = (0, _prosopo_procaptcha_common.createElement)("div", {
77
+ attributes: {
78
+ "aria-live": "polite",
79
+ "aria-atomic": "true"
80
+ },
81
+ style: VISUALLY_HIDDEN
82
+ });
83
+ if ("production" !== process.env.NODE_ENV) {
84
+ (0, _prosopo_procaptcha_common.applyAttributes)(audio, { "data-cy": "prosopo-audio-clip" });
85
+ (0, _prosopo_procaptcha_common.applyAttributes)(playButton, { "data-cy": "prosopo-audio-play" });
86
+ (0, _prosopo_procaptcha_common.applyAttributes)(input, { "data-cy": "prosopo-audio-answer" });
87
+ (0, _prosopo_procaptcha_common.applyAttributes)(submitButton, { "data-cy": "prosopo-audio-submit" });
88
+ }
89
+ const panel = (0, _prosopo_procaptcha_common.createElement)("div", {
90
+ style: {
91
+ position: "relative",
92
+ display: "flex",
93
+ flexDirection: "column",
94
+ gap: "14px",
95
+ width: `${CONTAINER_WIDTH}px`,
96
+ boxSizing: "border-box",
97
+ padding: "20px",
98
+ borderRadius: "20px",
99
+ transition: "opacity 0.3s ease, transform 0.3s ease"
100
+ },
101
+ children: [
102
+ instruction,
103
+ audio,
104
+ playRow,
105
+ input,
106
+ submitButton,
107
+ announcer
108
+ ]
109
+ });
110
+ const surfaceProps = () => ({
111
+ show: true,
112
+ placement: props.placement,
113
+ anchor: props.anchor,
114
+ onDismiss: props.onDismiss,
115
+ scrim: visible ? "dim" : "none",
116
+ dialogLabel: t("WIDGET.AUDIO_CHALLENGE_LABEL")
117
+ });
118
+ const surface = (0, _prosopo_procaptcha_common.mountChallengeSurface)(surfaceProps());
119
+ surface.content.append(style, panel);
120
+ const announce = (message) => {
121
+ announcer.textContent = message;
122
+ };
123
+ const playLabel = () => {
124
+ if (playing) return t("WIDGET.AUDIO_PLAYING");
125
+ return hasPlayed || answer.length > 0 ? t("WIDGET.AUDIO_REPLAY") : t("WIDGET.AUDIO_PLAY");
126
+ };
127
+ const render = () => {
128
+ const { theme, showRetry, submitting, characterCount } = props;
129
+ const accent = showRetry ? theme.palette.error.main : theme.palette.primary.main;
130
+ const blocked = submitting || 0 === answer.length;
131
+ const buttonStyle = {
132
+ fontFamily: theme.font.fontFamily,
133
+ fontSize: "14px",
134
+ padding: "10px 16px",
135
+ borderRadius: "8px",
136
+ border: `1px solid ${accent}`,
137
+ backgroundColor: "transparent",
138
+ color: accent,
139
+ cursor: "pointer"
140
+ };
141
+ (0, _prosopo_procaptcha_common.applyStyles)(panel, {
142
+ backgroundColor: theme.palette.surface,
143
+ color: theme.palette.onSurface,
144
+ fontFamily: theme.font.fontFamily,
145
+ opacity: visible ? 1 : 0,
146
+ transform: visible ? "scale(1)" : "scale(0.9)",
147
+ animation: shaking ? `prosopo-audio-shake ${SHAKE_MS}ms ease` : "none"
148
+ });
149
+ instruction.textContent = showRetry ? t("WIDGET.AUDIO_INCORRECT") : t("WIDGET.AUDIO_INSTRUCTIONS", { count: characterCount });
150
+ (0, _prosopo_procaptcha_common.applyStyles)(instruction, { color: showRetry ? theme.palette.error.main : theme.palette.onSurface });
151
+ if (audio.getAttribute("src") !== props.clip) audio.setAttribute("src", props.clip);
152
+ playButton.textContent = playLabel();
153
+ (0, _prosopo_procaptcha_common.applyStyles)(playButton, {
154
+ ...buttonStyle,
155
+ flex: 1
156
+ });
157
+ input.maxLength = characterCount * 2;
158
+ input.disabled = submitting;
159
+ if (input.value !== answer) input.value = answer;
160
+ (0, _prosopo_procaptcha_common.applyAttributes)(input, { "aria-label": t("WIDGET.AUDIO_INPUT_LABEL", { count: characterCount }) });
161
+ (0, _prosopo_procaptcha_common.applyStyles)(input, {
162
+ fontFamily: theme.font.fontFamily,
163
+ fontSize: "18px",
164
+ letterSpacing: "0.3em",
165
+ textAlign: "center",
166
+ padding: "10px",
167
+ borderRadius: "8px",
168
+ border: `1px solid ${accent}`,
169
+ backgroundColor: "transparent",
170
+ color: theme.palette.onSurface
171
+ });
172
+ submitButton.textContent = submitting ? t("WIDGET.AUDIO_CHECKING") : t("WIDGET.AUDIO_SUBMIT");
173
+ submitButton.disabled = blocked;
174
+ (0, _prosopo_procaptcha_common.applyStyles)(submitButton, {
175
+ ...buttonStyle,
176
+ backgroundColor: theme.palette.primary.main,
177
+ borderColor: theme.palette.primary.main,
178
+ color: theme.palette.primary.contrastText,
179
+ opacity: blocked ? .5 : 1,
180
+ cursor: blocked ? "not-allowed" : "pointer"
181
+ });
182
+ surface.update(surfaceProps());
183
+ };
184
+ const play = () => {
185
+ const isReplay = hasPlayed;
186
+ audio.currentTime = 0;
187
+ record(isReplay ? "replay" : "play");
188
+ if (isReplay) replays += 1;
189
+ hasPlayed = true;
190
+ const clipAtPlay = props.clip;
191
+ audio.play().then(() => {
192
+ if (clipAtPlay !== props.clip) return;
193
+ playing = true;
194
+ announce(t("WIDGET.AUDIO_PLAYING"));
195
+ render();
196
+ }, () => {
197
+ playing = false;
198
+ announce(t("WIDGET.AUDIO_PLAYBACK_FAILED"));
199
+ render();
200
+ });
201
+ render();
202
+ };
203
+ const submit = () => {
204
+ if (props.submitting || 0 === answer.length) return;
205
+ props.onComplete(answer, replays, [...events]);
206
+ };
207
+ teardown.addEventListener(playButton, "click", play);
208
+ teardown.addEventListener(submitButton, "click", submit);
209
+ teardown.addEventListener(input, "input", () => {
210
+ record("key");
211
+ answer = input.value;
212
+ render();
213
+ });
214
+ teardown.addEventListener(input, "keydown", (event) => {
215
+ if (!(event instanceof KeyboardEvent) || "Enter" !== event.key) return;
216
+ event.preventDefault();
217
+ submit();
218
+ });
219
+ teardown.addEventListener(audio, "ended", () => {
220
+ playing = false;
221
+ announce(t("WIDGET.AUDIO_FINISHED"));
222
+ render();
223
+ });
224
+ teardown.addEventListener(audio, "pause", () => {
225
+ playing = false;
226
+ render();
227
+ });
228
+ const resetForNewClip = () => {
229
+ audio.pause();
230
+ audio.currentTime = 0;
231
+ answer = "";
232
+ playing = false;
233
+ replays = 0;
234
+ hasPlayed = false;
235
+ events = [];
236
+ startedAt = Date.now();
237
+ };
238
+ const startShake = () => {
239
+ shaking = true;
240
+ announce(t("WIDGET.AUDIO_INCORRECT"));
241
+ if (void 0 !== shakeTimer) clearTimeout(shakeTimer);
242
+ shakeTimer = setTimeout(() => {
243
+ shakeTimer = void 0;
244
+ shaking = false;
245
+ render();
246
+ }, SHAKE_MS);
247
+ };
248
+ teardown.add(() => {
249
+ if (void 0 !== shakeTimer) clearTimeout(shakeTimer);
250
+ });
251
+ if (props.showRetry) startShake();
252
+ render();
253
+ input.focus();
254
+ const frameRequest = requestAnimationFrame(() => {
255
+ visible = true;
256
+ render();
257
+ });
258
+ teardown.add(() => cancelAnimationFrame(frameRequest));
259
+ return {
260
+ update: (nextProps) => {
261
+ const previous = props;
262
+ props = nextProps;
263
+ if (nextProps.clip !== previous.clip) resetForNewClip();
264
+ if (nextProps.showRetry && !previous.showRetry) startShake();
265
+ render();
266
+ },
267
+ destroy: () => {
268
+ teardown.run();
269
+ audio.pause();
270
+ surface.destroy();
271
+ }
272
+ };
273
+ };
274
+ //#endregion
275
+ exports.mountAudioPlayer = mountAudioPlayer;
@@ -0,0 +1,7 @@
1
+ let _prosopo_procaptcha_common = require("@prosopo/procaptcha-common");
2
+ //#region src/components/procaptchaAudio.ts
3
+ var loadProcaptchaAudio = async () => (await Promise.resolve().then(() => require("./procaptchaWidget.cjs"))).mountProcaptchaAudioWidget;
4
+ var mountProcaptchaAudio = (0, _prosopo_procaptcha_common.lazyMount)(loadProcaptchaAudio);
5
+ //#endregion
6
+ exports.loadProcaptchaAudio = loadProcaptchaAudio;
7
+ exports.mountProcaptchaAudio = mountProcaptchaAudio;
@@ -0,0 +1,195 @@
1
+ const require_Manager = require("../services/Manager.cjs");
2
+ const require_audioPlayer = require("./audioPlayer.cjs");
3
+ let _prosopo_locale = require("@prosopo/locale");
4
+ let _prosopo_procaptcha_common = require("@prosopo/procaptcha-common");
5
+ let _prosopo_types = require("@prosopo/types");
6
+ let _prosopo_widget_skeleton = require("@prosopo/widget-skeleton");
7
+ //#region src/components/procaptchaWidget.ts
8
+ var mountProcaptchaAudioWidget = (container, props) => {
9
+ const teardown = new _prosopo_procaptcha_common.Teardown();
10
+ const config = props.config;
11
+ const i18n = props.i18n;
12
+ const frictionlessState = props.frictionlessState;
13
+ const callbacks = props.callbacks || {};
14
+ const translator = (0, _prosopo_locale.createTranslator)(i18n);
15
+ const isInvisible = _prosopo_types.ModeEnum.invisible === config.mode;
16
+ const theme = "light" === config.theme ? _prosopo_widget_skeleton.lightTheme : _prosopo_widget_skeleton.darkTheme;
17
+ const store = (0, _prosopo_procaptcha_common.createProcaptchaState)();
18
+ let loading = false;
19
+ let audioPhase = "checkbox";
20
+ let challengeData = null;
21
+ let showRetry = true === props.startShowRetry;
22
+ let lastError = store.state.error;
23
+ let lastCoords = null;
24
+ let sessionInvalidatedFired = false;
25
+ let honeypot;
26
+ let checkbox;
27
+ let player;
28
+ const onReload = props.onReload;
29
+ const updateState = (0, _prosopo_procaptcha_common.buildUpdateState)(store.state, store.update);
30
+ const manager = require_Manager.Manager(config, store.state, updateState, callbacks, frictionlessState, () => honeypot?.getValue(), onReload ? (x, y) => onReload(x, y, { showRetry: true }) : void 0);
31
+ const root = (0, _prosopo_procaptcha_common.createElement)("div");
32
+ container.appendChild(root);
33
+ if (frictionlessState?.hp) honeypot = (0, _prosopo_procaptcha_common.mountHoneypot)(root, { encodedQuestion: frictionlessState.hp });
34
+ const reportError = (error) => {
35
+ callbacks.onError?.(error instanceof Error ? error : new Error(String(error)));
36
+ };
37
+ const returnToCheckbox = () => {
38
+ audioPhase = "checkbox";
39
+ challengeData = null;
40
+ showRetry = false;
41
+ };
42
+ const showChallenge = (challenge) => {
43
+ if (challenge) {
44
+ challengeData = challenge;
45
+ audioPhase = "answering";
46
+ }
47
+ };
48
+ const handleAudioComplete = async (answer, replays, audioEvents) => {
49
+ audioPhase = "submitting";
50
+ scheduler.schedule();
51
+ let verified = false;
52
+ try {
53
+ verified = await manager.submitSolution(answer, replays, audioEvents);
54
+ } catch (error) {
55
+ reportError(error);
56
+ }
57
+ if (verified) {
58
+ returnToCheckbox();
59
+ loading = false;
60
+ scheduler.schedule();
61
+ return;
62
+ }
63
+ showRetry = true;
64
+ if (onReload) {
65
+ scheduler.schedule();
66
+ return;
67
+ }
68
+ audioPhase = "answering";
69
+ scheduler.schedule();
70
+ try {
71
+ const newChallenge = await manager.start();
72
+ if (newChallenge) challengeData = newChallenge;
73
+ else returnToCheckbox();
74
+ } catch {
75
+ returnToCheckbox();
76
+ }
77
+ loading = false;
78
+ scheduler.schedule();
79
+ };
80
+ const handleDismiss = () => {
81
+ returnToCheckbox();
82
+ loading = false;
83
+ scheduler.schedule();
84
+ };
85
+ const playerProps = (challenge) => ({
86
+ clip: challenge.clip,
87
+ characterCount: challenge.characterCount,
88
+ onComplete: (answer, replays, events) => {
89
+ handleAudioComplete(answer, replays, events);
90
+ },
91
+ showRetry,
92
+ submitting: "submitting" === audioPhase,
93
+ theme,
94
+ translator,
95
+ placement: config.placement,
96
+ anchor: props.container,
97
+ onDismiss: handleDismiss
98
+ });
99
+ const runErrorEffect = () => {
100
+ if (store.state.error === lastError) return;
101
+ lastError = store.state.error;
102
+ if (!store.state.error) return;
103
+ loading = false;
104
+ returnToCheckbox();
105
+ if ("CAPTCHA.NO_SESSION_FOUND" !== store.state.error.key) return;
106
+ if (props.onSessionInvalidated && !sessionInvalidatedFired || void 0 !== frictionlessState) {
107
+ loading = true;
108
+ store.update({ error: void 0 });
109
+ }
110
+ if (props.onSessionInvalidated && !sessionInvalidatedFired) {
111
+ sessionInvalidatedFired = true;
112
+ props.onSessionInvalidated(lastCoords?.x, lastCoords?.y);
113
+ return;
114
+ }
115
+ if (frictionlessState) {
116
+ const timer = setTimeout(() => {
117
+ frictionlessState.restart();
118
+ }, 100);
119
+ teardown.add(() => clearTimeout(timer));
120
+ }
121
+ };
122
+ const render = () => {
123
+ runErrorEffect();
124
+ if (("answering" === audioPhase || "submitting" === audioPhase) && null !== challengeData) if (void 0 === player) player = require_audioPlayer.mountAudioPlayer(playerProps(challengeData));
125
+ else player.update(playerProps(challengeData));
126
+ else {
127
+ player?.destroy();
128
+ player = void 0;
129
+ }
130
+ checkbox?.update(checkboxProps());
131
+ };
132
+ const scheduler = (0, _prosopo_procaptcha_common.createRenderScheduler)(render);
133
+ const beginChallenge = async (coords) => {
134
+ if (loading) return;
135
+ loading = true;
136
+ showRetry = false;
137
+ scheduler.schedule();
138
+ if (coords) lastCoords = coords;
139
+ try {
140
+ showChallenge(await manager.start(coords?.x, coords?.y));
141
+ } catch (error) {
142
+ reportError(error);
143
+ } finally {
144
+ loading = false;
145
+ scheduler.schedule();
146
+ }
147
+ };
148
+ const checkboxProps = () => ({
149
+ checked: store.state.isHuman,
150
+ theme,
151
+ labelText: translator.isReady() ? translator.t("WIDGET.I_AM_HUMAN") : "",
152
+ error: store.state.error ? (0, _prosopo_locale.localiseErrorMessage)(translator.i18n, store.state.error) : void 0,
153
+ loadingText: translator.t("WIDGET.CHECKING", { defaultValue: "Checking that you are human" }),
154
+ loading: loading || "submitting" === audioPhase,
155
+ onChange: (event) => beginChallenge((0, _prosopo_procaptcha_common.trustedClickCoords)(event))
156
+ });
157
+ if (!isInvisible) checkbox = (0, _prosopo_procaptcha_common.mountCheckbox)(root, checkboxProps());
158
+ teardown.add(scheduler.cancel);
159
+ teardown.add(store.subscribe(scheduler.schedule));
160
+ teardown.add(translator.subscribe(scheduler.schedule));
161
+ const handleExecute = () => {
162
+ beginChallenge();
163
+ };
164
+ if (props.container) teardown.addEventListener(props.container, _prosopo_procaptcha_common.PROCAPTCHA_EXECUTE_EVENT, handleExecute);
165
+ if (isInvisible) teardown.addEventListener(document, _prosopo_procaptcha_common.PROCAPTCHA_EXECUTE_EVENT, handleExecute);
166
+ if (config.language) if (i18n) {
167
+ if (i18n.language !== config.language) i18n.changeLanguage(config.language);
168
+ } else (0, _prosopo_locale.loadI18next)(false, config.language);
169
+ if (props.autoStart) {
170
+ loading = true;
171
+ const coords = props.startCoords;
172
+ lastCoords = coords ?? null;
173
+ scheduler.schedule();
174
+ manager.start(coords?.x ?? 0, coords?.y ?? 0).then((challenge) => {
175
+ showChallenge(challenge);
176
+ loading = false;
177
+ scheduler.schedule();
178
+ }, () => {
179
+ loading = false;
180
+ scheduler.schedule();
181
+ });
182
+ }
183
+ render();
184
+ return { destroy: () => {
185
+ manager.dispose();
186
+ teardown.run();
187
+ player?.destroy();
188
+ checkbox?.destroy();
189
+ honeypot?.destroy();
190
+ root.parentNode?.removeChild(root);
191
+ } };
192
+ };
193
+ //#endregion
194
+ exports.default = mountProcaptchaAudioWidget;
195
+ exports.mountProcaptchaAudioWidget = mountProcaptchaAudioWidget;
@@ -0,0 +1,8 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_audioPlayer = require("./components/audioPlayer.cjs");
3
+ const require_procaptchaWidget = require("./components/procaptchaWidget.cjs");
4
+ const require_procaptchaAudio = require("./components/procaptchaAudio.cjs");
5
+ exports.loadProcaptchaAudio = require_procaptchaAudio.loadProcaptchaAudio;
6
+ exports.mountAudioPlayer = require_audioPlayer.mountAudioPlayer;
7
+ exports.mountProcaptchaAudio = require_procaptchaAudio.mountProcaptchaAudio;
8
+ exports.mountProcaptchaAudioWidget = require_procaptchaWidget.default;