为 linux.do 编辑器提供语音录制、上传与播放能力。
// ==UserScript==
// @name linux-do-voice-msg
// @namespace https://github.com/chenyu5/linux-do-voice-msg
// @version 1.0.6
// @author helloai
// @description 为 linux.do 编辑器提供语音录制、上传与播放能力。
// @license MIT
// @match https://linux.do/*
// @grant none
// ==/UserScript==
(function () {
'use strict';
const d=new Set;const importCSS = async e=>{d.has(e)||(d.add(e),(t=>{typeof GM_addStyle=="function"?GM_addStyle(t):(document.head||document.documentElement).appendChild(document.createElement("style")).append(t);})(e));};
importCSS(' .ldv-wave-canvas.svelte-b21gtz{display:block;width:100%;background:transparent}.ldv-composer-recorder-shell.svelte-1vayy8g{display:grid;gap:8px;width:100%;min-width:0;box-sizing:border-box;font-family:var(--ldv-font-family)}.ldv-recorder-placeholder.svelte-1vayy8g,.ldv-composer-recorder.svelte-1vayy8g{display:grid;grid-template-columns:auto minmax(0,1fr) auto auto auto auto;align-items:center;gap:10px;width:100%;max-width:560px;min-height:62px;padding:8px 12px;border:1px solid var(--ldv-outline);border-radius:22px;box-sizing:border-box;background:var(--ldv-surface);box-shadow:var(--ldv-shadow-soft);color:var(--ldv-text)}.ldv-recorder-placeholder.svelte-1vayy8g{grid-template-columns:minmax(0,1fr) auto auto;color:var(--ldv-muted)}.ldv-recorder-wave-slot.svelte-1vayy8g{min-width:0}.ldv-recorder-wave-slot.is-placeholder.svelte-1vayy8g{opacity:.82}.ldv-placeholder-text.svelte-1vayy8g{white-space:nowrap;font-size:.84rem;color:var(--ldv-muted)}.ldv-placeholder-icon.svelte-1vayy8g{width:24px;height:24px;display:inline-flex;color:var(--ldv-accent)}.ldv-placeholder-icon.svelte-1vayy8g svg:where(.svelte-1vayy8g){width:100%;height:100%}.ldv-recorder-primary.svelte-1vayy8g{width:38px;height:38px;display:inline-flex;align-items:center;justify-content:center;border:none;border-radius:999px;background:var(--ldv-accent);color:var(--secondary);box-shadow:0 8px 16px color-mix(in srgb,var(--ldv-accent) 20%,transparent);cursor:pointer;transition:transform .16s ease,opacity .16s ease,box-shadow .16s ease}.ldv-recorder-primary.svelte-1vayy8g:hover:not(:disabled),.ldv-recorder-send.svelte-1vayy8g:hover:not(:disabled),.ldv-recorder-icon-button.svelte-1vayy8g:hover:not(:disabled){transform:translateY(-1px)}.ldv-recorder-primary.svelte-1vayy8g:disabled,.ldv-recorder-send.svelte-1vayy8g:disabled,.ldv-recorder-icon-button.svelte-1vayy8g:disabled{opacity:.5;cursor:not-allowed}.ldv-recorder-primary.svelte-1vayy8g svg:where(.svelte-1vayy8g){width:18px;height:18px}.ldv-recorder-duration.svelte-1vayy8g{min-width:64px;text-align:center;font-size:.84rem;font-weight:600;color:var(--ldv-accent);white-space:nowrap}.ldv-recorder-duration.ldv-near-limit.svelte-1vayy8g{color:var(--ldv-danger)}.ldv-recorder-icon-button.svelte-1vayy8g,.ldv-recorder-send.svelte-1vayy8g{width:40px;height:40px;display:inline-flex;align-items:center;justify-content:center;border:1px solid var(--ldv-outline);border-radius:999px;background:var(--ldv-surface-muted);color:var(--ldv-muted);cursor:pointer;transition:transform .16s ease,color .16s ease,background-color .16s ease}.ldv-recorder-icon-button.svelte-1vayy8g:hover:not(:disabled){border-color:color-mix(in srgb,var(--ldv-danger) 18%,transparent);background:color-mix(in srgb,var(--secondary) 84%,var(--danger) 16%)}.ldv-recorder-send.svelte-1vayy8g{color:var(--ldv-accent)}.ldv-recorder-icon-button.ldv-recorder-delete.svelte-1vayy8g{color:var(--ldv-danger);border-color:color-mix(in srgb,var(--ldv-danger) 16%,transparent)}.ldv-recorder-icon-button.ldv-recorder-delete.svelte-1vayy8g:hover:not(:disabled){color:var(--ldv-danger)}.ldv-send-spinner-svg.svelte-1vayy8g{width:20px;height:20px}.ldv-recorder-icon-image.svelte-1vayy8g{display:block;width:20px;height:20px;object-fit:contain;flex:none}.ldv-recorder-delete-image.svelte-1vayy8g{width:22px;height:22px}.ldv-recorder-send-image.svelte-1vayy8g{width:20px;height:20px}.ldv-recorder-send.svelte-1vayy8g:hover:not(:disabled){border-color:color-mix(in srgb,var(--ldv-accent) 22%,transparent);background:color-mix(in srgb,var(--secondary) 82%,var(--tertiary) 18%)}.ldv-recorder-divider.svelte-1vayy8g{width:1px;height:24px;background:color-mix(in srgb,var(--primary) 12%,transparent)}.ldv-composer-recorder.is-paused.svelte-1vayy8g .ldv-recorder-wave-slot:where(.svelte-1vayy8g){opacity:.86}.ldv-composer-recorder.is-uploading.svelte-1vayy8g{opacity:.92}.ldv-send-spinner-svg.svelte-1vayy8g{animation:svelte-1vayy8g-ldv-spin .8s linear infinite}.ldv-recorder-feedback.svelte-1vayy8g{margin:0 8px;font-size:.78rem;color:color-mix(in srgb,var(--primary) 64%,transparent)}@keyframes svelte-1vayy8g-ldv-spin{to{transform:rotate(360deg)}}@media(max-width:720px){.ldv-recorder-placeholder.svelte-1vayy8g,.ldv-composer-recorder.svelte-1vayy8g{width:100%;gap:8px;padding:8px 10px;min-height:58px}.ldv-recorder-duration.svelte-1vayy8g{min-width:56px;font-size:.8rem}}@media(max-width:560px){.ldv-recorder-placeholder.svelte-1vayy8g,.ldv-composer-recorder.svelte-1vayy8g{grid-template-columns:auto minmax(0,1fr) auto auto auto;gap:8px}.ldv-recorder-duration.svelte-1vayy8g{grid-column:3}.ldv-recorder-divider.svelte-1vayy8g{display:none}.ldv-recorder-send.svelte-1vayy8g{grid-column:5}}@media(max-width:480px){.ldv-recorder-placeholder.svelte-1vayy8g{grid-template-columns:1fr auto}.ldv-placeholder-text.svelte-1vayy8g{display:none}.ldv-composer-recorder.svelte-1vayy8g{grid-template-columns:auto minmax(0,1fr) auto auto;row-gap:10px}.ldv-recorder-duration.svelte-1vayy8g{grid-column:3 / 5;justify-self:end}.ldv-recorder-icon-button.svelte-1vayy8g{grid-column:3}.ldv-recorder-send.svelte-1vayy8g{grid-column:4}}.ldv-toolbar-button.svelte-7pay83{position:relative;display:inline-flex;align-items:center;justify-content:center;width:var(--button-height);height:var(--button-height);border:none;border-radius:var(--d-border-radius);background:transparent;color:var(--ldv-muted);box-shadow:none;cursor:pointer;transition:transform .16s ease,background-color .16s ease,opacity .16s ease}.ldv-toolbar-button.svelte-7pay83:hover:not(:disabled){transform:translateY(-1px);background:var(--d-hover)}.ldv-toolbar-button.svelte-7pay83:disabled{cursor:not-allowed}.ldv-toolbar-button.is-recording.svelte-7pay83{animation:svelte-7pay83-ldv-pulse 1.2s ease-in-out infinite}.ldv-toolbar-button.is-uploading.svelte-7pay83{opacity:.78}.ldv-toolbar-button.is-uploading.svelte-7pay83:after{content:"";position:absolute;inset:4px;border:2px solid color-mix(in srgb,var(--ldv-accent) 18%,transparent);border-top-color:currentColor;border-radius:999px;animation:svelte-7pay83-ldv-spin .9s linear infinite}.ldv-toolbar-icon.svelte-7pay83{width:1.28em;height:1.28em;display:inline-flex}.ldv-toolbar-image.svelte-7pay83{width:100%;height:100%;display:block;object-fit:contain}.ldv-toolbar-button.is-recording.svelte-7pay83 .ldv-toolbar-image:where(.svelte-7pay83){transform:scale(1.03)}.ldv-toolbar-button.is-uploading.svelte-7pay83 .ldv-toolbar-image:where(.svelte-7pay83){opacity:.4}@keyframes svelte-7pay83-ldv-pulse{0%,to{box-shadow:0 0 color-mix(in srgb,var(--ldv-accent) 0%,transparent)}55%{box-shadow:0 0 0 5px color-mix(in srgb,var(--ldv-accent) 14%,transparent)}}@keyframes svelte-7pay83-ldv-spin{to{transform:rotate(360deg)}}.ldv-player-wrap.svelte-19h8psz{display:inline-grid;gap:6px;width:min(100%,420px);max-width:100%;font-family:var(--ldv-font-family);color:var(--ldv-player-text);vertical-align:middle}.ldv-player-card.svelte-19h8psz{display:grid;gap:0;border:1px solid var(--ldv-player-outline);border-radius:22px;background:var(--ldv-player-bg);box-shadow:var(--ldv-player-shadow);transition:background-color .16s ease,border-color .16s ease,box-shadow .16s ease}.ldv-player-card.is-playing.svelte-19h8psz{background:var(--ldv-player-bg-active);box-shadow:0 8px 18px color-mix(in srgb,var(--ldv-accent) 10%,transparent)}.ldv-player-card.is-paused.svelte-19h8psz{border-style:dashed}.ldv-player-primary.svelte-19h8psz{display:grid;grid-template-columns:auto minmax(0,1fr) auto auto;align-items:center;gap:10px;min-height:56px;padding:8px 12px}.ldv-player-secondary.svelte-19h8psz{display:grid;gap:8px;padding:8px 12px 10px;border-top:1px solid color-mix(in srgb,var(--ldv-player-outline) 76%,transparent)}.ldv-player-secondary.is-compact.svelte-19h8psz{gap:0;padding-top:5px;padding-bottom:6px}.ldv-player-secondary-body.svelte-19h8psz{display:grid;gap:6px;min-height:0}.ldv-player-main.svelte-19h8psz,.ldv-player-replay.svelte-19h8psz{width:34px;height:34px;display:inline-flex;align-items:center;justify-content:center;border-radius:999px;cursor:pointer;transition:transform .16s ease,border-color .16s ease,background-color .16s ease,color .16s ease,opacity .16s ease}.ldv-player-main.svelte-19h8psz:hover:not(:disabled),.ldv-player-replay.svelte-19h8psz:hover:not(:disabled){transform:translateY(-1px)}.ldv-player-main.svelte-19h8psz:disabled,.ldv-player-replay.svelte-19h8psz:disabled{opacity:.58;cursor:not-allowed}.ldv-player-main.svelte-19h8psz{border:none;background:var(--ldv-accent);color:var(--secondary)}.ldv-player-replay.svelte-19h8psz{border:1px solid var(--ldv-player-outline);background:var(--ldv-surface-muted);color:var(--ldv-accent);border-radius:12px}.ldv-player-main.svelte-19h8psz svg:where(.svelte-19h8psz),.ldv-player-spinner-svg.svelte-19h8psz{width:18px;height:18px}.ldv-player-replay-image.svelte-19h8psz{display:block;width:20px;height:20px;object-fit:contain;flex:none}.ldv-player-spinner-svg.svelte-19h8psz{animation:svelte-19h8psz-ldv-player-spin .8s linear infinite}.ldv-player-waveform.svelte-19h8psz{display:flex;align-items:center;gap:3px;min-width:0;height:28px;overflow:hidden}.ldv-player-bar.svelte-19h8psz{flex:1 1 0;min-width:3px;border-radius:999px;background:var(--ldv-wave-inactive);transition:background-color .12s ease}.ldv-player-bar.is-played.svelte-19h8psz{background:var(--ldv-wave-color)}.ldv-player-time.svelte-19h8psz{min-width:72px;text-align:right;font-size:.82rem;font-weight:600;color:var(--ldv-accent);white-space:nowrap}.ldv-player-error.svelte-19h8psz{margin:0;font-size:.76rem;color:var(--ldv-danger)}.ldv-player-transcript-panel.svelte-19h8psz{display:grid;gap:6px}.ldv-player-transcript-actions.svelte-19h8psz{display:inline-flex;align-items:center;justify-self:end;gap:10px;min-height:20px}.ldv-player-transcript-action.svelte-19h8psz{padding:0;display:inline-flex;align-items:center;justify-content:center;border:none;background:transparent;color:var(--ldv-accent);font-size:.78rem;font-weight:600;cursor:pointer;line-height:1.4;transition:color .16s ease,opacity .16s ease,text-decoration-color .16s ease}.ldv-player-transcript-action.svelte-19h8psz:hover:not(:disabled){text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:3px}.ldv-player-transcript-toggle.svelte-19h8psz{width:18px;height:18px;flex:none}.ldv-player-transcript-toggle.svelte-19h8psz:hover:not(:disabled){text-decoration:none}.ldv-player-transcript-toggle-icon.svelte-19h8psz{display:block;width:18px;height:18px;object-fit:contain}.ldv-player-transcript-action.svelte-19h8psz:disabled{opacity:.58;cursor:not-allowed;text-decoration:none}.ldv-player-transcript-note.svelte-19h8psz,.ldv-player-transcript-content.svelte-19h8psz{margin:0;font-size:.78rem;line-height:1.55}.ldv-player-transcript-note.svelte-19h8psz{color:var(--ldv-muted)}.ldv-player-transcript-note.is-error.svelte-19h8psz{color:var(--ldv-danger)}.ldv-player-transcript-content.svelte-19h8psz{color:var(--ldv-player-text);white-space:pre-wrap;word-break:break-word}.ldv-player-transcript-content.is-collapsed.svelte-19h8psz{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.ldv-player-transcript-content.is-pending.svelte-19h8psz{color:color-mix(in srgb,var(--ldv-player-text) 78%,var(--ldv-muted) 22%)}@keyframes svelte-19h8psz-ldv-player-spin{to{transform:rotate(360deg)}}@media(max-width:520px){.ldv-player-wrap.svelte-19h8psz{width:min(100%,360px)}.ldv-player-card.svelte-19h8psz{border-radius:20px}.ldv-player-primary.svelte-19h8psz{gap:8px;padding:8px 10px}.ldv-player-secondary.svelte-19h8psz{padding:8px 10px 10px}.ldv-player-secondary.is-compact.svelte-19h8psz{padding-top:4px;padding-bottom:5px}.ldv-player-time.svelte-19h8psz{min-width:64px;font-size:.78rem}.ldv-player-transcript-actions.svelte-19h8psz{gap:8px}}@media(max-width:420px){.ldv-player-card.svelte-19h8psz{gap:0}.ldv-player-primary.svelte-19h8psz{grid-template-columns:auto minmax(0,1fr) auto auto;gap:6px;padding:7px 8px}.ldv-player-main.svelte-19h8psz,.ldv-player-replay.svelte-19h8psz{width:32px;height:32px}.ldv-player-main.svelte-19h8psz svg:where(.svelte-19h8psz),.ldv-player-spinner-svg.svelte-19h8psz{width:16px;height:16px}.ldv-player-replay-image.svelte-19h8psz{width:18px;height:18px}.ldv-player-waveform.svelte-19h8psz{gap:2px;height:26px}.ldv-player-bar.svelte-19h8psz{min-width:2px}.ldv-player-time.svelte-19h8psz{min-width:56px;font-size:.76rem}} ');
const appCss = ':root{--ldv-font-family: "IBM Plex Sans", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;--ldv-surface: color-mix(in srgb, var(--secondary) 96%, var(--header_background) 4%);--ldv-surface-muted: color-mix(in srgb, var(--secondary) 90%, var(--header_background) 10%);--ldv-outline: color-mix(in srgb, var(--primary) 12%, transparent);--ldv-shadow-soft: 0 8px 18px color-mix(in srgb, var(--primary) 8%, transparent);--ldv-text: var(--primary);--ldv-muted: color-mix(in srgb, var(--primary) 56%, transparent);--ldv-danger: var(--danger);--ldv-accent: var(--tertiary);--ldv-wave-color: var(--tertiary);--ldv-wave-inactive: color-mix(in srgb, var(--primary) 14%, var(--secondary) 86%);--ldv-player-bg: var(--ldv-surface);--ldv-player-bg-active: color-mix(in srgb, var(--secondary) 86%, var(--highlight) 14%);--ldv-player-outline: var(--ldv-outline);--ldv-player-text: var(--primary);--ldv-player-shadow: var(--ldv-shadow-soft)}.ldv-toolbar-button-slot{display:inline-flex;align-items:center}.ldv-inline-recorder-host{width:100%;min-width:0;box-sizing:border-box;margin:8px 0 6px}.ldv-voice-player-host{display:inline-flex;width:auto;min-width:0;max-width:100%;vertical-align:middle}';
importCSS(appCss);
const DEV = false;
var is_array = Array.isArray;
var index_of = Array.prototype.indexOf;
var includes = Array.prototype.includes;
var array_from = Array.from;
var define_property = Object.defineProperty;
var get_descriptor = Object.getOwnPropertyDescriptor;
var get_descriptors = Object.getOwnPropertyDescriptors;
var object_prototype = Object.prototype;
var array_prototype = Array.prototype;
var get_prototype_of = Object.getPrototypeOf;
var is_extensible = Object.isExtensible;
const noop = () => {
};
function run(fn) {
return fn();
}
function run_all(arr) {
for (var i = 0; i < arr.length; i++) {
arr[i]();
}
}
function deferred() {
var resolve;
var reject;
var promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
return { promise, resolve, reject };
}
const DERIVED = 1 << 1;
const EFFECT = 1 << 2;
const RENDER_EFFECT = 1 << 3;
const MANAGED_EFFECT = 1 << 24;
const BLOCK_EFFECT = 1 << 4;
const BRANCH_EFFECT = 1 << 5;
const ROOT_EFFECT = 1 << 6;
const BOUNDARY_EFFECT = 1 << 7;
const CONNECTED = 1 << 9;
const CLEAN = 1 << 10;
const DIRTY = 1 << 11;
const MAYBE_DIRTY = 1 << 12;
const INERT = 1 << 13;
const DESTROYED = 1 << 14;
const REACTION_RAN = 1 << 15;
const EFFECT_TRANSPARENT = 1 << 16;
const EAGER_EFFECT = 1 << 17;
const HEAD_EFFECT = 1 << 18;
const EFFECT_PRESERVED = 1 << 19;
const USER_EFFECT = 1 << 20;
const EFFECT_OFFSCREEN = 1 << 25;
const WAS_MARKED = 1 << 16;
const REACTION_IS_UPDATING = 1 << 21;
const ASYNC = 1 << 22;
const ERROR_VALUE = 1 << 23;
const STATE_SYMBOL = Symbol("$state");
const LEGACY_PROPS = Symbol("legacy props");
const LOADING_ATTR_SYMBOL = Symbol("");
const STALE_REACTION = new class StaleReactionError extends Error {
name = "StaleReactionError";
message = "The reaction that called `getAbortSignal()` was re-run or destroyed";
}();
function lifecycle_outside_component(name) {
{
throw new Error(`https://svelte.dev/e/lifecycle_outside_component`);
}
}
function async_derived_orphan() {
{
throw new Error(`https://svelte.dev/e/async_derived_orphan`);
}
}
function each_key_duplicate(a, b, value) {
{
throw new Error(`https://svelte.dev/e/each_key_duplicate`);
}
}
function effect_in_teardown(rune) {
{
throw new Error(`https://svelte.dev/e/effect_in_teardown`);
}
}
function effect_in_unowned_derived() {
{
throw new Error(`https://svelte.dev/e/effect_in_unowned_derived`);
}
}
function effect_orphan(rune) {
{
throw new Error(`https://svelte.dev/e/effect_orphan`);
}
}
function effect_update_depth_exceeded() {
{
throw new Error(`https://svelte.dev/e/effect_update_depth_exceeded`);
}
}
function props_invalid_value(key) {
{
throw new Error(`https://svelte.dev/e/props_invalid_value`);
}
}
function state_descriptors_fixed() {
{
throw new Error(`https://svelte.dev/e/state_descriptors_fixed`);
}
}
function state_prototype_fixed() {
{
throw new Error(`https://svelte.dev/e/state_prototype_fixed`);
}
}
function state_unsafe_mutation() {
{
throw new Error(`https://svelte.dev/e/state_unsafe_mutation`);
}
}
function svelte_boundary_reset_onerror() {
{
throw new Error(`https://svelte.dev/e/svelte_boundary_reset_onerror`);
}
}
const EACH_ITEM_REACTIVE = 1;
const EACH_INDEX_REACTIVE = 1 << 1;
const EACH_ITEM_IMMUTABLE = 1 << 4;
const PROPS_IS_RUNES = 1 << 1;
const PROPS_IS_UPDATED = 1 << 2;
const PROPS_IS_BINDABLE = 1 << 3;
const TEMPLATE_FRAGMENT = 1;
const TEMPLATE_USE_IMPORT_NODE = 1 << 1;
const UNINITIALIZED = Symbol();
const NAMESPACE_HTML = "http://www.w3.org/1999/xhtml";
function svelte_boundary_reset_noop() {
{
console.warn(`https://svelte.dev/e/svelte_boundary_reset_noop`);
}
}
function equals(value) {
return value === this.v;
}
function safe_not_equal(a, b) {
return a != a ? b == b : a !== b || a !== null && typeof a === "object" || typeof a === "function";
}
function safe_equals(value) {
return !safe_not_equal(value, this.v);
}
let legacy_mode_flag = false;
let tracing_mode_flag = false;
function enable_legacy_mode_flag() {
legacy_mode_flag = true;
}
let component_context = null;
function set_component_context(context) {
component_context = context;
}
function push(props, runes = false, fn) {
component_context = {
p: component_context,
i: false,
c: null,
e: null,
s: props,
x: null,
l: legacy_mode_flag && !runes ? { s: null, u: null, $: [] } : null
};
}
function pop(component) {
var context = (
component_context
);
var effects = context.e;
if (effects !== null) {
context.e = null;
for (var fn of effects) {
create_user_effect(fn);
}
}
context.i = true;
component_context = context.p;
return (
{}
);
}
function is_runes() {
return !legacy_mode_flag || component_context !== null && component_context.l === null;
}
let micro_tasks = [];
function run_micro_tasks() {
var tasks = micro_tasks;
micro_tasks = [];
run_all(tasks);
}
function queue_micro_task(fn) {
if (micro_tasks.length === 0 && !is_flushing_sync) {
var tasks = micro_tasks;
queueMicrotask(() => {
if (tasks === micro_tasks) run_micro_tasks();
});
}
micro_tasks.push(fn);
}
function flush_tasks() {
while (micro_tasks.length > 0) {
run_micro_tasks();
}
}
function handle_error(error) {
var effect2 = active_effect;
if (effect2 === null) {
active_reaction.f |= ERROR_VALUE;
return error;
}
if ((effect2.f & REACTION_RAN) === 0 && (effect2.f & EFFECT) === 0) {
throw error;
}
invoke_error_boundary(error, effect2);
}
function invoke_error_boundary(error, effect2) {
while (effect2 !== null) {
if ((effect2.f & BOUNDARY_EFFECT) !== 0) {
if ((effect2.f & REACTION_RAN) === 0) {
throw error;
}
try {
effect2.b.error(error);
return;
} catch (e) {
error = e;
}
}
effect2 = effect2.parent;
}
throw error;
}
const STATUS_MASK = -7169;
function set_signal_status(signal, status) {
signal.f = signal.f & STATUS_MASK | status;
}
function update_derived_status(derived2) {
if ((derived2.f & CONNECTED) !== 0 || derived2.deps === null) {
set_signal_status(derived2, CLEAN);
} else {
set_signal_status(derived2, MAYBE_DIRTY);
}
}
function clear_marked(deps) {
if (deps === null) return;
for (const dep of deps) {
if ((dep.f & DERIVED) === 0 || (dep.f & WAS_MARKED) === 0) {
continue;
}
dep.f ^= WAS_MARKED;
clear_marked(
dep.deps
);
}
}
function defer_effect(effect2, dirty_effects, maybe_dirty_effects) {
if ((effect2.f & DIRTY) !== 0) {
dirty_effects.add(effect2);
} else if ((effect2.f & MAYBE_DIRTY) !== 0) {
maybe_dirty_effects.add(effect2);
}
clear_marked(effect2.deps);
set_signal_status(effect2, CLEAN);
}
const batches = new Set();
let current_batch = null;
let batch_values = null;
let queued_root_effects = [];
let last_scheduled_effect = null;
let is_flushing_sync = false;
let collected_effects = null;
class Batch {
current = new Map();
previous = new Map();
#commit_callbacks = new Set();
#discard_callbacks = new Set();
#pending = 0;
#blocking_pending = 0;
#deferred = null;
#dirty_effects = new Set();
#maybe_dirty_effects = new Set();
#skipped_branches = new Map();
is_fork = false;
#decrement_queued = false;
#is_deferred() {
return this.is_fork || this.#blocking_pending > 0;
}
skip_effect(effect2) {
if (!this.#skipped_branches.has(effect2)) {
this.#skipped_branches.set(effect2, { d: [], m: [] });
}
}
unskip_effect(effect2) {
var tracked = this.#skipped_branches.get(effect2);
if (tracked) {
this.#skipped_branches.delete(effect2);
for (var e of tracked.d) {
set_signal_status(e, DIRTY);
schedule_effect(e);
}
for (e of tracked.m) {
set_signal_status(e, MAYBE_DIRTY);
schedule_effect(e);
}
}
}
process(root_effects) {
queued_root_effects = [];
this.apply();
var effects = collected_effects = [];
var render_effects = [];
for (const root2 of root_effects) {
this.#traverse_effect_tree(root2, effects, render_effects);
}
collected_effects = null;
if (this.#is_deferred()) {
this.#defer_effects(render_effects);
this.#defer_effects(effects);
for (const [e, t] of this.#skipped_branches) {
reset_branch(e, t);
}
} else {
current_batch = null;
for (const fn of this.#commit_callbacks) fn(this);
this.#commit_callbacks.clear();
if (this.#pending === 0) {
this.#commit();
}
flush_queued_effects(render_effects);
flush_queued_effects(effects);
this.#dirty_effects.clear();
this.#maybe_dirty_effects.clear();
this.#deferred?.resolve();
}
batch_values = null;
}
#traverse_effect_tree(root2, effects, render_effects) {
root2.f ^= CLEAN;
var effect2 = root2.first;
while (effect2 !== null) {
var flags2 = effect2.f;
var is_branch = (flags2 & (BRANCH_EFFECT | ROOT_EFFECT)) !== 0;
var is_skippable_branch = is_branch && (flags2 & CLEAN) !== 0;
var skip = is_skippable_branch || (flags2 & INERT) !== 0 || this.#skipped_branches.has(effect2);
if (!skip && effect2.fn !== null) {
if (is_branch) {
effect2.f ^= CLEAN;
} else if ((flags2 & EFFECT) !== 0) {
effects.push(effect2);
} else if (is_dirty(effect2)) {
if ((flags2 & BLOCK_EFFECT) !== 0) this.#maybe_dirty_effects.add(effect2);
update_effect(effect2);
}
var child2 = effect2.first;
if (child2 !== null) {
effect2 = child2;
continue;
}
}
while (effect2 !== null) {
var next = effect2.next;
if (next !== null) {
effect2 = next;
break;
}
effect2 = effect2.parent;
}
}
}
#defer_effects(effects) {
for (var i = 0; i < effects.length; i += 1) {
defer_effect(effects[i], this.#dirty_effects, this.#maybe_dirty_effects);
}
}
capture(source2, value) {
if (value !== UNINITIALIZED && !this.previous.has(source2)) {
this.previous.set(source2, value);
}
if ((source2.f & ERROR_VALUE) === 0) {
this.current.set(source2, source2.v);
batch_values?.set(source2, source2.v);
}
}
activate() {
current_batch = this;
this.apply();
}
deactivate() {
if (current_batch !== this) return;
current_batch = null;
batch_values = null;
}
flush() {
if (queued_root_effects.length > 0) {
current_batch = this;
flush_effects();
} else if (this.#pending === 0 && !this.is_fork) {
for (const fn of this.#commit_callbacks) fn(this);
this.#commit_callbacks.clear();
this.#commit();
this.#deferred?.resolve();
}
this.deactivate();
}
discard() {
for (const fn of this.#discard_callbacks) fn(this);
this.#discard_callbacks.clear();
}
#commit() {
if (batches.size > 1) {
this.previous.clear();
var previous_batch = current_batch;
var previous_batch_values = batch_values;
var is_earlier = true;
for (const batch of batches) {
if (batch === this) {
is_earlier = false;
continue;
}
const sources = [];
for (const [source2, value] of this.current) {
if (batch.current.has(source2)) {
if (is_earlier && value !== batch.current.get(source2)) {
batch.current.set(source2, value);
} else {
continue;
}
}
sources.push(source2);
}
if (sources.length === 0) {
continue;
}
const others = [...batch.current.keys()].filter((s) => !this.current.has(s));
if (others.length > 0) {
var prev_queued_root_effects = queued_root_effects;
queued_root_effects = [];
const marked = new Set();
const checked = new Map();
for (const source2 of sources) {
mark_effects(source2, others, marked, checked);
}
if (queued_root_effects.length > 0) {
current_batch = batch;
batch.apply();
for (const root2 of queued_root_effects) {
batch.#traverse_effect_tree(root2, [], []);
}
batch.deactivate();
}
queued_root_effects = prev_queued_root_effects;
}
}
current_batch = previous_batch;
batch_values = previous_batch_values;
}
this.#skipped_branches.clear();
batches.delete(this);
}
increment(blocking) {
this.#pending += 1;
if (blocking) this.#blocking_pending += 1;
}
decrement(blocking) {
this.#pending -= 1;
if (blocking) this.#blocking_pending -= 1;
if (this.#decrement_queued) return;
this.#decrement_queued = true;
queue_micro_task(() => {
this.#decrement_queued = false;
if (!this.#is_deferred()) {
this.revive();
} else if (queued_root_effects.length > 0) {
this.flush();
}
});
}
revive() {
for (const e of this.#dirty_effects) {
this.#maybe_dirty_effects.delete(e);
set_signal_status(e, DIRTY);
schedule_effect(e);
}
for (const e of this.#maybe_dirty_effects) {
set_signal_status(e, MAYBE_DIRTY);
schedule_effect(e);
}
this.flush();
}
oncommit(fn) {
this.#commit_callbacks.add(fn);
}
ondiscard(fn) {
this.#discard_callbacks.add(fn);
}
settled() {
return (this.#deferred ??= deferred()).promise;
}
static ensure() {
if (current_batch === null) {
const batch = current_batch = new Batch();
batches.add(current_batch);
if (!is_flushing_sync) {
queue_micro_task(() => {
if (current_batch !== batch) {
return;
}
batch.flush();
});
}
}
return current_batch;
}
apply() {
return;
}
}
function flushSync(fn) {
var was_flushing_sync = is_flushing_sync;
is_flushing_sync = true;
try {
var result;
if (fn) ;
while (true) {
flush_tasks();
if (queued_root_effects.length === 0) {
current_batch?.flush();
if (queued_root_effects.length === 0) {
last_scheduled_effect = null;
return (
result
);
}
}
flush_effects();
}
} finally {
is_flushing_sync = was_flushing_sync;
}
}
function flush_effects() {
try {
var flush_count = 0;
while (queued_root_effects.length > 0) {
var batch = Batch.ensure();
if (flush_count++ > 1e3) {
var updates, entry;
if (DEV) ;
infinite_loop_guard();
}
batch.process(queued_root_effects);
old_values.clear();
if (DEV) ;
}
} finally {
queued_root_effects = [];
last_scheduled_effect = null;
collected_effects = null;
}
}
function infinite_loop_guard() {
try {
effect_update_depth_exceeded();
} catch (error) {
invoke_error_boundary(error, last_scheduled_effect);
}
}
let eager_block_effects = null;
function flush_queued_effects(effects) {
var length = effects.length;
if (length === 0) return;
var i = 0;
while (i < length) {
var effect2 = effects[i++];
if ((effect2.f & (DESTROYED | INERT)) === 0 && is_dirty(effect2)) {
eager_block_effects = new Set();
update_effect(effect2);
if (effect2.deps === null && effect2.first === null && effect2.nodes === null && effect2.teardown === null && effect2.ac === null) {
unlink_effect(effect2);
}
if (eager_block_effects?.size > 0) {
old_values.clear();
for (const e of eager_block_effects) {
if ((e.f & (DESTROYED | INERT)) !== 0) continue;
const ordered_effects = [e];
let ancestor = e.parent;
while (ancestor !== null) {
if (eager_block_effects.has(ancestor)) {
eager_block_effects.delete(ancestor);
ordered_effects.push(ancestor);
}
ancestor = ancestor.parent;
}
for (let j = ordered_effects.length - 1; j >= 0; j--) {
const e2 = ordered_effects[j];
if ((e2.f & (DESTROYED | INERT)) !== 0) continue;
update_effect(e2);
}
}
eager_block_effects.clear();
}
}
}
eager_block_effects = null;
}
function mark_effects(value, sources, marked, checked) {
if (marked.has(value)) return;
marked.add(value);
if (value.reactions !== null) {
for (const reaction of value.reactions) {
const flags2 = reaction.f;
if ((flags2 & DERIVED) !== 0) {
mark_effects(
reaction,
sources,
marked,
checked
);
} else if ((flags2 & (ASYNC | BLOCK_EFFECT)) !== 0 && (flags2 & DIRTY) === 0 && depends_on(reaction, sources, checked)) {
set_signal_status(reaction, DIRTY);
schedule_effect(
reaction
);
}
}
}
}
function depends_on(reaction, sources, checked) {
const depends = checked.get(reaction);
if (depends !== void 0) return depends;
if (reaction.deps !== null) {
for (const dep of reaction.deps) {
if (includes.call(sources, dep)) {
return true;
}
if ((dep.f & DERIVED) !== 0 && depends_on(
dep,
sources,
checked
)) {
checked.set(
dep,
true
);
return true;
}
}
}
checked.set(reaction, false);
return false;
}
function schedule_effect(signal) {
var effect2 = last_scheduled_effect = signal;
var boundary2 = effect2.b;
if (boundary2?.is_pending && (signal.f & (EFFECT | RENDER_EFFECT | MANAGED_EFFECT)) !== 0 && (signal.f & REACTION_RAN) === 0) {
boundary2.defer_effect(signal);
return;
}
while (effect2.parent !== null) {
effect2 = effect2.parent;
var flags2 = effect2.f;
if (collected_effects !== null && effect2 === active_effect) {
if ((signal.f & RENDER_EFFECT) === 0) {
return;
}
}
if ((flags2 & (ROOT_EFFECT | BRANCH_EFFECT)) !== 0) {
if ((flags2 & CLEAN) === 0) {
return;
}
effect2.f ^= CLEAN;
}
}
queued_root_effects.push(effect2);
}
function reset_branch(effect2, tracked) {
if ((effect2.f & BRANCH_EFFECT) !== 0 && (effect2.f & CLEAN) !== 0) {
return;
}
if ((effect2.f & DIRTY) !== 0) {
tracked.d.push(effect2);
} else if ((effect2.f & MAYBE_DIRTY) !== 0) {
tracked.m.push(effect2);
}
set_signal_status(effect2, CLEAN);
var e = effect2.first;
while (e !== null) {
reset_branch(e, tracked);
e = e.next;
}
}
function createSubscriber(start) {
let subscribers = 0;
let version = source(0);
let stop;
return () => {
if (effect_tracking()) {
get$1(version);
render_effect(() => {
if (subscribers === 0) {
stop = untrack(() => start(() => increment(version)));
}
subscribers += 1;
return () => {
queue_micro_task(() => {
subscribers -= 1;
if (subscribers === 0) {
stop?.();
stop = void 0;
increment(version);
}
});
};
});
}
};
}
var flags = EFFECT_TRANSPARENT | EFFECT_PRESERVED;
function boundary(node, props, children, transform_error) {
new Boundary(node, props, children, transform_error);
}
class Boundary {
parent;
is_pending = false;
transform_error;
#anchor;
#hydrate_open = null;
#props;
#children;
#effect;
#main_effect = null;
#pending_effect = null;
#failed_effect = null;
#offscreen_fragment = null;
#local_pending_count = 0;
#pending_count = 0;
#pending_count_update_queued = false;
#dirty_effects = new Set();
#maybe_dirty_effects = new Set();
#effect_pending = null;
#effect_pending_subscriber = createSubscriber(() => {
this.#effect_pending = source(this.#local_pending_count);
return () => {
this.#effect_pending = null;
};
});
constructor(node, props, children, transform_error) {
this.#anchor = node;
this.#props = props;
this.#children = (anchor) => {
var effect2 = (
active_effect
);
effect2.b = this;
effect2.f |= BOUNDARY_EFFECT;
children(anchor);
};
this.parent =
active_effect.b;
this.transform_error = transform_error ?? this.parent?.transform_error ?? ((e) => e);
this.#effect = block(() => {
{
this.#render();
}
}, flags);
}
#hydrate_resolved_content() {
try {
this.#main_effect = branch(() => this.#children(this.#anchor));
} catch (error) {
this.error(error);
}
}
#hydrate_failed_content(error) {
const failed = this.#props.failed;
if (!failed) return;
this.#failed_effect = branch(() => {
failed(
this.#anchor,
() => error,
() => () => {
}
);
});
}
#hydrate_pending_content() {
const pending = this.#props.pending;
if (!pending) return;
this.is_pending = true;
this.#pending_effect = branch(() => pending(this.#anchor));
queue_micro_task(() => {
var fragment = this.#offscreen_fragment = document.createDocumentFragment();
var anchor = create_text();
fragment.append(anchor);
this.#main_effect = this.#run(() => {
Batch.ensure();
return branch(() => this.#children(anchor));
});
if (this.#pending_count === 0) {
this.#anchor.before(fragment);
this.#offscreen_fragment = null;
pause_effect(
this.#pending_effect,
() => {
this.#pending_effect = null;
}
);
this.#resolve();
}
});
}
#render() {
try {
this.is_pending = this.has_pending_snippet();
this.#pending_count = 0;
this.#local_pending_count = 0;
this.#main_effect = branch(() => {
this.#children(this.#anchor);
});
if (this.#pending_count > 0) {
var fragment = this.#offscreen_fragment = document.createDocumentFragment();
move_effect(this.#main_effect, fragment);
const pending = (
this.#props.pending
);
this.#pending_effect = branch(() => pending(this.#anchor));
} else {
this.#resolve();
}
} catch (error) {
this.error(error);
}
}
#resolve() {
this.is_pending = false;
for (const e of this.#dirty_effects) {
set_signal_status(e, DIRTY);
schedule_effect(e);
}
for (const e of this.#maybe_dirty_effects) {
set_signal_status(e, MAYBE_DIRTY);
schedule_effect(e);
}
this.#dirty_effects.clear();
this.#maybe_dirty_effects.clear();
}
defer_effect(effect2) {
defer_effect(effect2, this.#dirty_effects, this.#maybe_dirty_effects);
}
is_rendered() {
return !this.is_pending && (!this.parent || this.parent.is_rendered());
}
has_pending_snippet() {
return !!this.#props.pending;
}
#run(fn) {
var previous_effect = active_effect;
var previous_reaction = active_reaction;
var previous_ctx = component_context;
set_active_effect(this.#effect);
set_active_reaction(this.#effect);
set_component_context(this.#effect.ctx);
try {
return fn();
} catch (e) {
handle_error(e);
return null;
} finally {
set_active_effect(previous_effect);
set_active_reaction(previous_reaction);
set_component_context(previous_ctx);
}
}
#update_pending_count(d) {
if (!this.has_pending_snippet()) {
if (this.parent) {
this.parent.#update_pending_count(d);
}
return;
}
this.#pending_count += d;
if (this.#pending_count === 0) {
this.#resolve();
if (this.#pending_effect) {
pause_effect(this.#pending_effect, () => {
this.#pending_effect = null;
});
}
if (this.#offscreen_fragment) {
this.#anchor.before(this.#offscreen_fragment);
this.#offscreen_fragment = null;
}
}
}
update_pending_count(d) {
this.#update_pending_count(d);
this.#local_pending_count += d;
if (!this.#effect_pending || this.#pending_count_update_queued) return;
this.#pending_count_update_queued = true;
queue_micro_task(() => {
this.#pending_count_update_queued = false;
if (this.#effect_pending) {
internal_set(this.#effect_pending, this.#local_pending_count);
}
});
}
get_effect_pending() {
this.#effect_pending_subscriber();
return get$1(
this.#effect_pending
);
}
error(error) {
var onerror = this.#props.onerror;
let failed = this.#props.failed;
if (!onerror && !failed) {
throw error;
}
if (this.#main_effect) {
destroy_effect(this.#main_effect);
this.#main_effect = null;
}
if (this.#pending_effect) {
destroy_effect(this.#pending_effect);
this.#pending_effect = null;
}
if (this.#failed_effect) {
destroy_effect(this.#failed_effect);
this.#failed_effect = null;
}
var did_reset = false;
var calling_on_error = false;
const reset = () => {
if (did_reset) {
svelte_boundary_reset_noop();
return;
}
did_reset = true;
if (calling_on_error) {
svelte_boundary_reset_onerror();
}
if (this.#failed_effect !== null) {
pause_effect(this.#failed_effect, () => {
this.#failed_effect = null;
});
}
this.#run(() => {
Batch.ensure();
this.#render();
});
};
const handle_error_result = (transformed_error) => {
try {
calling_on_error = true;
onerror?.(transformed_error, reset);
calling_on_error = false;
} catch (error2) {
invoke_error_boundary(error2, this.#effect && this.#effect.parent);
}
if (failed) {
this.#failed_effect = this.#run(() => {
Batch.ensure();
try {
return branch(() => {
var effect2 = (
active_effect
);
effect2.b = this;
effect2.f |= BOUNDARY_EFFECT;
failed(
this.#anchor,
() => transformed_error,
() => reset
);
});
} catch (error2) {
invoke_error_boundary(
error2,
this.#effect.parent
);
return null;
}
});
}
};
queue_micro_task(() => {
var result;
try {
result = this.transform_error(error);
} catch (e) {
invoke_error_boundary(e, this.#effect && this.#effect.parent);
return;
}
if (result !== null && typeof result === "object" && typeof
result.then === "function") {
result.then(
handle_error_result,
(e) => invoke_error_boundary(e, this.#effect && this.#effect.parent)
);
} else {
handle_error_result(result);
}
});
}
}
function flatten(blockers, sync, async, fn) {
const d = is_runes() ? derived : derived_safe_equal;
var pending = blockers.filter((b) => !b.settled);
if (async.length === 0 && pending.length === 0) {
fn(sync.map(d));
return;
}
var parent = (
active_effect
);
var restore = capture();
var blocker_promise = pending.length === 1 ? pending[0].promise : pending.length > 1 ? Promise.all(pending.map((b) => b.promise)) : null;
function finish(values) {
restore();
try {
fn(values);
} catch (error) {
if ((parent.f & DESTROYED) === 0) {
invoke_error_boundary(error, parent);
}
}
unset_context();
}
if (async.length === 0) {
blocker_promise.then(() => finish(sync.map(d)));
return;
}
function run2() {
restore();
Promise.all(async.map((expression) => async_derived(expression))).then((result) => finish([...sync.map(d), ...result])).catch((error) => invoke_error_boundary(error, parent));
}
if (blocker_promise) {
blocker_promise.then(run2);
} else {
run2();
}
}
function capture() {
var previous_effect = active_effect;
var previous_reaction = active_reaction;
var previous_component_context = component_context;
var previous_batch = current_batch;
return function restore(activate_batch = true) {
set_active_effect(previous_effect);
set_active_reaction(previous_reaction);
set_component_context(previous_component_context);
if (activate_batch) previous_batch?.activate();
};
}
function unset_context(deactivate_batch = true) {
set_active_effect(null);
set_active_reaction(null);
set_component_context(null);
if (deactivate_batch) current_batch?.deactivate();
}
function increment_pending() {
var boundary2 = (
active_effect.b
);
var batch = (
current_batch
);
var blocking = boundary2.is_rendered();
boundary2.update_pending_count(1);
batch.increment(blocking);
return () => {
boundary2.update_pending_count(-1);
batch.decrement(blocking);
};
}
function derived(fn) {
var flags2 = DERIVED | DIRTY;
var parent_derived = active_reaction !== null && (active_reaction.f & DERIVED) !== 0 ? (
active_reaction
) : null;
if (active_effect !== null) {
active_effect.f |= EFFECT_PRESERVED;
}
const signal = {
ctx: component_context,
deps: null,
effects: null,
equals,
f: flags2,
fn,
reactions: null,
rv: 0,
v: (
UNINITIALIZED
),
wv: 0,
parent: parent_derived ?? active_effect,
ac: null
};
return signal;
}
function async_derived(fn, label, location) {
let parent = (
active_effect
);
if (parent === null) {
async_derived_orphan();
}
var promise = (
void 0
);
var signal = source(
UNINITIALIZED
);
var should_suspend = !active_reaction;
var deferreds = new Map();
async_effect(() => {
var d = deferred();
promise = d.promise;
try {
Promise.resolve(fn()).then(d.resolve, d.reject).finally(unset_context);
} catch (error) {
d.reject(error);
unset_context();
}
var batch = (
current_batch
);
if (should_suspend) {
var decrement_pending = increment_pending();
deferreds.get(batch)?.reject(STALE_REACTION);
deferreds.delete(batch);
deferreds.set(batch, d);
}
const handler = (value, error = void 0) => {
batch.activate();
if (error) {
if (error !== STALE_REACTION) {
signal.f |= ERROR_VALUE;
internal_set(signal, error);
}
} else {
if ((signal.f & ERROR_VALUE) !== 0) {
signal.f ^= ERROR_VALUE;
}
internal_set(signal, value);
for (const [b, d2] of deferreds) {
deferreds.delete(b);
if (b === batch) break;
d2.reject(STALE_REACTION);
}
}
if (decrement_pending) {
decrement_pending();
}
};
d.promise.then(handler, (e) => handler(null, e || "unknown"));
});
teardown(() => {
for (const d of deferreds.values()) {
d.reject(STALE_REACTION);
}
});
return new Promise((fulfil) => {
function next(p) {
function go() {
if (p === promise) {
fulfil(signal);
} else {
next(promise);
}
}
p.then(go, go);
}
next(promise);
});
}
function derived_safe_equal(fn) {
const signal = derived(fn);
signal.equals = safe_equals;
return signal;
}
function destroy_derived_effects(derived2) {
var effects = derived2.effects;
if (effects !== null) {
derived2.effects = null;
for (var i = 0; i < effects.length; i += 1) {
destroy_effect(
effects[i]
);
}
}
}
function get_derived_parent_effect(derived2) {
var parent = derived2.parent;
while (parent !== null) {
if ((parent.f & DERIVED) === 0) {
return (parent.f & DESTROYED) === 0 ? (
parent
) : null;
}
parent = parent.parent;
}
return null;
}
function execute_derived(derived2) {
var value;
var prev_active_effect = active_effect;
set_active_effect(get_derived_parent_effect(derived2));
{
try {
derived2.f &= ~WAS_MARKED;
destroy_derived_effects(derived2);
value = update_reaction(derived2);
} finally {
set_active_effect(prev_active_effect);
}
}
return value;
}
function update_derived(derived2) {
var value = execute_derived(derived2);
if (!derived2.equals(value)) {
derived2.wv = increment_write_version();
if (!current_batch?.is_fork || derived2.deps === null) {
derived2.v = value;
if (derived2.deps === null) {
set_signal_status(derived2, CLEAN);
return;
}
}
}
if (is_destroying_effect) {
return;
}
if (batch_values !== null) {
if (effect_tracking() || current_batch?.is_fork) {
batch_values.set(derived2, value);
}
} else {
update_derived_status(derived2);
}
}
function freeze_derived_effects(derived2) {
if (derived2.effects === null) return;
for (const e of derived2.effects) {
if (e.teardown || e.ac) {
e.teardown?.();
e.ac?.abort(STALE_REACTION);
e.teardown = noop;
e.ac = null;
remove_reactions(e, 0);
destroy_effect_children(e);
}
}
}
function unfreeze_derived_effects(derived2) {
if (derived2.effects === null) return;
for (const e of derived2.effects) {
if (e.teardown) {
update_effect(e);
}
}
}
let eager_effects = new Set();
const old_values = new Map();
let eager_effects_deferred = false;
function source(v, stack) {
var signal = {
f: 0,
v,
reactions: null,
equals,
rv: 0,
wv: 0
};
return signal;
}
function state(v, stack) {
const s = source(v);
push_reaction_value(s);
return s;
}
function mutable_source(initial_value, immutable = false, trackable = true) {
const s = source(initial_value);
if (!immutable) {
s.equals = safe_equals;
}
if (legacy_mode_flag && trackable && component_context !== null && component_context.l !== null) {
(component_context.l.s ??= []).push(s);
}
return s;
}
function mutate(source2, value) {
set(
source2,
untrack(() => get$1(source2))
);
return value;
}
function set(source2, value, should_proxy = false) {
if (active_reaction !== null &&
(!untracking || (active_reaction.f & EAGER_EFFECT) !== 0) && is_runes() && (active_reaction.f & (DERIVED | BLOCK_EFFECT | ASYNC | EAGER_EFFECT)) !== 0 && (current_sources === null || !includes.call(current_sources, source2))) {
state_unsafe_mutation();
}
let new_value = should_proxy ? proxy(value) : value;
return internal_set(source2, new_value);
}
function internal_set(source2, value) {
if (!source2.equals(value)) {
var old_value = source2.v;
if (is_destroying_effect) {
old_values.set(source2, value);
} else {
old_values.set(source2, old_value);
}
source2.v = value;
var batch = Batch.ensure();
batch.capture(source2, old_value);
if ((source2.f & DERIVED) !== 0) {
const derived2 = (
source2
);
if ((source2.f & DIRTY) !== 0) {
execute_derived(derived2);
}
update_derived_status(derived2);
}
source2.wv = increment_write_version();
mark_reactions(source2, DIRTY);
if (is_runes() && active_effect !== null && (active_effect.f & CLEAN) !== 0 && (active_effect.f & (BRANCH_EFFECT | ROOT_EFFECT)) === 0) {
if (untracked_writes === null) {
set_untracked_writes([source2]);
} else {
untracked_writes.push(source2);
}
}
if (!batch.is_fork && eager_effects.size > 0 && !eager_effects_deferred) {
flush_eager_effects();
}
}
return value;
}
function flush_eager_effects() {
eager_effects_deferred = false;
for (const effect2 of eager_effects) {
if ((effect2.f & CLEAN) !== 0) {
set_signal_status(effect2, MAYBE_DIRTY);
}
if (is_dirty(effect2)) {
update_effect(effect2);
}
}
eager_effects.clear();
}
function increment(source2) {
set(source2, source2.v + 1);
}
function mark_reactions(signal, status) {
var reactions = signal.reactions;
if (reactions === null) return;
var runes = is_runes();
var length = reactions.length;
for (var i = 0; i < length; i++) {
var reaction = reactions[i];
var flags2 = reaction.f;
if (!runes && reaction === active_effect) continue;
var not_dirty = (flags2 & DIRTY) === 0;
if (not_dirty) {
set_signal_status(reaction, status);
}
if ((flags2 & DERIVED) !== 0) {
var derived2 = (
reaction
);
batch_values?.delete(derived2);
if ((flags2 & WAS_MARKED) === 0) {
if (flags2 & CONNECTED) {
reaction.f |= WAS_MARKED;
}
mark_reactions(derived2, MAYBE_DIRTY);
}
} else if (not_dirty) {
if ((flags2 & BLOCK_EFFECT) !== 0 && eager_block_effects !== null) {
eager_block_effects.add(
reaction
);
}
schedule_effect(
reaction
);
}
}
}
function proxy(value) {
if (typeof value !== "object" || value === null || STATE_SYMBOL in value) {
return value;
}
const prototype = get_prototype_of(value);
if (prototype !== object_prototype && prototype !== array_prototype) {
return value;
}
var sources = new Map();
var is_proxied_array = is_array(value);
var version = state(0);
var parent_version = update_version;
var with_parent = (fn) => {
if (update_version === parent_version) {
return fn();
}
var reaction = active_reaction;
var version2 = update_version;
set_active_reaction(null);
set_update_version(parent_version);
var result = fn();
set_active_reaction(reaction);
set_update_version(version2);
return result;
};
if (is_proxied_array) {
sources.set("length", state(
value.length
));
}
return new Proxy(
value,
{
defineProperty(_, prop2, descriptor) {
if (!("value" in descriptor) || descriptor.configurable === false || descriptor.enumerable === false || descriptor.writable === false) {
state_descriptors_fixed();
}
var s = sources.get(prop2);
if (s === void 0) {
with_parent(() => {
var s2 = state(descriptor.value);
sources.set(prop2, s2);
return s2;
});
} else {
set(s, descriptor.value, true);
}
return true;
},
deleteProperty(target, prop2) {
var s = sources.get(prop2);
if (s === void 0) {
if (prop2 in target) {
const s2 = with_parent(() => state(UNINITIALIZED));
sources.set(prop2, s2);
increment(version);
}
} else {
set(s, UNINITIALIZED);
increment(version);
}
return true;
},
get(target, prop2, receiver) {
if (prop2 === STATE_SYMBOL) {
return value;
}
var s = sources.get(prop2);
var exists = prop2 in target;
if (s === void 0 && (!exists || get_descriptor(target, prop2)?.writable)) {
s = with_parent(() => {
var p = proxy(exists ? target[prop2] : UNINITIALIZED);
var s2 = state(p);
return s2;
});
sources.set(prop2, s);
}
if (s !== void 0) {
var v = get$1(s);
return v === UNINITIALIZED ? void 0 : v;
}
return Reflect.get(target, prop2, receiver);
},
getOwnPropertyDescriptor(target, prop2) {
var descriptor = Reflect.getOwnPropertyDescriptor(target, prop2);
if (descriptor && "value" in descriptor) {
var s = sources.get(prop2);
if (s) descriptor.value = get$1(s);
} else if (descriptor === void 0) {
var source2 = sources.get(prop2);
var value2 = source2?.v;
if (source2 !== void 0 && value2 !== UNINITIALIZED) {
return {
enumerable: true,
configurable: true,
value: value2,
writable: true
};
}
}
return descriptor;
},
has(target, prop2) {
if (prop2 === STATE_SYMBOL) {
return true;
}
var s = sources.get(prop2);
var has = s !== void 0 && s.v !== UNINITIALIZED || Reflect.has(target, prop2);
if (s !== void 0 || active_effect !== null && (!has || get_descriptor(target, prop2)?.writable)) {
if (s === void 0) {
s = with_parent(() => {
var p = has ? proxy(target[prop2]) : UNINITIALIZED;
var s2 = state(p);
return s2;
});
sources.set(prop2, s);
}
var value2 = get$1(s);
if (value2 === UNINITIALIZED) {
return false;
}
}
return has;
},
set(target, prop2, value2, receiver) {
var s = sources.get(prop2);
var has = prop2 in target;
if (is_proxied_array && prop2 === "length") {
for (var i = value2; i <
s.v; i += 1) {
var other_s = sources.get(i + "");
if (other_s !== void 0) {
set(other_s, UNINITIALIZED);
} else if (i in target) {
other_s = with_parent(() => state(UNINITIALIZED));
sources.set(i + "", other_s);
}
}
}
if (s === void 0) {
if (!has || get_descriptor(target, prop2)?.writable) {
s = with_parent(() => state(void 0));
set(s, proxy(value2));
sources.set(prop2, s);
}
} else {
has = s.v !== UNINITIALIZED;
var p = with_parent(() => proxy(value2));
set(s, p);
}
var descriptor = Reflect.getOwnPropertyDescriptor(target, prop2);
if (descriptor?.set) {
descriptor.set.call(receiver, value2);
}
if (!has) {
if (is_proxied_array && typeof prop2 === "string") {
var ls = (
sources.get("length")
);
var n = Number(prop2);
if (Number.isInteger(n) && n >= ls.v) {
set(ls, n + 1);
}
}
increment(version);
}
return true;
},
ownKeys(target) {
get$1(version);
var own_keys = Reflect.ownKeys(target).filter((key2) => {
var source3 = sources.get(key2);
return source3 === void 0 || source3.v !== UNINITIALIZED;
});
for (var [key, source2] of sources) {
if (source2.v !== UNINITIALIZED && !(key in target)) {
own_keys.push(key);
}
}
return own_keys;
},
setPrototypeOf() {
state_prototype_fixed();
}
}
);
}
var $window;
var is_firefox;
var first_child_getter;
var next_sibling_getter;
function init_operations() {
if ($window !== void 0) {
return;
}
$window = window;
is_firefox = /Firefox/.test(navigator.userAgent);
var element_prototype = Element.prototype;
var node_prototype = Node.prototype;
var text_prototype = Text.prototype;
first_child_getter = get_descriptor(node_prototype, "firstChild").get;
next_sibling_getter = get_descriptor(node_prototype, "nextSibling").get;
if (is_extensible(element_prototype)) {
element_prototype.__click = void 0;
element_prototype.__className = void 0;
element_prototype.__attributes = null;
element_prototype.__style = void 0;
element_prototype.__e = void 0;
}
if (is_extensible(text_prototype)) {
text_prototype.__t = void 0;
}
}
function create_text(value = "") {
return document.createTextNode(value);
}
function get_first_child(node) {
return (
first_child_getter.call(node)
);
}
function get_next_sibling(node) {
return (
next_sibling_getter.call(node)
);
}
function child(node, is_text) {
{
return get_first_child(node);
}
}
function first_child(node, is_text = false) {
{
var first = get_first_child(node);
if (first instanceof Comment && first.data === "") return get_next_sibling(first);
return first;
}
}
function sibling(node, count = 1, is_text = false) {
let next_sibling = node;
while (count--) {
next_sibling =
get_next_sibling(next_sibling);
}
{
return next_sibling;
}
}
function clear_text_content(node) {
node.textContent = "";
}
function create_element(tag, namespace, is) {
let options = void 0;
return (
document.createElementNS(NAMESPACE_HTML, tag, options)
);
}
function without_reactive_context(fn) {
var previous_reaction = active_reaction;
var previous_effect = active_effect;
set_active_reaction(null);
set_active_effect(null);
try {
return fn();
} finally {
set_active_reaction(previous_reaction);
set_active_effect(previous_effect);
}
}
function validate_effect(rune) {
if (active_effect === null) {
if (active_reaction === null) {
effect_orphan();
}
effect_in_unowned_derived();
}
if (is_destroying_effect) {
effect_in_teardown();
}
}
function push_effect(effect2, parent_effect) {
var parent_last = parent_effect.last;
if (parent_last === null) {
parent_effect.last = parent_effect.first = effect2;
} else {
parent_last.next = effect2;
effect2.prev = parent_last;
parent_effect.last = effect2;
}
}
function create_effect(type, fn) {
var parent = active_effect;
if (parent !== null && (parent.f & INERT) !== 0) {
type |= INERT;
}
var effect2 = {
ctx: component_context,
deps: null,
nodes: null,
f: type | DIRTY | CONNECTED,
first: null,
fn,
last: null,
next: null,
parent,
b: parent && parent.b,
prev: null,
teardown: null,
wv: 0,
ac: null
};
var e = effect2;
if ((type & EFFECT) !== 0) {
if (collected_effects !== null) {
collected_effects.push(effect2);
} else {
schedule_effect(effect2);
}
} else if (fn !== null) {
try {
update_effect(effect2);
} catch (e2) {
destroy_effect(effect2);
throw e2;
}
if (e.deps === null && e.teardown === null && e.nodes === null && e.first === e.last &&
(e.f & EFFECT_PRESERVED) === 0) {
e = e.first;
if ((type & BLOCK_EFFECT) !== 0 && (type & EFFECT_TRANSPARENT) !== 0 && e !== null) {
e.f |= EFFECT_TRANSPARENT;
}
}
}
if (e !== null) {
e.parent = parent;
if (parent !== null) {
push_effect(e, parent);
}
if (active_reaction !== null && (active_reaction.f & DERIVED) !== 0 && (type & ROOT_EFFECT) === 0) {
var derived2 = (
active_reaction
);
(derived2.effects ??= []).push(e);
}
}
return effect2;
}
function effect_tracking() {
return active_reaction !== null && !untracking;
}
function teardown(fn) {
const effect2 = create_effect(RENDER_EFFECT, null);
set_signal_status(effect2, CLEAN);
effect2.teardown = fn;
return effect2;
}
function user_effect(fn) {
validate_effect();
var flags2 = (
active_effect.f
);
var defer = !active_reaction && (flags2 & BRANCH_EFFECT) !== 0 && (flags2 & REACTION_RAN) === 0;
if (defer) {
var context = (
component_context
);
(context.e ??= []).push(fn);
} else {
return create_user_effect(fn);
}
}
function create_user_effect(fn) {
return create_effect(EFFECT | USER_EFFECT, fn);
}
function user_pre_effect(fn) {
validate_effect();
return create_effect(RENDER_EFFECT | USER_EFFECT, fn);
}
function component_root(fn) {
Batch.ensure();
const effect2 = create_effect(ROOT_EFFECT | EFFECT_PRESERVED, fn);
return (options = {}) => {
return new Promise((fulfil) => {
if (options.outro) {
pause_effect(effect2, () => {
destroy_effect(effect2);
fulfil(void 0);
});
} else {
destroy_effect(effect2);
fulfil(void 0);
}
});
};
}
function effect(fn) {
return create_effect(EFFECT, fn);
}
function legacy_pre_effect(deps, fn) {
var context = (
component_context
);
var token = { effect: null, ran: false, deps };
context.l.$.push(token);
token.effect = render_effect(() => {
deps();
if (token.ran) return;
token.ran = true;
untrack(fn);
});
}
function legacy_pre_effect_reset() {
var context = (
component_context
);
render_effect(() => {
for (var token of context.l.$) {
token.deps();
var effect2 = token.effect;
if ((effect2.f & CLEAN) !== 0 && effect2.deps !== null) {
set_signal_status(effect2, MAYBE_DIRTY);
}
if (is_dirty(effect2)) {
update_effect(effect2);
}
token.ran = false;
}
});
}
function async_effect(fn) {
return create_effect(ASYNC | EFFECT_PRESERVED, fn);
}
function render_effect(fn, flags2 = 0) {
return create_effect(RENDER_EFFECT | flags2, fn);
}
function template_effect(fn, sync = [], async = [], blockers = []) {
flatten(blockers, sync, async, (values) => {
create_effect(RENDER_EFFECT, () => fn(...values.map(get$1)));
});
}
function block(fn, flags2 = 0) {
var effect2 = create_effect(BLOCK_EFFECT | flags2, fn);
return effect2;
}
function branch(fn) {
return create_effect(BRANCH_EFFECT | EFFECT_PRESERVED, fn);
}
function execute_effect_teardown(effect2) {
var teardown2 = effect2.teardown;
if (teardown2 !== null) {
const previously_destroying_effect = is_destroying_effect;
const previous_reaction = active_reaction;
set_is_destroying_effect(true);
set_active_reaction(null);
try {
teardown2.call(null);
} finally {
set_is_destroying_effect(previously_destroying_effect);
set_active_reaction(previous_reaction);
}
}
}
function destroy_effect_children(signal, remove_dom = false) {
var effect2 = signal.first;
signal.first = signal.last = null;
while (effect2 !== null) {
const controller = effect2.ac;
if (controller !== null) {
without_reactive_context(() => {
controller.abort(STALE_REACTION);
});
}
var next = effect2.next;
if ((effect2.f & ROOT_EFFECT) !== 0) {
effect2.parent = null;
} else {
destroy_effect(effect2, remove_dom);
}
effect2 = next;
}
}
function destroy_block_effect_children(signal) {
var effect2 = signal.first;
while (effect2 !== null) {
var next = effect2.next;
if ((effect2.f & BRANCH_EFFECT) === 0) {
destroy_effect(effect2);
}
effect2 = next;
}
}
function destroy_effect(effect2, remove_dom = true) {
var removed = false;
if ((remove_dom || (effect2.f & HEAD_EFFECT) !== 0) && effect2.nodes !== null && effect2.nodes.end !== null) {
remove_effect_dom(
effect2.nodes.start,
effect2.nodes.end
);
removed = true;
}
destroy_effect_children(effect2, remove_dom && !removed);
remove_reactions(effect2, 0);
set_signal_status(effect2, DESTROYED);
var transitions = effect2.nodes && effect2.nodes.t;
if (transitions !== null) {
for (const transition of transitions) {
transition.stop();
}
}
execute_effect_teardown(effect2);
var parent = effect2.parent;
if (parent !== null && parent.first !== null) {
unlink_effect(effect2);
}
effect2.next = effect2.prev = effect2.teardown = effect2.ctx = effect2.deps = effect2.fn = effect2.nodes = effect2.ac = null;
}
function remove_effect_dom(node, end) {
while (node !== null) {
var next = node === end ? null : get_next_sibling(node);
node.remove();
node = next;
}
}
function unlink_effect(effect2) {
var parent = effect2.parent;
var prev = effect2.prev;
var next = effect2.next;
if (prev !== null) prev.next = next;
if (next !== null) next.prev = prev;
if (parent !== null) {
if (parent.first === effect2) parent.first = next;
if (parent.last === effect2) parent.last = prev;
}
}
function pause_effect(effect2, callback, destroy = true) {
var transitions = [];
pause_children(effect2, transitions, true);
var fn = () => {
if (destroy) destroy_effect(effect2);
if (callback) callback();
};
var remaining = transitions.length;
if (remaining > 0) {
var check = () => --remaining || fn();
for (var transition of transitions) {
transition.out(check);
}
} else {
fn();
}
}
function pause_children(effect2, transitions, local) {
if ((effect2.f & INERT) !== 0) return;
effect2.f ^= INERT;
var t = effect2.nodes && effect2.nodes.t;
if (t !== null) {
for (const transition of t) {
if (transition.is_global || local) {
transitions.push(transition);
}
}
}
var child2 = effect2.first;
while (child2 !== null) {
var sibling2 = child2.next;
var transparent = (child2.f & EFFECT_TRANSPARENT) !== 0 ||
(child2.f & BRANCH_EFFECT) !== 0 && (effect2.f & BLOCK_EFFECT) !== 0;
pause_children(child2, transitions, transparent ? local : false);
child2 = sibling2;
}
}
function resume_effect(effect2) {
resume_children(effect2, true);
}
function resume_children(effect2, local) {
if ((effect2.f & INERT) === 0) return;
effect2.f ^= INERT;
if ((effect2.f & CLEAN) === 0) {
set_signal_status(effect2, DIRTY);
schedule_effect(effect2);
}
var child2 = effect2.first;
while (child2 !== null) {
var sibling2 = child2.next;
var transparent = (child2.f & EFFECT_TRANSPARENT) !== 0 || (child2.f & BRANCH_EFFECT) !== 0;
resume_children(child2, transparent ? local : false);
child2 = sibling2;
}
var t = effect2.nodes && effect2.nodes.t;
if (t !== null) {
for (const transition of t) {
if (transition.is_global || local) {
transition.in();
}
}
}
}
function move_effect(effect2, fragment) {
if (!effect2.nodes) return;
var node = effect2.nodes.start;
var end = effect2.nodes.end;
while (node !== null) {
var next = node === end ? null : get_next_sibling(node);
fragment.append(node);
node = next;
}
}
let is_updating_effect = false;
let is_destroying_effect = false;
function set_is_destroying_effect(value) {
is_destroying_effect = value;
}
let active_reaction = null;
let untracking = false;
function set_active_reaction(reaction) {
active_reaction = reaction;
}
let active_effect = null;
function set_active_effect(effect2) {
active_effect = effect2;
}
let current_sources = null;
function push_reaction_value(value) {
if (active_reaction !== null && true) {
if (current_sources === null) {
current_sources = [value];
} else {
current_sources.push(value);
}
}
}
let new_deps = null;
let skipped_deps = 0;
let untracked_writes = null;
function set_untracked_writes(value) {
untracked_writes = value;
}
let write_version = 1;
let read_version = 0;
let update_version = read_version;
function set_update_version(value) {
update_version = value;
}
function increment_write_version() {
return ++write_version;
}
function is_dirty(reaction) {
var flags2 = reaction.f;
if ((flags2 & DIRTY) !== 0) {
return true;
}
if (flags2 & DERIVED) {
reaction.f &= ~WAS_MARKED;
}
if ((flags2 & MAYBE_DIRTY) !== 0) {
var dependencies = (
reaction.deps
);
var length = dependencies.length;
for (var i = 0; i < length; i++) {
var dependency = dependencies[i];
if (is_dirty(
dependency
)) {
update_derived(
dependency
);
}
if (dependency.wv > reaction.wv) {
return true;
}
}
if ((flags2 & CONNECTED) !== 0 &&
batch_values === null) {
set_signal_status(reaction, CLEAN);
}
}
return false;
}
function schedule_possible_effect_self_invalidation(signal, effect2, root2 = true) {
var reactions = signal.reactions;
if (reactions === null) return;
if (current_sources !== null && includes.call(current_sources, signal)) {
return;
}
for (var i = 0; i < reactions.length; i++) {
var reaction = reactions[i];
if ((reaction.f & DERIVED) !== 0) {
schedule_possible_effect_self_invalidation(
reaction,
effect2,
false
);
} else if (effect2 === reaction) {
if (root2) {
set_signal_status(reaction, DIRTY);
} else if ((reaction.f & CLEAN) !== 0) {
set_signal_status(reaction, MAYBE_DIRTY);
}
schedule_effect(
reaction
);
}
}
}
function update_reaction(reaction) {
var previous_deps = new_deps;
var previous_skipped_deps = skipped_deps;
var previous_untracked_writes = untracked_writes;
var previous_reaction = active_reaction;
var previous_sources = current_sources;
var previous_component_context = component_context;
var previous_untracking = untracking;
var previous_update_version = update_version;
var flags2 = reaction.f;
new_deps =
null;
skipped_deps = 0;
untracked_writes = null;
active_reaction = (flags2 & (BRANCH_EFFECT | ROOT_EFFECT)) === 0 ? reaction : null;
current_sources = null;
set_component_context(reaction.ctx);
untracking = false;
update_version = ++read_version;
if (reaction.ac !== null) {
without_reactive_context(() => {
reaction.ac.abort(STALE_REACTION);
});
reaction.ac = null;
}
try {
reaction.f |= REACTION_IS_UPDATING;
var fn = (
reaction.fn
);
var result = fn();
reaction.f |= REACTION_RAN;
var deps = reaction.deps;
var is_fork = current_batch?.is_fork;
if (new_deps !== null) {
var i;
if (!is_fork) {
remove_reactions(reaction, skipped_deps);
}
if (deps !== null && skipped_deps > 0) {
deps.length = skipped_deps + new_deps.length;
for (i = 0; i < new_deps.length; i++) {
deps[skipped_deps + i] = new_deps[i];
}
} else {
reaction.deps = deps = new_deps;
}
if (effect_tracking() && (reaction.f & CONNECTED) !== 0) {
for (i = skipped_deps; i < deps.length; i++) {
(deps[i].reactions ??= []).push(reaction);
}
}
} else if (!is_fork && deps !== null && skipped_deps < deps.length) {
remove_reactions(reaction, skipped_deps);
deps.length = skipped_deps;
}
if (is_runes() && untracked_writes !== null && !untracking && deps !== null && (reaction.f & (DERIVED | MAYBE_DIRTY | DIRTY)) === 0) {
for (i = 0; i <
untracked_writes.length; i++) {
schedule_possible_effect_self_invalidation(
untracked_writes[i],
reaction
);
}
}
if (previous_reaction !== null && previous_reaction !== reaction) {
read_version++;
if (previous_reaction.deps !== null) {
for (let i2 = 0; i2 < previous_skipped_deps; i2 += 1) {
previous_reaction.deps[i2].rv = read_version;
}
}
if (previous_deps !== null) {
for (const dep of previous_deps) {
dep.rv = read_version;
}
}
if (untracked_writes !== null) {
if (previous_untracked_writes === null) {
previous_untracked_writes = untracked_writes;
} else {
previous_untracked_writes.push(...
untracked_writes);
}
}
}
if ((reaction.f & ERROR_VALUE) !== 0) {
reaction.f ^= ERROR_VALUE;
}
return result;
} catch (error) {
return handle_error(error);
} finally {
reaction.f ^= REACTION_IS_UPDATING;
new_deps = previous_deps;
skipped_deps = previous_skipped_deps;
untracked_writes = previous_untracked_writes;
active_reaction = previous_reaction;
current_sources = previous_sources;
set_component_context(previous_component_context);
untracking = previous_untracking;
update_version = previous_update_version;
}
}
function remove_reaction(signal, dependency) {
let reactions = dependency.reactions;
if (reactions !== null) {
var index2 = index_of.call(reactions, signal);
if (index2 !== -1) {
var new_length = reactions.length - 1;
if (new_length === 0) {
reactions = dependency.reactions = null;
} else {
reactions[index2] = reactions[new_length];
reactions.pop();
}
}
}
if (reactions === null && (dependency.f & DERIVED) !== 0 &&
(new_deps === null || !includes.call(new_deps, dependency))) {
var derived2 = (
dependency
);
if ((derived2.f & CONNECTED) !== 0) {
derived2.f ^= CONNECTED;
derived2.f &= ~WAS_MARKED;
}
update_derived_status(derived2);
freeze_derived_effects(derived2);
remove_reactions(derived2, 0);
}
}
function remove_reactions(signal, start_index) {
var dependencies = signal.deps;
if (dependencies === null) return;
for (var i = start_index; i < dependencies.length; i++) {
remove_reaction(signal, dependencies[i]);
}
}
function update_effect(effect2) {
var flags2 = effect2.f;
if ((flags2 & DESTROYED) !== 0) {
return;
}
set_signal_status(effect2, CLEAN);
var previous_effect = active_effect;
var was_updating_effect = is_updating_effect;
active_effect = effect2;
is_updating_effect = true;
try {
if ((flags2 & (BLOCK_EFFECT | MANAGED_EFFECT)) !== 0) {
destroy_block_effect_children(effect2);
} else {
destroy_effect_children(effect2);
}
execute_effect_teardown(effect2);
var teardown2 = update_reaction(effect2);
effect2.teardown = typeof teardown2 === "function" ? teardown2 : null;
effect2.wv = write_version;
var dep;
if (DEV && tracing_mode_flag && (effect2.f & DIRTY) !== 0 && effect2.deps !== null) ;
} finally {
is_updating_effect = was_updating_effect;
active_effect = previous_effect;
}
}
async function tick() {
await Promise.resolve();
flushSync();
}
function get$1(signal) {
var flags2 = signal.f;
var is_derived = (flags2 & DERIVED) !== 0;
if (active_reaction !== null && !untracking) {
var destroyed = active_effect !== null && (active_effect.f & DESTROYED) !== 0;
if (!destroyed && (current_sources === null || !includes.call(current_sources, signal))) {
var deps = active_reaction.deps;
if ((active_reaction.f & REACTION_IS_UPDATING) !== 0) {
if (signal.rv < read_version) {
signal.rv = read_version;
if (new_deps === null && deps !== null && deps[skipped_deps] === signal) {
skipped_deps++;
} else if (new_deps === null) {
new_deps = [signal];
} else {
new_deps.push(signal);
}
}
} else {
(active_reaction.deps ??= []).push(signal);
var reactions = signal.reactions;
if (reactions === null) {
signal.reactions = [active_reaction];
} else if (!includes.call(reactions, active_reaction)) {
reactions.push(active_reaction);
}
}
}
}
if (is_destroying_effect && old_values.has(signal)) {
return old_values.get(signal);
}
if (is_derived) {
var derived2 = (
signal
);
if (is_destroying_effect) {
var value = derived2.v;
if ((derived2.f & CLEAN) === 0 && derived2.reactions !== null || depends_on_old_values(derived2)) {
value = execute_derived(derived2);
}
old_values.set(derived2, value);
return value;
}
var should_connect = (derived2.f & CONNECTED) === 0 && !untracking && active_reaction !== null && (is_updating_effect || (active_reaction.f & CONNECTED) !== 0);
var is_new = (derived2.f & REACTION_RAN) === 0;
if (is_dirty(derived2)) {
if (should_connect) {
derived2.f |= CONNECTED;
}
update_derived(derived2);
}
if (should_connect && !is_new) {
unfreeze_derived_effects(derived2);
reconnect(derived2);
}
}
if (batch_values?.has(signal)) {
return batch_values.get(signal);
}
if ((signal.f & ERROR_VALUE) !== 0) {
throw signal.v;
}
return signal.v;
}
function reconnect(derived2) {
derived2.f |= CONNECTED;
if (derived2.deps === null) return;
for (const dep of derived2.deps) {
(dep.reactions ??= []).push(derived2);
if ((dep.f & DERIVED) !== 0 && (dep.f & CONNECTED) === 0) {
unfreeze_derived_effects(
dep
);
reconnect(
dep
);
}
}
}
function depends_on_old_values(derived2) {
if (derived2.v === UNINITIALIZED) return true;
if (derived2.deps === null) return false;
for (const dep of derived2.deps) {
if (old_values.has(dep)) {
return true;
}
if ((dep.f & DERIVED) !== 0 && depends_on_old_values(
dep
)) {
return true;
}
}
return false;
}
function untrack(fn) {
var previous_untracking = untracking;
try {
untracking = true;
return fn();
} finally {
untracking = previous_untracking;
}
}
function deep_read_state(value) {
if (typeof value !== "object" || !value || value instanceof EventTarget) {
return;
}
if (STATE_SYMBOL in value) {
deep_read(value);
} else if (!Array.isArray(value)) {
for (let key in value) {
const prop2 = value[key];
if (typeof prop2 === "object" && prop2 && STATE_SYMBOL in prop2) {
deep_read(prop2);
}
}
}
}
function deep_read(value, visited = new Set()) {
if (typeof value === "object" && value !== null &&
!(value instanceof EventTarget) && !visited.has(value)) {
visited.add(value);
if (value instanceof Date) {
value.getTime();
}
for (let key in value) {
try {
deep_read(value[key], visited);
} catch (e) {
}
}
const proto = get_prototype_of(value);
if (proto !== Object.prototype && proto !== Array.prototype && proto !== Map.prototype && proto !== Set.prototype && proto !== Date.prototype) {
const descriptors = get_descriptors(proto);
for (let key in descriptors) {
const get2 = descriptors[key].get;
if (get2) {
try {
get2.call(value);
} catch (e) {
}
}
}
}
}
}
const PASSIVE_EVENTS = ["touchstart", "touchmove"];
function is_passive_event(name) {
return PASSIVE_EVENTS.includes(name);
}
const event_symbol = Symbol("events");
const all_registered_events = new Set();
const root_event_handles = new Set();
function create_event(event_name, dom, handler, options = {}) {
function target_handler(event2) {
if (!options.capture) {
handle_event_propagation.call(dom, event2);
}
if (!event2.cancelBubble) {
return without_reactive_context(() => {
return handler?.call(this, event2);
});
}
}
if (event_name.startsWith("pointer") || event_name.startsWith("touch") || event_name === "wheel") {
queue_micro_task(() => {
dom.addEventListener(event_name, target_handler, options);
});
} else {
dom.addEventListener(event_name, target_handler, options);
}
return target_handler;
}
function event(event_name, dom, handler, capture2, passive) {
var options = { capture: capture2, passive };
var target_handler = create_event(event_name, dom, handler, options);
if (dom === document.body ||
dom === window ||
dom === document ||
dom instanceof HTMLMediaElement) {
teardown(() => {
dom.removeEventListener(event_name, target_handler, options);
});
}
}
let last_propagated_event = null;
function handle_event_propagation(event2) {
var handler_element = this;
var owner_document = (
handler_element.ownerDocument
);
var event_name = event2.type;
var path = event2.composedPath?.() || [];
var current_target = (
path[0] || event2.target
);
last_propagated_event = event2;
var path_idx = 0;
var handled_at = last_propagated_event === event2 && event2[event_symbol];
if (handled_at) {
var at_idx = path.indexOf(handled_at);
if (at_idx !== -1 && (handler_element === document || handler_element ===
window)) {
event2[event_symbol] = handler_element;
return;
}
var handler_idx = path.indexOf(handler_element);
if (handler_idx === -1) {
return;
}
if (at_idx <= handler_idx) {
path_idx = at_idx;
}
}
current_target =
path[path_idx] || event2.target;
if (current_target === handler_element) return;
define_property(event2, "currentTarget", {
configurable: true,
get() {
return current_target || owner_document;
}
});
var previous_reaction = active_reaction;
var previous_effect = active_effect;
set_active_reaction(null);
set_active_effect(null);
try {
var throw_error;
var other_errors = [];
while (current_target !== null) {
var parent_element = current_target.assignedSlot || current_target.parentNode ||
current_target.host || null;
try {
var delegated = current_target[event_symbol]?.[event_name];
if (delegated != null && (!
current_target.disabled ||
event2.target === current_target)) {
delegated.call(current_target, event2);
}
} catch (error) {
if (throw_error) {
other_errors.push(error);
} else {
throw_error = error;
}
}
if (event2.cancelBubble || parent_element === handler_element || parent_element === null) {
break;
}
current_target = parent_element;
}
if (throw_error) {
for (let error of other_errors) {
queueMicrotask(() => {
throw error;
});
}
throw throw_error;
}
} finally {
event2[event_symbol] = handler_element;
delete event2.currentTarget;
set_active_reaction(previous_reaction);
set_active_effect(previous_effect);
}
}
const policy = (
globalThis?.window?.trustedTypes && globalThis.window.trustedTypes.createPolicy("svelte-trusted-html", {
createHTML: (html) => {
return html;
}
})
);
function create_trusted_html(html) {
return (
policy?.createHTML(html) ?? html
);
}
function create_fragment_from_html(html) {
var elem = create_element("template");
elem.innerHTML = create_trusted_html(html.replaceAll("<!>", "<!---->"));
return elem.content;
}
function assign_nodes(start, end) {
var effect2 = (
active_effect
);
if (effect2.nodes === null) {
effect2.nodes = { start, end, a: null, t: null };
}
}
function from_html(content, flags2) {
var is_fragment = (flags2 & TEMPLATE_FRAGMENT) !== 0;
var use_import_node = (flags2 & TEMPLATE_USE_IMPORT_NODE) !== 0;
var node;
var has_start = !content.startsWith("<!>");
return () => {
if (node === void 0) {
node = create_fragment_from_html(has_start ? content : "<!>" + content);
if (!is_fragment) node =
get_first_child(node);
}
var clone = (
use_import_node || is_firefox ? document.importNode(node, true) : node.cloneNode(true)
);
if (is_fragment) {
var start = (
get_first_child(clone)
);
var end = (
clone.lastChild
);
assign_nodes(start, end);
} else {
assign_nodes(clone, clone);
}
return clone;
};
}
function from_namespace(content, flags2, ns = "svg") {
var has_start = !content.startsWith("<!>");
var wrapped = `<${ns}>${has_start ? content : "<!>" + content}</${ns}>`;
var node;
return () => {
if (!node) {
var fragment = (
create_fragment_from_html(wrapped)
);
var root2 = (
get_first_child(fragment)
);
{
node =
get_first_child(root2);
}
}
var clone = (
node.cloneNode(true)
);
{
assign_nodes(clone, clone);
}
return clone;
};
}
function from_svg(content, flags2) {
return from_namespace(content, flags2, "svg");
}
function append(anchor, dom) {
if (anchor === null) {
return;
}
anchor.before(
dom
);
}
function set_text(text, value) {
var str = value == null ? "" : typeof value === "object" ? `${value}` : value;
if (str !== (text.__t ??= text.nodeValue)) {
text.__t = str;
text.nodeValue = `${str}`;
}
}
function mount(component, options) {
return _mount(component, options);
}
const listeners = new Map();
function _mount(Component, { target, anchor, props = {}, events, context, intro = true, transformError }) {
init_operations();
var component = void 0;
var unmount2 = component_root(() => {
var anchor_node = anchor ?? target.appendChild(create_text());
boundary(
anchor_node,
{
pending: () => {
}
},
(anchor_node2) => {
push({});
var ctx = (
component_context
);
if (context) ctx.c = context;
if (events) {
props.$$events = events;
}
component = Component(anchor_node2, props) || {};
pop();
},
transformError
);
var registered_events = new Set();
var event_handle = (events2) => {
for (var i = 0; i < events2.length; i++) {
var event_name = events2[i];
if (registered_events.has(event_name)) continue;
registered_events.add(event_name);
var passive = is_passive_event(event_name);
for (const node of [target, document]) {
var counts = listeners.get(node);
if (counts === void 0) {
counts = new Map();
listeners.set(node, counts);
}
var count = counts.get(event_name);
if (count === void 0) {
node.addEventListener(event_name, handle_event_propagation, { passive });
counts.set(event_name, 1);
} else {
counts.set(event_name, count + 1);
}
}
}
};
event_handle(array_from(all_registered_events));
root_event_handles.add(event_handle);
return () => {
for (var event_name of registered_events) {
for (const node of [target, document]) {
var counts = (
listeners.get(node)
);
var count = (
counts.get(event_name)
);
if (--count == 0) {
node.removeEventListener(event_name, handle_event_propagation);
counts.delete(event_name);
if (counts.size === 0) {
listeners.delete(node);
}
} else {
counts.set(event_name, count);
}
}
}
root_event_handles.delete(event_handle);
if (anchor_node !== anchor) {
anchor_node.parentNode?.removeChild(anchor_node);
}
};
});
mounted_components.set(component, unmount2);
return component;
}
let mounted_components = new WeakMap();
function unmount(component, options) {
const fn = mounted_components.get(component);
if (fn) {
mounted_components.delete(component);
return fn(options);
}
return Promise.resolve();
}
class BranchManager {
anchor;
#batches = new Map();
#onscreen = new Map();
#offscreen = new Map();
#outroing = new Set();
#transition = true;
constructor(anchor, transition = true) {
this.anchor = anchor;
this.#transition = transition;
}
#commit = (batch) => {
if (!this.#batches.has(batch)) return;
var key = (
this.#batches.get(batch)
);
var onscreen = this.#onscreen.get(key);
if (onscreen) {
resume_effect(onscreen);
this.#outroing.delete(key);
} else {
var offscreen = this.#offscreen.get(key);
if (offscreen) {
this.#onscreen.set(key, offscreen.effect);
this.#offscreen.delete(key);
offscreen.fragment.lastChild.remove();
this.anchor.before(offscreen.fragment);
onscreen = offscreen.effect;
}
}
for (const [b, k] of this.#batches) {
this.#batches.delete(b);
if (b === batch) {
break;
}
const offscreen2 = this.#offscreen.get(k);
if (offscreen2) {
destroy_effect(offscreen2.effect);
this.#offscreen.delete(k);
}
}
for (const [k, effect2] of this.#onscreen) {
if (k === key || this.#outroing.has(k)) continue;
const on_destroy = () => {
const keys = Array.from(this.#batches.values());
if (keys.includes(k)) {
var fragment = document.createDocumentFragment();
move_effect(effect2, fragment);
fragment.append(create_text());
this.#offscreen.set(k, { effect: effect2, fragment });
} else {
destroy_effect(effect2);
}
this.#outroing.delete(k);
this.#onscreen.delete(k);
};
if (this.#transition || !onscreen) {
this.#outroing.add(k);
pause_effect(effect2, on_destroy, false);
} else {
on_destroy();
}
}
};
#discard = (batch) => {
this.#batches.delete(batch);
const keys = Array.from(this.#batches.values());
for (const [k, branch2] of this.#offscreen) {
if (!keys.includes(k)) {
destroy_effect(branch2.effect);
this.#offscreen.delete(k);
}
}
};
ensure(key, fn) {
var batch = (
current_batch
);
if (fn && !this.#onscreen.has(key) && !this.#offscreen.has(key)) {
{
this.#onscreen.set(
key,
branch(() => fn(this.anchor))
);
}
}
this.#batches.set(batch, key);
{
this.#commit(batch);
}
}
}
function if_block(node, fn, elseif = false) {
var branches = new BranchManager(node);
var flags2 = elseif ? EFFECT_TRANSPARENT : 0;
function update_branch(key, fn2) {
branches.ensure(key, fn2);
}
block(() => {
var has_branch = false;
fn((fn2, key = 0) => {
has_branch = true;
update_branch(key, fn2);
});
if (!has_branch) {
update_branch(false, null);
}
}, flags2);
}
function index(_, i) {
return i;
}
function pause_effects(state2, to_destroy, controlled_anchor) {
var transitions = [];
var length = to_destroy.length;
var group;
var remaining = to_destroy.length;
for (var i = 0; i < length; i++) {
let effect2 = to_destroy[i];
pause_effect(
effect2,
() => {
if (group) {
group.pending.delete(effect2);
group.done.add(effect2);
if (group.pending.size === 0) {
var groups = (
state2.outrogroups
);
destroy_effects(array_from(group.done));
groups.delete(group);
if (groups.size === 0) {
state2.outrogroups = null;
}
}
} else {
remaining -= 1;
}
},
false
);
}
if (remaining === 0) {
var fast_path = transitions.length === 0 && controlled_anchor !== null;
if (fast_path) {
var anchor = (
controlled_anchor
);
var parent_node = (
anchor.parentNode
);
clear_text_content(parent_node);
parent_node.append(anchor);
state2.items.clear();
}
destroy_effects(to_destroy, !fast_path);
} else {
group = {
pending: new Set(to_destroy),
done: new Set()
};
(state2.outrogroups ??= new Set()).add(group);
}
}
function destroy_effects(to_destroy, remove_dom = true) {
for (var i = 0; i < to_destroy.length; i++) {
destroy_effect(to_destroy[i], remove_dom);
}
}
var offscreen_anchor;
function each(node, flags2, get_collection, get_key, render_fn, fallback_fn = null) {
var anchor = node;
var items = new Map();
{
var parent_node = (
node
);
anchor = parent_node.appendChild(create_text());
}
var fallback = null;
var each_array = derived_safe_equal(() => {
var collection = get_collection();
return is_array(collection) ? collection : collection == null ? [] : array_from(collection);
});
var array;
var first_run = true;
function commit() {
state2.fallback = fallback;
reconcile(state2, array, anchor, flags2, get_key);
if (fallback !== null) {
if (array.length === 0) {
if ((fallback.f & EFFECT_OFFSCREEN) === 0) {
resume_effect(fallback);
} else {
fallback.f ^= EFFECT_OFFSCREEN;
move(fallback, null, anchor);
}
} else {
pause_effect(fallback, () => {
fallback = null;
});
}
}
}
var effect2 = block(() => {
array =
get$1(each_array);
var length = array.length;
var keys = new Set();
for (var index2 = 0; index2 < length; index2 += 1) {
var value = array[index2];
var key = get_key(value, index2);
var item = first_run ? null : items.get(key);
if (item) {
if (item.v) internal_set(item.v, value);
if (item.i) internal_set(item.i, index2);
} else {
item = create_item(
items,
first_run ? anchor : offscreen_anchor ??= create_text(),
value,
key,
index2,
render_fn,
flags2,
get_collection
);
if (!first_run) {
item.e.f |= EFFECT_OFFSCREEN;
}
items.set(key, item);
}
keys.add(key);
}
if (length === 0 && fallback_fn && !fallback) {
if (first_run) {
fallback = branch(() => fallback_fn(anchor));
} else {
fallback = branch(() => fallback_fn(offscreen_anchor ??= create_text()));
fallback.f |= EFFECT_OFFSCREEN;
}
}
if (length > keys.size) {
{
each_key_duplicate();
}
}
if (!first_run) {
{
commit();
}
}
get$1(each_array);
});
var state2 = { effect: effect2, items, outrogroups: null, fallback };
first_run = false;
}
function skip_to_branch(effect2) {
while (effect2 !== null && (effect2.f & BRANCH_EFFECT) === 0) {
effect2 = effect2.next;
}
return effect2;
}
function reconcile(state2, array, anchor, flags2, get_key) {
var length = array.length;
var items = state2.items;
var current = skip_to_branch(state2.effect.first);
var seen;
var prev = null;
var matched = [];
var stashed = [];
var value;
var key;
var effect2;
var i;
for (i = 0; i < length; i += 1) {
value = array[i];
key = get_key(value, i);
effect2 =
items.get(key).e;
if (state2.outrogroups !== null) {
for (const group of state2.outrogroups) {
group.pending.delete(effect2);
group.done.delete(effect2);
}
}
if ((effect2.f & EFFECT_OFFSCREEN) !== 0) {
effect2.f ^= EFFECT_OFFSCREEN;
if (effect2 === current) {
move(effect2, null, anchor);
} else {
var next = prev ? prev.next : current;
if (effect2 === state2.effect.last) {
state2.effect.last = effect2.prev;
}
if (effect2.prev) effect2.prev.next = effect2.next;
if (effect2.next) effect2.next.prev = effect2.prev;
link(state2, prev, effect2);
link(state2, effect2, next);
move(effect2, next, anchor);
prev = effect2;
matched = [];
stashed = [];
current = skip_to_branch(prev.next);
continue;
}
}
if ((effect2.f & INERT) !== 0) {
resume_effect(effect2);
}
if (effect2 !== current) {
if (seen !== void 0 && seen.has(effect2)) {
if (matched.length < stashed.length) {
var start = stashed[0];
var j;
prev = start.prev;
var a = matched[0];
var b = matched[matched.length - 1];
for (j = 0; j < matched.length; j += 1) {
move(matched[j], start, anchor);
}
for (j = 0; j < stashed.length; j += 1) {
seen.delete(stashed[j]);
}
link(state2, a.prev, b.next);
link(state2, prev, a);
link(state2, b, start);
current = start;
prev = b;
i -= 1;
matched = [];
stashed = [];
} else {
seen.delete(effect2);
move(effect2, current, anchor);
link(state2, effect2.prev, effect2.next);
link(state2, effect2, prev === null ? state2.effect.first : prev.next);
link(state2, prev, effect2);
prev = effect2;
}
continue;
}
matched = [];
stashed = [];
while (current !== null && current !== effect2) {
(seen ??= new Set()).add(current);
stashed.push(current);
current = skip_to_branch(current.next);
}
if (current === null) {
continue;
}
}
if ((effect2.f & EFFECT_OFFSCREEN) === 0) {
matched.push(effect2);
}
prev = effect2;
current = skip_to_branch(effect2.next);
}
if (state2.outrogroups !== null) {
for (const group of state2.outrogroups) {
if (group.pending.size === 0) {
destroy_effects(array_from(group.done));
state2.outrogroups?.delete(group);
}
}
if (state2.outrogroups.size === 0) {
state2.outrogroups = null;
}
}
if (current !== null || seen !== void 0) {
var to_destroy = [];
if (seen !== void 0) {
for (effect2 of seen) {
if ((effect2.f & INERT) === 0) {
to_destroy.push(effect2);
}
}
}
while (current !== null) {
if ((current.f & INERT) === 0 && current !== state2.fallback) {
to_destroy.push(current);
}
current = skip_to_branch(current.next);
}
var destroy_length = to_destroy.length;
if (destroy_length > 0) {
var controlled_anchor = length === 0 ? anchor : null;
pause_effects(state2, to_destroy, controlled_anchor);
}
}
}
function create_item(items, anchor, value, key, index2, render_fn, flags2, get_collection) {
var v = (flags2 & EACH_ITEM_REACTIVE) !== 0 ? (flags2 & EACH_ITEM_IMMUTABLE) === 0 ? mutable_source(value, false, false) : source(value) : null;
var i = (flags2 & EACH_INDEX_REACTIVE) !== 0 ? source(index2) : null;
return {
v,
i,
e: branch(() => {
render_fn(anchor, v ?? value, i ?? index2, get_collection);
return () => {
items.delete(key);
};
})
};
}
function move(effect2, next, anchor) {
if (!effect2.nodes) return;
var node = effect2.nodes.start;
var end = effect2.nodes.end;
var dest = next && (next.f & EFFECT_OFFSCREEN) === 0 ? (
next.nodes.start
) : anchor;
while (node !== null) {
var next_node = (
get_next_sibling(node)
);
dest.before(node);
if (node === end) {
return;
}
node = next_node;
}
}
function link(state2, prev, next) {
if (prev === null) {
state2.effect.first = next;
} else {
prev.next = next;
}
if (next === null) {
state2.effect.last = prev;
} else {
next.prev = prev;
}
}
const whitespace = [..." \n\r\f \v\uFEFF"];
function to_class(value, hash, directives) {
var classname = value == null ? "" : "" + value;
if (directives) {
for (var key of Object.keys(directives)) {
if (directives[key]) {
classname = classname ? classname + " " + key : key;
} else if (classname.length) {
var len = key.length;
var a = 0;
while ((a = classname.indexOf(key, a)) >= 0) {
var b = a + len;
if ((a === 0 || whitespace.includes(classname[a - 1])) && (b === classname.length || whitespace.includes(classname[b]))) {
classname = (a === 0 ? "" : classname.substring(0, a)) + classname.substring(b + 1);
} else {
a = b;
}
}
}
}
}
return classname === "" ? null : classname;
}
function to_style(value, styles) {
return value == null ? null : String(value);
}
function set_class(dom, is_html, value, hash, prev_classes, next_classes) {
var prev = dom.__className;
if (prev !== value || prev === void 0) {
var next_class_name = to_class(value, hash, next_classes);
{
if (next_class_name == null) {
dom.removeAttribute("class");
} else {
dom.className = next_class_name;
}
}
dom.__className = value;
} else if (next_classes && prev_classes !== next_classes) {
for (var key in next_classes) {
var is_present = !!next_classes[key];
if (prev_classes == null || is_present !== !!prev_classes[key]) {
dom.classList.toggle(key, is_present);
}
}
}
return next_classes;
}
function set_style(dom, value, prev_styles, next_styles) {
var prev = dom.__style;
if (prev !== value) {
var next_style_attr = to_style(value);
{
if (next_style_attr == null) {
dom.removeAttribute("style");
} else {
dom.style.cssText = next_style_attr;
}
}
dom.__style = value;
}
return next_styles;
}
const IS_CUSTOM_ELEMENT = Symbol("is custom element");
const IS_HTML = Symbol("is html");
function set_attribute(element, attribute, value, skip_warning) {
var attributes = get_attributes(element);
if (attributes[attribute] === (attributes[attribute] = value)) return;
if (attribute === "loading") {
element[LOADING_ATTR_SYMBOL] = value;
}
if (value == null) {
element.removeAttribute(attribute);
} else if (typeof value !== "string" && get_setters(element).includes(attribute)) {
element[attribute] = value;
} else {
element.setAttribute(attribute, value);
}
}
function get_attributes(element) {
return (
element.__attributes ??= {
[IS_CUSTOM_ELEMENT]: element.nodeName.includes("-"),
[IS_HTML]: element.namespaceURI === NAMESPACE_HTML
}
);
}
var setters_cache = new Map();
function get_setters(element) {
var cache_key = element.getAttribute("is") || element.nodeName;
var setters = setters_cache.get(cache_key);
if (setters) return setters;
setters_cache.set(cache_key, setters = []);
var descriptors;
var proto = element;
var element_proto = Element.prototype;
while (element_proto !== proto) {
descriptors = get_descriptors(proto);
for (var key in descriptors) {
if (descriptors[key].set) {
setters.push(key);
}
}
proto = get_prototype_of(proto);
}
return setters;
}
function is_bound_this(bound_value, element_or_component) {
return bound_value === element_or_component || bound_value?.[STATE_SYMBOL] === element_or_component;
}
function bind_this(element_or_component = {}, update, get_value, get_parts) {
effect(() => {
var old_parts;
var parts;
render_effect(() => {
old_parts = parts;
parts = [];
untrack(() => {
if (element_or_component !== get_value(...parts)) {
update(element_or_component, ...parts);
if (old_parts && is_bound_this(get_value(...old_parts), element_or_component)) {
update(null, ...old_parts);
}
}
});
});
return () => {
queue_micro_task(() => {
if (parts && is_bound_this(get_value(...parts), element_or_component)) {
update(null, ...parts);
}
});
};
});
return element_or_component;
}
function init(immutable = false) {
const context = (
component_context
);
const callbacks = context.l.u;
if (!callbacks) return;
let props = () => deep_read_state(context.s);
if (immutable) {
let version = 0;
let prev = (
{}
);
const d = derived(() => {
let changed = false;
const props2 = context.s;
for (const key in props2) {
if (props2[key] !== prev[key]) {
prev[key] = props2[key];
changed = true;
}
}
if (changed) version++;
return version;
});
props = () => get$1(d);
}
if (callbacks.b.length) {
user_pre_effect(() => {
observe_all(context, props);
run_all(callbacks.b);
});
}
user_effect(() => {
const fns = untrack(() => callbacks.m.map(run));
return () => {
for (const fn of fns) {
if (typeof fn === "function") {
fn();
}
}
};
});
if (callbacks.a.length) {
user_effect(() => {
observe_all(context, props);
run_all(callbacks.a);
});
}
}
function observe_all(context, props) {
if (context.l.s) {
for (const signal of context.l.s) get$1(signal);
}
props();
}
function subscribe_to_store(store, run2, invalidate) {
if (store == null) {
run2(void 0);
return noop;
}
const unsub = untrack(
() => store.subscribe(
run2,
invalidate
)
);
return unsub.unsubscribe ? () => unsub.unsubscribe() : unsub;
}
const subscriber_queue = [];
function writable(value, start = noop) {
let stop = null;
const subscribers = new Set();
function set2(new_value) {
if (safe_not_equal(value, new_value)) {
value = new_value;
if (stop) {
const run_queue = !subscriber_queue.length;
for (const subscriber of subscribers) {
subscriber[1]();
subscriber_queue.push(subscriber, value);
}
if (run_queue) {
for (let i = 0; i < subscriber_queue.length; i += 2) {
subscriber_queue[i][0](subscriber_queue[i + 1]);
}
subscriber_queue.length = 0;
}
}
}
}
function update(fn) {
set2(fn(
value
));
}
function subscribe(run2, invalidate = noop) {
const subscriber = [run2, invalidate];
subscribers.add(subscriber);
if (subscribers.size === 1) {
stop = start(set2, update) || noop;
}
run2(
value
);
return () => {
subscribers.delete(subscriber);
if (subscribers.size === 0 && stop) {
stop();
stop = null;
}
};
}
return { set: set2, update, subscribe };
}
function get(store) {
let value;
subscribe_to_store(store, (_) => value = _)();
return value;
}
let is_store_binding = false;
let IS_UNMOUNTED = Symbol();
function store_get(store, store_name, stores) {
const entry = stores[store_name] ??= {
store: null,
source: mutable_source(void 0),
unsubscribe: noop
};
if (entry.store !== store && !(IS_UNMOUNTED in stores)) {
entry.unsubscribe();
entry.store = store ?? null;
if (store == null) {
entry.source.v = void 0;
entry.unsubscribe = noop;
} else {
var is_synchronous_callback = true;
entry.unsubscribe = subscribe_to_store(store, (v) => {
if (is_synchronous_callback) {
entry.source.v = v;
} else {
set(entry.source, v);
}
});
is_synchronous_callback = false;
}
}
if (store && IS_UNMOUNTED in stores) {
return get(store);
}
return get$1(entry.source);
}
function setup_stores() {
const stores = {};
function cleanup() {
teardown(() => {
for (var store_name in stores) {
const ref = stores[store_name];
ref.unsubscribe();
}
define_property(stores, IS_UNMOUNTED, {
enumerable: false,
value: true
});
});
}
return [stores, cleanup];
}
function capture_store_binding(fn) {
var previous_is_store_binding = is_store_binding;
try {
is_store_binding = false;
return [fn(), is_store_binding];
} finally {
is_store_binding = previous_is_store_binding;
}
}
function prop(props, key, flags2, fallback) {
var runes = !legacy_mode_flag || (flags2 & PROPS_IS_RUNES) !== 0;
var bindable = (flags2 & PROPS_IS_BINDABLE) !== 0;
var fallback_value = (
fallback
);
var fallback_dirty = true;
var get_fallback = () => {
if (fallback_dirty) {
fallback_dirty = false;
fallback_value =
fallback;
}
return fallback_value;
};
var setter;
{
var is_entry_props = STATE_SYMBOL in props || LEGACY_PROPS in props;
setter = get_descriptor(props, key)?.set ?? (is_entry_props && key in props ? (v) => props[key] = v : void 0);
}
var initial_value;
var is_store_sub = false;
{
[initial_value, is_store_sub] = capture_store_binding(() => (
props[key]
));
}
if (initial_value === void 0 && fallback !== void 0) {
initial_value = get_fallback();
if (setter) {
if (runes) props_invalid_value();
setter(initial_value);
}
}
var getter;
if (runes) {
getter = () => {
var value = (
props[key]
);
if (value === void 0) return get_fallback();
fallback_dirty = true;
return value;
};
} else {
getter = () => {
var value = (
props[key]
);
if (value !== void 0) {
fallback_value =
void 0;
}
return value === void 0 ? fallback_value : value;
};
}
if (runes && (flags2 & PROPS_IS_UPDATED) === 0) {
return getter;
}
if (setter) {
var legacy_parent = props.$$legacy;
return (
(function(value, mutation) {
if (arguments.length > 0) {
if (!runes || !mutation || legacy_parent || is_store_sub) {
setter(mutation ? getter() : value);
}
return value;
}
return getter();
})
);
}
var overridden = false;
var d = derived_safe_equal(() => {
overridden = false;
return getter();
});
get$1(d);
var parent_effect = (
active_effect
);
return (
(function(value, mutation) {
if (arguments.length > 0) {
const new_value = mutation ? get$1(d) : runes && bindable ? proxy(value) : value;
set(d, new_value);
overridden = true;
if (fallback_value !== void 0) {
fallback_value = new_value;
}
return value;
}
if (is_destroying_effect && overridden || (parent_effect.f & DESTROYED) !== 0) {
return d.v;
}
return get$1(d);
})
);
}
function onMount(fn) {
if (component_context === null) {
lifecycle_outside_component();
}
if (legacy_mode_flag && component_context.l !== null) {
init_update_callbacks(component_context).m.push(fn);
} else {
user_effect(() => {
const cleanup = untrack(fn);
if (typeof cleanup === "function") return (
cleanup
);
});
}
}
function onDestroy(fn) {
if (component_context === null) {
lifecycle_outside_component();
}
onMount(() => () => untrack(fn));
}
function init_update_callbacks(context) {
var l = (
context.l
);
return l.u ??= { a: [], b: [], m: [] };
}
const PUBLIC_VERSION = "5";
if (typeof window !== "undefined") {
((window.__svelte ??= {}).v ??= new Set()).add(PUBLIC_VERSION);
}
enable_legacy_mode_flag();
const deleteIcon = "data:image/svg+xml,%3c?xml%20version='1.0'%20standalone='no'?%3e%3c!DOCTYPE%20svg%20PUBLIC%20'-//W3C//DTD%20SVG%201.1//EN'%20'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'%3e%3csvg%20t='1772784991371'%20class='icon'%20viewBox='0%200%201024%201024'%20version='1.1'%20xmlns='http://www.w3.org/2000/svg'%20p-id='22990'%20xmlns:xlink='http://www.w3.org/1999/xlink'%20width='200'%20height='200'%3e%3cpath%20d='M911.9%20198l-8-8H675.2c-8.7-35.4-29.1-67.4-57.5-90.6C587.8%2075.3%20550.3%2062%20512%2062s-75.9%2013.3-105.7%2037.4c-28.5%2023.1-48.9%2055.2-57.5%2090.6h-229l-8%208v64l8%208h263.4c10.6%200%2021-3.9%2028.6-11.2%207.9-7.6%2012.2-17.8%2012.2-28.7%200-23.5%209.1-45.6%2025.8-62.2%2016.6-16.7%2038.7-25.8%2062.2-25.8s45.6%209.2%2062.2%2025.8c16.6%2016.7%2025.8%2038.8%2025.8%2062.2%200%2010.9%204.3%2021.1%2012.2%2028.7%207.6%207.4%2018%2011.2%2028.6%2011.2h263.1c4.4%200%208-3.6%208-8v-64zM792%20370c-4.4%200-8%203.6-8%208v460.5c-0.2%2024.1-19.9%2043.5-44%2043.5H283.9c-24.1%200-43.8-19.4-44-43.6V378c0-4.4-3.6-8-8-8h-64c-4.4%200-8%203.6-8%208v459.7c0%2069.7%2041.5%20124.3%2094.5%20124.3h515.1c53%200%2094.5-54.6%2094.5-124.3V378c0-4.4-3.6-8-8-8h-64z'%20p-id='22991'%20fill='%23d81e06'%3e%3c/path%3e%3cpath%20d='M424%20822h-56c-4.4%200-8-3.6-8-8V430c0-4.4%203.6-8%208-8h56c4.4%200%208%203.6%208%208v384c0%204.4-3.6%208-8%208zM664%20822h-56c-4.4%200-8-3.6-8-8V430c0-4.4%203.6-8%208-8h56c4.4%200%208%203.6%208%208v384c0%204.4-3.6%208-8%208z'%20p-id='22992'%20fill='%23d81e06'%3e%3c/path%3e%3c/svg%3e";
const sendIcon = "data:image/svg+xml,%3c?xml%20version='1.0'%20standalone='no'?%3e%3c!DOCTYPE%20svg%20PUBLIC%20'-//W3C//DTD%20SVG%201.1//EN'%20'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'%3e%3csvg%20t='1772784880759'%20class='icon'%20viewBox='0%200%201024%201024'%20version='1.1'%20xmlns='http://www.w3.org/2000/svg'%20p-id='17553'%20xmlns:xlink='http://www.w3.org/1999/xlink'%20width='200'%20height='200'%3e%3cpath%20d='M1012.3026%207.372257a32.022693%2032.022693%200%200%200-32.662508-4.926568l-959.721081%20396.876658a31.990703%2031.990703%200%200%200-7.517815%2054.704102l243.833136%20191.528337a31.990703%2031.990703%200%201%200%2039.540508-50.289385l-200.77365-157.746155L948.097259%2084.693786l-178.924%20852.392273-236.443284-169.80665a32.054684%2032.054684%200%200%200-39.060648%201.34361l-82.40805%2068.172187%203.071108-125.339573L775.251493%20349.992683a32.022693%2032.022693%200%200%200-45.298835-45.234853L360.044162%20675.274148a32.054684%2032.054684%200%200%200-9.341285%2021.84965l-5.118512%20208.291466a31.958712%2031.958712%200%200%200%2052.336789%2025.432608l117.501851-97.187754%20256.30951%20184.074503a31.894731%2031.894731%200%200%200%2030.231214%203.838884%2031.990703%2031.990703%200%200%200%2019.706273-23.289231l201.477446-959.721081a31.990703%2031.990703%200%200%200-10.844848-31.190936z'%20p-id='17554'%20fill='%2300aeff'%3e%3c/path%3e%3c/svg%3e";
const INSTALL_GUIDE_URL = "https://greasyfork.org/zh-CN/scripts/568599-linux-do-voice-msg";
const MAX_RECORDING_MS = 5 * 60 * 1e3;
const MAX_FILE_SIZE_BYTES = 4 * 1024 * 1024;
const TARGET_AUDIO_BITRATE = 64e3;
const RECORDING_TIMESLICE_MS = 500;
const EDITOR_ROOT_SELECTOR = ".d-editor";
const EDITOR_TOOLBAR_SELECTOR = ".d-editor-button-bar";
const EDITOR_TEXTAREA_SELECTOR = "textarea.d-editor-input";
const EDITOR_TEXTAREA_WRAPPER_SELECTOR = ".d-editor-textarea-wrapper";
const EDITOR_RICH_TEXT_SELECTOR = ".ProseMirror";
const EDITOR_RICH_TEXT_CONTAINER_SELECTOR = ".ProseMirror-container, .d-editor-input.--rich-editor-enabled, .d-editor-input:not(textarea)";
const ATTACHMENT_SELECTOR = ".cooked a.attachment";
const EDITOR_INJECTED_ATTR = "data-voice-injected";
const INLINE_RECORDER_ATTR = "data-voice-inline";
const INLINE_RECORDER_HOST_CLASS = "ldv-inline-recorder-host";
const VOICE_PLAYER_HOST_CLASS = "ldv-voice-player-host";
const VOICE_PROCESSED_ATTR = "data-voice-processed";
const DETECT_SCAN_DEBOUNCE_MS = 300;
const PLAYER_SYNC_EVENT = "ldvmsg:player-activate";
const SUPPORTED_AUDIO_FORMATS = [
{
mimeType: "audio/webm;codecs=opus",
extension: "opus",
label: "Opus"
},
{
mimeType: "audio/mpeg",
extension: "mp3",
label: "MP3"
}
];
function formatRecordingDuration(durationMs) {
const bounded = Math.max(0, durationMs);
const minutes = Math.floor(bounded / 6e4);
const seconds = Math.floor(bounded % 6e4 / 1e3);
const tenths = Math.floor(bounded % 1e3 / 100);
return `${String(minutes).padStart(2, "0")}:${String(seconds).padStart(2, "0")}.${tenths}`;
}
function formatPlaybackDuration(durationSeconds) {
if (!Number.isFinite(durationSeconds) || durationSeconds <= 0) {
return "0:00";
}
const totalSeconds = Math.max(0, Math.round(durationSeconds));
const minutes = Math.floor(totalSeconds / 60);
const seconds = totalSeconds % 60;
return `${minutes}:${String(seconds).padStart(2, "0")}`;
}
function formatPlaybackRange(currentSeconds, totalSeconds) {
return `${formatPlaybackDuration(currentSeconds)} / ${formatPlaybackDuration(totalSeconds)}`;
}
function formatBytes(bytes) {
if (bytes < 1024) {
return `${bytes} B`;
}
if (bytes < 1024 * 1024) {
return `${(bytes / 1024).toFixed(1)} KB`;
}
return `${(bytes / (1024 * 1024)).toFixed(2)} MB`;
}
function getSupportedAudioFormat() {
if (typeof MediaRecorder === "undefined") {
return null;
}
if (typeof MediaRecorder.isTypeSupported !== "function") {
return SUPPORTED_AUDIO_FORMATS[0] ?? null;
}
return SUPPORTED_AUDIO_FORMATS.find((candidate) => MediaRecorder.isTypeSupported(candidate.mimeType)) ?? null;
}
function clamp(value, min, max) {
return Math.min(max, Math.max(min, value));
}
function createWaveformBars(seed, count = 36) {
let state2 = 0;
for (const character of seed) {
state2 = state2 * 31 + character.charCodeAt(0) >>> 0;
}
return Array.from({ length: count }, (_, index2) => {
state2 = state2 * 1664525 + 1013904223 >>> 0;
const randomFactor = (state2 & 1023) / 1023;
const curveFactor = Math.sin(index2 / Math.max(1, count - 1) * Math.PI * 1.15);
const height = 0.28 + curveFactor * 0.18 + randomFactor * 0.42;
return clamp(height, 0.18, 1);
});
}
async function decodeAudioDuration(source2) {
if (typeof AudioContext === "undefined") {
return null;
}
const audioContext = new AudioContext();
try {
const decoded = await audioContext.decodeAudioData(source2.slice(0));
return Number.isFinite(decoded.duration) && decoded.duration > 0 ? decoded.duration : null;
} catch {
return null;
} finally {
void audioContext.close().catch(() => void 0);
}
}
var root$3 = from_html(`<canvas class="ldv-wave-canvas svelte-b21gtz"></canvas>`);
function WaveVisualizer($$anchor, $$props) {
push($$props, false);
let readFrame = prop($$props, "readFrame", 8, null);
let active = prop($$props, "active", 8, false);
let paused = prop($$props, "paused", 8, false);
let displayHeight = prop($$props, "displayHeight", 8, 54);
const SAMPLE_INTERVAL_MS = 120;
let canvas = mutable_source();
let animationFrameId = 0;
let history = [];
let incomingSample = 0.32;
let sampleAccumulator = 0;
let previousTimestamp = 0;
const sourceBuffer = new Uint8Array(256);
function createSeedBars(count) {
return Array.from({ length: count }, (_, index2) => {
const wave = Math.sin(index2 * 0.55) * 0.16 + Math.cos(index2 * 0.23) * 0.12;
return clamp(0.24 + Math.abs(wave), 0.14, 0.82);
});
}
function getBarCount() {
const width = get$1(canvas)?.getBoundingClientRect().width || 300;
return Math.max(26, Math.floor(width / 10));
}
function ensureHistory(barCount) {
if (history.length === barCount) {
return;
}
const seedBars = createSeedBars(barCount);
const preserved = history.slice(-barCount);
history = Array.from({ length: barCount }, (_, index2) => preserved[index2] ?? seedBars[index2]);
if (!incomingSample) {
incomingSample = history[history.length - 1] ?? 0.32;
}
}
function resizeCanvas() {
if (!get$1(canvas)) {
return;
}
const bounds = get$1(canvas).getBoundingClientRect();
const nextWidth = Math.max(240, Math.floor(bounds.width * window.devicePixelRatio));
const nextHeight = Math.max(44, Math.floor(displayHeight() * window.devicePixelRatio));
if (get$1(canvas).width !== nextWidth || get$1(canvas).height !== nextHeight) {
mutate(canvas, get$1(canvas).width = nextWidth);
mutate(canvas, get$1(canvas).height = nextHeight);
}
ensureHistory(getBarCount());
}
function measureAmplitude() {
if (!readFrame() || !readFrame()(sourceBuffer)) {
return incomingSample || 0.32;
}
const chunkSize = 48;
let energy = 0;
let peak = 0;
for (let start = 0; start < sourceBuffer.length; start += chunkSize) {
const end = Math.min(sourceBuffer.length, start + chunkSize);
let localEnergy = 0;
for (let index2 = start; index2 < end; index2 += 1) {
localEnergy += Math.abs(sourceBuffer[index2] - 128) / 128;
}
peak = Math.max(peak, localEnergy / Math.max(1, end - start));
energy += localEnergy;
}
const average = energy / sourceBuffer.length;
return clamp(average * 0.55 + peak * 0.9 + 0.12, 0.16, 0.9);
}
function pushNextSample() {
history.push(incomingSample);
const barCount = getBarCount();
if (history.length > barCount) {
history = history.slice(history.length - barCount);
}
incomingSample = measureAmplitude();
}
function advanceSampling(elapsedMs) {
if (!active() || paused()) {
sampleAccumulator = 0;
return;
}
sampleAccumulator += elapsedMs;
while (sampleAccumulator >= SAMPLE_INTERVAL_MS) {
pushNextSample();
sampleAccumulator -= SAMPLE_INTERVAL_MS;
}
}
function drawRoundedRect(context, x, y, width, height, radius) {
const clampedRadius = Math.min(radius, width / 2, height / 2);
context.beginPath();
context.moveTo(x + clampedRadius, y);
context.lineTo(x + width - clampedRadius, y);
context.quadraticCurveTo(x + width, y, x + width, y + clampedRadius);
context.lineTo(x + width, y + height - clampedRadius);
context.quadraticCurveTo(x + width, y + height, x + width - clampedRadius, y + height);
context.lineTo(x + clampedRadius, y + height);
context.quadraticCurveTo(x, y + height, x, y + height - clampedRadius);
context.lineTo(x, y + clampedRadius);
context.quadraticCurveTo(x, y, x + clampedRadius, y);
context.closePath();
context.fill();
}
function draw() {
if (!get$1(canvas)) {
return;
}
resizeCanvas();
const context = get$1(canvas).getContext("2d");
if (!context) {
return;
}
const width = get$1(canvas).width;
const height = get$1(canvas).height;
const barCount = history.length || getBarCount();
const step = width / Math.max(1, barCount);
const barWidth = Math.max(3, Math.min(step * 0.48, 8 * window.devicePixelRatio));
const maxBarHeight = height * 0.9;
const progress = active() && !paused() ? sampleAccumulator / SAMPLE_INTERVAL_MS : 0;
const styles = getComputedStyle(get$1(canvas));
const activeColor = styles.getPropertyValue("--ldv-wave-color").trim() || styles.getPropertyValue("--tertiary").trim() || styles.getPropertyValue("--primary").trim();
const inactiveColor = styles.getPropertyValue("--ldv-wave-inactive").trim() || styles.getPropertyValue("--quaternary").trim() || styles.getPropertyValue("--primary").trim();
const gradient = context.createLinearGradient(0, 0, width, 0);
gradient.addColorStop(0, activeColor);
gradient.addColorStop(0.72, activeColor);
gradient.addColorStop(1, inactiveColor);
context.clearRect(0, 0, width, height);
context.fillStyle = gradient;
context.globalAlpha = active() ? 1 : paused() ? 0.72 : 0.88;
history.forEach((value, index2) => {
const barHeight = Math.max(height * 0.22, maxBarHeight * value);
const x = index2 * step - step * progress + (step - barWidth) / 2;
const y = (height - barHeight) / 2;
drawRoundedRect(context, x, y, barWidth, barHeight, barWidth / 2);
});
if (active() || paused()) {
const previewHeight = Math.max(height * 0.22, maxBarHeight * incomingSample);
const previewX = history.length * step - step * progress + (step - barWidth) / 2;
const previewY = (height - previewHeight) / 2;
drawRoundedRect(context, previewX, previewY, barWidth, previewHeight, barWidth / 2);
}
context.globalAlpha = 1;
}
function loop(timestamp) {
if (previousTimestamp === 0) {
previousTimestamp = timestamp;
}
const elapsedMs = timestamp - previousTimestamp;
previousTimestamp = timestamp;
if (active() && !paused()) {
advanceSampling(elapsedMs);
}
draw();
animationFrameId = window.requestAnimationFrame(loop);
}
onMount(() => {
const handleResize = () => {
resizeCanvas();
draw();
};
resizeCanvas();
incomingSample = measureAmplitude();
draw();
animationFrameId = window.requestAnimationFrame(loop);
window.addEventListener("resize", handleResize);
return () => {
window.cancelAnimationFrame(animationFrameId);
window.removeEventListener("resize", handleResize);
};
});
onDestroy(() => {
window.cancelAnimationFrame(animationFrameId);
previousTimestamp = 0;
});
init();
var canvas_1 = root$3();
bind_this(canvas_1, ($$value) => set(canvas, $$value), () => get$1(canvas));
template_effect(() => set_style(canvas_1, `height: ${displayHeight()}px`));
append($$anchor, canvas_1);
pop();
}
let csrfTokenCache = null;
function readCsrfTokenFromMeta() {
const token = document.querySelector('meta[name="csrf-token"]')?.content?.trim();
return token || null;
}
async function getCsrfToken(forceRefresh = false) {
if (!forceRefresh) {
const fromMeta = readCsrfTokenFromMeta();
if (fromMeta) {
csrfTokenCache = fromMeta;
return fromMeta;
}
if (csrfTokenCache) {
return csrfTokenCache;
}
}
const response = await fetch("/session/csrf", {
credentials: "same-origin",
headers: {
Accept: "application/json",
"X-Requested-With": "XMLHttpRequest"
}
});
if (!response.ok) {
throw new Error("无法获取论坛上传令牌,请刷新页面后重试。");
}
const payload = await response.json();
if (!payload.csrf) {
throw new Error("论坛未返回有效的上传令牌。");
}
csrfTokenCache = payload.csrf;
return payload.csrf;
}
async function uploadVoiceFileOnce(blob, fileName, csrfToken, onProgress) {
const formData = new FormData();
formData.append("type", "composer");
formData.append("upload_type", "composer");
formData.append("file", blob, fileName);
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open("POST", "/uploads.json", true);
xhr.responseType = "json";
xhr.setRequestHeader("X-CSRF-Token", csrfToken);
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
xhr.upload.addEventListener("progress", (event2) => {
if (!onProgress) {
return;
}
const total = event2.total || blob.size;
const loaded = event2.loaded;
const percent = total > 0 ? Math.min(100, Math.round(loaded / total * 100)) : 0;
onProgress({ loaded, total, percent });
});
xhr.addEventListener("error", () => {
reject(new Error("上传失败,请检查网络连接后重试。"));
});
xhr.addEventListener("timeout", () => {
reject(new Error("上传超时,请稍后重试。"));
});
xhr.addEventListener("load", () => {
const payload = xhr.response;
if (xhr.status >= 200 && xhr.status < 300 && payload && "short_url" in payload) {
onProgress?.({ loaded: blob.size, total: blob.size, percent: 100 });
resolve(payload);
return;
}
const firstError = Array.isArray(payload?.errors) ? payload.errors?.[0] : null;
reject(new Error(firstError || "上传失败,论坛没有返回可用的附件地址。"));
});
xhr.timeout = 6e4;
xhr.send(formData);
});
}
async function uploadVoiceFile(blob, fileName, onProgress) {
try {
const csrfToken = await getCsrfToken();
return await uploadVoiceFileOnce(blob, fileName, csrfToken, onProgress);
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
if (!/csrf|令牌|token/i.test(message)) {
throw error;
}
const refreshedToken = await getCsrfToken(true);
return uploadVoiceFileOnce(blob, fileName, refreshedToken, onProgress);
}
}
function buildVoiceMessageMarkdown(shortUrl) {
return `
[语音消息|attachment](${shortUrl})➔[安装插件播放](${INSTALL_GUIDE_URL})
`;
}
function lookupAppEvents() {
const discourse = window.Discourse;
const appEvents = discourse?.lookup?.("service:app-events");
if (!appEvents || typeof appEvents !== "object") {
return null;
}
return typeof appEvents.trigger === "function" ? appEvents : null;
}
function insertMarkdownIntoActiveComposer(markdown) {
const appEvents = lookupAppEvents();
if (!appEvents) {
return false;
}
appEvents.trigger("composer:insert-block", markdown);
return true;
}
function insertEmptyParagraphIntoActiveComposer() {
const appEvents = lookupAppEvents();
if (!appEvents) {
return false;
}
appEvents.trigger("composer:insert-text", "\n\n");
return true;
}
function insertMarkdownIntoTextarea(textarea, markdown) {
const start = textarea.selectionStart ?? textarea.value.length;
const end = textarea.selectionEnd ?? start;
const before = textarea.value.slice(0, start);
const after = textarea.value.slice(end);
textarea.value = `${before}${markdown}${after}`;
const nextCursor = start + markdown.length;
textarea.selectionStart = nextCursor;
textarea.selectionEnd = nextCursor;
textarea.focus();
textarea.dispatchEvent(new Event("input", { bubbles: true }));
textarea.dispatchEvent(new Event("change", { bubbles: true }));
}
function insertVoiceMessageIntoComposer(markdown, options = {}) {
if (options.richEditor) {
options.richEditor.focus();
}
if (options.richEditor && insertMarkdownIntoActiveComposer(markdown)) {
insertEmptyParagraphIntoActiveComposer();
return;
}
if (options.textarea) {
insertMarkdownIntoTextarea(options.textarea, markdown);
return;
}
if (insertMarkdownIntoActiveComposer(markdown)) {
return;
}
throw new Error("没有找到可用的编辑器,无法插入语音消息。");
}
function createShortUuid(length = 8) {
const bytes = new Uint8Array(length);
crypto.getRandomValues(bytes);
return Array.from(bytes, (byte) => (byte % 16).toString(16)).join("");
}
function createInitialSnapshot() {
return {
phase: "idle",
durationMs: 0,
maxDurationMs: MAX_RECORDING_MS,
format: null,
errorMessage: null,
maxDurationReached: false
};
}
class VoiceRecorder {
snapshot = createInitialSnapshot();
listeners = new Set();
stream = null;
mediaRecorder = null;
audioContext = null;
analyser = null;
sourceNode = null;
destinationNode = null;
silentSourceNode = null;
silentGainNode = null;
chunks = [];
currentFormat = null;
tickTimer = null;
accumulatedMs = 0;
startedAt = 0;
stopReason = null;
stopPromise = null;
resolveStop = null;
rejectStop = null;
result = null;
subscribe(listener) {
this.listeners.add(listener);
listener(this.snapshot);
return () => {
this.listeners.delete(listener);
};
}
getSnapshot() {
return this.snapshot;
}
getResult() {
return this.result;
}
async start() {
if (this.snapshot.phase !== "idle" && this.snapshot.phase !== "cancelled") {
throw new Error("录音器当前不可重复启动。");
}
if (!navigator.mediaDevices?.getUserMedia) {
throw new Error("当前浏览器不支持麦克风录音。");
}
const supportedFormat = getSupportedAudioFormat();
if (!supportedFormat) {
throw new Error("当前浏览器不支持 Opus 或 MP3 录音。");
}
this.resetSession();
this.currentFormat = supportedFormat;
this.updateSnapshot({
phase: "starting",
durationMs: 0,
format: supportedFormat,
errorMessage: null,
maxDurationReached: false
});
try {
await this.createRecorderPipeline(supportedFormat);
await this.attachMicrophone();
if (!this.mediaRecorder) {
throw new Error("录音器初始化失败。");
}
this.startedAt = performance.now();
this.mediaRecorder.start(RECORDING_TIMESLICE_MS);
this.startTicker();
this.updateSnapshot({
phase: "recording",
durationMs: 0,
format: supportedFormat
});
} catch (error) {
this.fail(this.toFriendlyError(error));
throw error;
}
}
async pause() {
if (!this.mediaRecorder || this.snapshot.phase !== "recording") {
return;
}
this.accumulatedMs = this.getCurrentDurationMs();
this.startedAt = 0;
this.mediaRecorder.pause();
this.stopTicker();
try {
this.detachMicrophone();
this.updateSnapshot({
phase: "paused",
durationMs: this.accumulatedMs,
errorMessage: null
});
} catch (error) {
this.fail(this.toFriendlyError(error));
throw error;
}
}
async resume() {
if (!this.mediaRecorder || this.snapshot.phase !== "paused") {
return;
}
const durationMs = Math.min(this.accumulatedMs, MAX_RECORDING_MS);
this.updateSnapshot({
phase: "starting",
durationMs,
errorMessage: null
});
try {
await this.attachMicrophone();
this.startedAt = performance.now();
this.mediaRecorder.resume();
this.startTicker();
this.updateSnapshot({
phase: "recording",
durationMs,
errorMessage: null
});
} catch (error) {
this.detachMicrophone();
this.updateSnapshot({
phase: "paused",
durationMs,
errorMessage: this.toFriendlyError(error)
});
throw error;
}
}
async finalize(reason = "send") {
if (this.result) {
return this.result;
}
if (this.stopPromise) {
return this.stopPromise;
}
if (!this.mediaRecorder) {
throw new Error("录音尚未开始。");
}
this.stopReason = reason;
this.accumulatedMs = this.getCurrentDurationMs();
this.startedAt = 0;
this.updateSnapshot({
phase: "stopping",
durationMs: Math.min(this.accumulatedMs, MAX_RECORDING_MS),
maxDurationReached: reason === "limit"
});
this.stopPromise = new Promise((resolve, reject) => {
this.resolveStop = resolve;
this.rejectStop = reject;
});
this.mediaRecorder.stop();
return this.stopPromise;
}
async cancel() {
if (this.snapshot.phase === "cancelled" || this.snapshot.phase === "idle") {
return;
}
this.stopReason = "cancel";
this.stopTicker();
if (this.mediaRecorder && this.mediaRecorder.state !== "inactive") {
this.mediaRecorder.stop();
return;
}
this.cleanupRecorderPipeline();
this.updateSnapshot({ phase: "cancelled" });
}
readWaveformFrame(target) {
if (!this.analyser) {
return false;
}
this.analyser.getByteTimeDomainData(target);
return true;
}
async createRecorderPipeline(format) {
const audioContext = new AudioContext();
if (audioContext.state === "suspended") {
await audioContext.resume();
}
const analyser = audioContext.createAnalyser();
analyser.fftSize = 2048;
analyser.smoothingTimeConstant = 0.85;
const destinationNode = audioContext.createMediaStreamDestination();
const silentSourceNode = audioContext.createConstantSource();
const silentGainNode = audioContext.createGain();
silentGainNode.gain.value = 0;
silentSourceNode.connect(silentGainNode);
silentGainNode.connect(destinationNode);
silentSourceNode.start();
const mediaRecorder = new MediaRecorder(destinationNode.stream, {
mimeType: format.mimeType,
audioBitsPerSecond: TARGET_AUDIO_BITRATE
});
mediaRecorder.addEventListener("dataavailable", (event2) => {
if (this.stopReason === "cancel") {
return;
}
if (event2.data && event2.data.size > 0) {
this.chunks.push(event2.data);
}
});
mediaRecorder.addEventListener("stop", () => {
this.handleRecorderStop();
});
mediaRecorder.addEventListener("error", (event2) => {
this.fail(event2.error?.message || "录音器发生未知错误。");
});
this.audioContext = audioContext;
this.analyser = analyser;
this.destinationNode = destinationNode;
this.silentSourceNode = silentSourceNode;
this.silentGainNode = silentGainNode;
this.mediaRecorder = mediaRecorder;
}
async attachMicrophone() {
if (!navigator.mediaDevices?.getUserMedia) {
throw new Error("当前浏览器不支持麦克风录音。");
}
if (!this.audioContext || !this.analyser || !this.destinationNode) {
throw new Error("录音管线尚未初始化。");
}
const stream = await navigator.mediaDevices.getUserMedia({
audio: {
channelCount: 1,
echoCancellation: true,
noiseSuppression: true
}
});
try {
const sourceNode = this.audioContext.createMediaStreamSource(stream);
sourceNode.connect(this.analyser);
sourceNode.connect(this.destinationNode);
this.stream = stream;
this.sourceNode = sourceNode;
} catch (error) {
stream.getTracks().forEach((track) => track.stop());
throw error;
}
}
detachMicrophone() {
this.sourceNode?.disconnect();
this.stream?.getTracks().forEach((track) => track.stop());
this.sourceNode = null;
this.stream = null;
}
handleRecorderStop() {
this.stopTicker();
if (this.stopReason === "cancel") {
this.cleanupRecorderPipeline();
this.stopPromise = null;
this.resolveStop = null;
this.rejectStop = null;
this.updateSnapshot({ phase: "cancelled" });
return;
}
const format = this.currentFormat;
if (!format) {
this.fail("录音格式丢失,请重新开始录音。");
return;
}
const blob = new Blob(this.chunks, { type: format.mimeType });
const durationMs = Math.min(Math.round(this.accumulatedMs), MAX_RECORDING_MS);
const result = {
blob,
durationMs,
format,
fileName: `ldvmsg-${Date.now()}-${createShortUuid()}.${format.extension}.zip`,
fileSize: blob.size,
stoppedByLimit: this.stopReason === "limit"
};
this.result = result;
this.cleanupRecorderPipeline();
this.updateSnapshot({
phase: "ready",
durationMs,
maxDurationReached: result.stoppedByLimit
});
this.resolveStop?.(result);
this.stopPromise = null;
this.resolveStop = null;
this.rejectStop = null;
}
startTicker() {
this.stopTicker();
this.tickTimer = window.setInterval(() => {
const durationMs = this.getCurrentDurationMs();
this.updateSnapshot({ durationMs });
if (durationMs >= MAX_RECORDING_MS && this.snapshot.phase === "recording") {
void this.finalize("limit").catch((error) => {
this.fail(this.toFriendlyError(error));
});
}
}, 100);
}
stopTicker() {
if (this.tickTimer !== null) {
window.clearInterval(this.tickTimer);
this.tickTimer = null;
}
}
getCurrentDurationMs() {
if (this.snapshot.phase === "recording" && this.startedAt > 0) {
return Math.min(MAX_RECORDING_MS, this.accumulatedMs + (performance.now() - this.startedAt));
}
return Math.min(MAX_RECORDING_MS, this.accumulatedMs);
}
cleanupRecorderPipeline() {
this.detachMicrophone();
this.silentSourceNode?.disconnect();
this.silentGainNode?.disconnect();
try {
this.silentSourceNode?.stop();
} catch {
}
void this.audioContext?.close().catch(() => void 0);
this.mediaRecorder = null;
this.audioContext = null;
this.analyser = null;
this.destinationNode = null;
this.silentSourceNode = null;
this.silentGainNode = null;
}
resetSession() {
this.stopTicker();
this.cleanupRecorderPipeline();
this.chunks = [];
this.currentFormat = null;
this.accumulatedMs = 0;
this.startedAt = 0;
this.stopReason = null;
this.stopPromise = null;
this.resolveStop = null;
this.rejectStop = null;
this.result = null;
}
updateSnapshot(patch) {
this.snapshot = {
...this.snapshot,
...patch
};
for (const listener of this.listeners) {
listener(this.snapshot);
}
}
fail(message) {
this.stopTicker();
this.cleanupRecorderPipeline();
this.updateSnapshot({
phase: "error",
errorMessage: message
});
this.rejectStop?.(new Error(message));
this.stopPromise = null;
this.resolveStop = null;
this.rejectStop = null;
}
toFriendlyError(error) {
if (error instanceof DOMException) {
if (error.name === "NotAllowedError" || error.name === "SecurityError") {
return "需要麦克风权限才能录制语音消息。";
}
if (error.name === "NotFoundError") {
return "没有检测到可用的麦克风设备。";
}
}
return error instanceof Error ? error.message : "录音初始化失败,请稍后重试。";
}
}
var root_1$1 = from_html(`<div class="ldv-recorder-placeholder svelte-1vayy8g" aria-live="polite"><div class="ldv-recorder-wave-slot is-placeholder svelte-1vayy8g"><!></div> <span class="ldv-placeholder-text svelte-1vayy8g">正在连接麦克风</span> <span class="ldv-placeholder-icon svelte-1vayy8g" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" class="svelte-1vayy8g"><path d="M12 15.8a3.8 3.8 0 0 0 3.8-3.8V7.8a3.8 3.8 0 1 0-7.6 0V12a3.8 3.8 0 0 0 3.8 3.8Z"></path><path d="M5.8 11.6a6.2 6.2 0 0 0 12.4 0"></path><path d="M12 17.8v3.2"></path><path d="M9 21h6"></path></svg></span></div>`);
var root_3$1 = from_svg(`<svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true" class="svelte-1vayy8g"><rect x="7" y="5.5" width="3.2" height="13" rx="1"></rect><rect x="13.8" y="5.5" width="3.2" height="13" rx="1"></rect></svg>`);
var root_4$1 = from_svg(`<svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true" class="svelte-1vayy8g"><path d="M8 6.2v11.6a.8.8 0 0 0 1.22.68l8.5-5.8a.8.8 0 0 0 0-1.32l-8.5-5.8A.8.8 0 0 0 8 6.2Z"></path></svg>`);
var root_5$1 = from_svg(`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" aria-hidden="true" class="ldv-send-spinner-svg svelte-1vayy8g"><circle cx="12" cy="12" r="8.4" opacity="0.25"></circle><path d="M20.4 12a8.4 8.4 0 0 0-8.4-8.4"></path></svg>`);
var root_6$1 = from_html(`<img alt="" aria-hidden="true" class="ldv-recorder-icon-image ldv-recorder-send-image svelte-1vayy8g"/>`);
var root_2$1 = from_html(`<div><button type="button" class="ldv-recorder-primary svelte-1vayy8g"><!></button> <div class="ldv-recorder-wave-slot svelte-1vayy8g"><!></div> <span> </span> <button type="button" class="ldv-recorder-icon-button ldv-recorder-delete svelte-1vayy8g" aria-label="删除录音" title="删除录音"><img alt="" aria-hidden="true" class="ldv-recorder-icon-image ldv-recorder-delete-image svelte-1vayy8g"/></button> <span class="ldv-recorder-divider svelte-1vayy8g" aria-hidden="true"></span> <button type="button" class="ldv-recorder-send svelte-1vayy8g"><!></button></div>`);
var root_7$1 = from_html(`<p class="ldv-recorder-feedback svelte-1vayy8g"> </p>`);
var root$2 = from_html(`<div class="ldv-composer-recorder-shell svelte-1vayy8g"><!> <!></div>`);
function ComposerRecorder($$anchor, $$props) {
push($$props, false);
const isPlaceholder = mutable_source();
const isReady = mutable_source();
const formattedDuration = mutable_source();
const nearLimit = mutable_source();
const canToggleRecording = mutable_source();
const canSend = mutable_source();
const primaryButtonTitle = mutable_source();
const durationLabel = mutable_source();
let textarea = prop($$props, "textarea", 8, null);
let richEditor = prop($$props, "richEditor", 8, null);
let onClose = prop($$props, "onClose", 8, () => {
});
let onStateChange = prop($$props, "onStateChange", 8, () => {
});
const initialSnapshot = {
phase: "idle",
durationMs: 0,
maxDurationMs: MAX_RECORDING_MS,
format: null,
errorMessage: null,
maxDurationReached: false
};
let recorder = mutable_source(null);
let snapshot = mutable_source(initialSnapshot);
let finalResult = mutable_source(null);
let unsubscribe = () => {
};
let mounted = false;
let destroyHandled = false;
let uploadProgress = mutable_source(0);
let uploading = mutable_source(false);
let feedbackMessage = mutable_source("");
function applyToolbarState(state2) {
onStateChange()(state2);
}
function closeInlineRecorder2() {
destroyHandled = true;
applyToolbarState("idle");
onClose()();
}
function handleRecorderError(message) {
if (!mounted) {
return;
}
window.alert(message);
closeInlineRecorder2();
}
async function initializeRecorder() {
set(recorder, new VoiceRecorder());
unsubscribe = get$1(recorder).subscribe((nextSnapshot) => {
set(snapshot, nextSnapshot);
if (!get$1(uploading)) {
applyToolbarState("recording");
}
if (nextSnapshot.phase === "ready" && !get$1(finalResult)) {
set(finalResult, get$1(recorder)?.getResult() ?? null);
set(feedbackMessage, get$1(finalResult)?.stoppedByLimit ? "已达到 5 分钟上限,请发送或删除。" : "");
}
if (nextSnapshot.phase === "error") {
handleRecorderError(nextSnapshot.errorMessage || "录音失败,请稍后重试。");
}
});
await get$1(recorder).start();
}
async function ensureResult(reason = "send") {
if (get$1(finalResult)) {
return get$1(finalResult);
}
if (!get$1(recorder)) {
throw new Error("录音器未初始化。");
}
set(finalResult, await get$1(recorder).finalize(reason));
return get$1(finalResult);
}
function handlePrimaryAction() {
void toggleRecording();
}
function hasConnectedComposerTarget() {
return Boolean(textarea()?.isConnected || richEditor()?.isConnected);
}
async function toggleRecording() {
if (!get$1(recorder) || !get$1(canToggleRecording)) {
return;
}
if (get$1(snapshot).phase === "recording") {
try {
await get$1(recorder).pause();
set(feedbackMessage, "已暂停,麦克风已释放,可继续录音或直接发送。");
} catch (error) {
set(feedbackMessage, error instanceof Error ? error.message : "暂停录音失败,请稍后重试。");
}
return;
}
try {
await get$1(recorder).resume();
set(feedbackMessage, "");
} catch (error) {
set(feedbackMessage, error instanceof Error ? error.message : "继续录音失败,请稍后重试。");
}
}
async function handleDelete() {
if (get$1(uploading)) {
return;
}
if (get$1(recorder)) {
await get$1(recorder).cancel();
}
closeInlineRecorder2();
}
async function handleSend() {
if (!get$1(canSend) || get$1(uploading)) {
return;
}
try {
set(feedbackMessage, "");
const result = await ensureResult("send");
if (result.fileSize > MAX_FILE_SIZE_BYTES) {
set(feedbackMessage, `录音文件过大(${formatBytes(result.fileSize)}),请缩短录音时间后重试。`);
return;
}
if (!hasConnectedComposerTarget()) {
throw new Error("编辑器已关闭,无法插入语音消息。");
}
set(uploading, true);
set(uploadProgress, 0);
applyToolbarState("uploading");
const upload = await uploadVoiceFile(result.blob, result.fileName, (progress) => {
set(uploadProgress, progress.percent);
});
if (!mounted) {
return;
}
if (!hasConnectedComposerTarget()) {
throw new Error("编辑器已关闭,无法插入语音消息。");
}
const markdown = buildVoiceMessageMarkdown(upload.short_url);
insertVoiceMessageIntoComposer(markdown, { textarea: textarea(), richEditor: richEditor() });
closeInlineRecorder2();
} catch (error) {
if (!mounted) {
return;
}
set(uploading, false);
applyToolbarState("recording");
set(feedbackMessage, error instanceof Error ? error.message : "上传失败,请稍后重试。");
}
}
onMount(() => {
mounted = true;
set(snapshot, { ...initialSnapshot, phase: "starting" });
applyToolbarState("recording");
void initializeRecorder().catch((error) => {
handleRecorderError(error instanceof Error ? error.message : "录音初始化失败。");
});
});
onDestroy(() => {
mounted = false;
unsubscribe();
if (!destroyHandled && get$1(recorder) && !get$1(uploading)) {
void get$1(recorder).cancel();
}
});
legacy_pre_effect(() => get$1(snapshot), () => {
set(isPlaceholder, get$1(snapshot).phase === "starting");
});
legacy_pre_effect(() => (get$1(snapshot), get$1(finalResult)), () => {
set(isReady, get$1(snapshot).phase === "ready" || get$1(finalResult) !== null);
});
legacy_pre_effect(() => get$1(snapshot), () => {
set(formattedDuration, formatRecordingDuration(get$1(snapshot).durationMs));
});
legacy_pre_effect(() => (get$1(snapshot), MAX_RECORDING_MS), () => {
set(nearLimit, get$1(snapshot).durationMs >= MAX_RECORDING_MS - 15e3);
});
legacy_pre_effect(() => (get$1(uploading), get$1(snapshot), get$1(finalResult)), () => {
set(canToggleRecording, !get$1(uploading) && (get$1(snapshot).phase === "recording" || get$1(snapshot).phase === "paused" && get$1(finalResult) === null));
});
legacy_pre_effect(() => (get$1(uploading), get$1(snapshot), get$1(isReady)), () => {
set(canSend, !get$1(uploading) && (get$1(snapshot).phase === "recording" || get$1(snapshot).phase === "paused" || get$1(isReady)));
});
legacy_pre_effect(() => (get$1(snapshot), get$1(finalResult)), () => {
set(primaryButtonTitle, get$1(snapshot).phase === "recording" ? "暂停录音" : get$1(finalResult) ? "录音已完成" : "继续录音");
});
legacy_pre_effect(
() => (get$1(uploading), get$1(uploadProgress), get$1(formattedDuration)),
() => {
set(durationLabel, get$1(uploading) ? `上传 ${get$1(uploadProgress)}%` : get$1(formattedDuration));
}
);
legacy_pre_effect_reset();
init();
var div = root$2();
var node = child(div);
{
var consequent = ($$anchor2) => {
var div_1 = root_1$1();
var div_2 = child(div_1);
var node_1 = child(div_2);
WaveVisualizer(node_1, { active: false, paused: false, displayHeight: 46 });
append($$anchor2, div_1);
};
var alternate_2 = ($$anchor2) => {
var div_3 = root_2$1();
let classes;
var button = child(div_3);
var node_2 = child(button);
{
var consequent_1 = ($$anchor3) => {
var svg = root_3$1();
append($$anchor3, svg);
};
var alternate = ($$anchor3) => {
var svg_1 = root_4$1();
append($$anchor3, svg_1);
};
if_block(node_2, ($$render) => {
if (get$1(snapshot), untrack(() => get$1(snapshot).phase === "recording")) $$render(consequent_1);
else $$render(alternate, false);
});
}
var div_4 = sibling(button, 2);
var node_3 = child(div_4);
{
let $0 = derived_safe_equal(() => (get$1(recorder), untrack(() => get$1(recorder) ? get$1(recorder).readWaveformFrame.bind(get$1(recorder)) : null)));
let $1 = derived_safe_equal(() => (get$1(snapshot), untrack(() => get$1(snapshot).phase === "recording")));
let $2 = derived_safe_equal(() => (get$1(snapshot), untrack(() => get$1(snapshot).phase !== "recording")));
WaveVisualizer(node_3, {
get readFrame() {
return get$1($0);
},
get active() {
return get$1($1);
},
get paused() {
return get$1($2);
},
displayHeight: 52
});
}
var span = sibling(div_4, 2);
let classes_1;
var text = child(span);
var button_1 = sibling(span, 2);
var img = child(button_1);
var button_2 = sibling(button_1, 4);
var node_4 = child(button_2);
{
var consequent_2 = ($$anchor3) => {
var svg_2 = root_5$1();
append($$anchor3, svg_2);
};
var alternate_1 = ($$anchor3) => {
var img_1 = root_6$1();
template_effect(() => set_attribute(img_1, "src", sendIcon));
append($$anchor3, img_1);
};
if_block(node_4, ($$render) => {
if (get$1(uploading)) $$render(consequent_2);
else $$render(alternate_1, false);
});
}
template_effect(() => {
classes = set_class(div_3, 1, "ldv-composer-recorder svelte-1vayy8g", null, classes, {
"is-paused": get$1(snapshot).phase === "paused" || get$1(isReady),
"is-uploading": get$1(uploading)
});
set_attribute(button, "aria-label", get$1(primaryButtonTitle));
set_attribute(button, "title", get$1(primaryButtonTitle));
button.disabled = !get$1(canToggleRecording);
classes_1 = set_class(span, 1, "ldv-recorder-duration svelte-1vayy8g", null, classes_1, { "ldv-near-limit": get$1(nearLimit) && !get$1(uploading) });
set_text(text, get$1(durationLabel));
button_1.disabled = get$1(uploading);
set_attribute(img, "src", deleteIcon);
set_attribute(button_2, "aria-label", get$1(uploading) ? "正在上传语音消息" : "发送语音消息");
set_attribute(button_2, "title", get$1(uploading) ? "正在上传语音消息" : "发送语音消息");
button_2.disabled = !get$1(canSend);
});
event("click", button, handlePrimaryAction);
event("click", button_1, handleDelete);
event("click", button_2, handleSend);
append($$anchor2, div_3);
};
if_block(node, ($$render) => {
if (get$1(isPlaceholder)) $$render(consequent);
else $$render(alternate_2, false);
});
}
var node_5 = sibling(node, 2);
{
var consequent_3 = ($$anchor2) => {
var p = root_7$1();
var text_1 = child(p);
template_effect(() => set_text(text_1, get$1(feedbackMessage)));
append($$anchor2, p);
};
if_block(node_5, ($$render) => {
if (get$1(feedbackMessage)) $$render(consequent_3);
});
}
append($$anchor, div);
pop();
}
const microIcon = "data:image/svg+xml,%3c?xml%20version='1.0'%20standalone='no'?%3e%3c!DOCTYPE%20svg%20PUBLIC%20'-//W3C//DTD%20SVG%201.1//EN'%20'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'%3e%3csvg%20t='1772785999709'%20class='icon'%20viewBox='0%200%201024%201024'%20version='1.1'%20xmlns='http://www.w3.org/2000/svg'%20p-id='4395'%20xmlns:xlink='http://www.w3.org/1999/xlink'%20width='200'%20height='200'%3e%3cpath%20d='M512%2010.24c-124.416%200-225.28%20100.864-225.28%20225.28v256c0%20110.42816%2079.4624%20202.30144%20184.32%20221.56288v67.1232C344.54528%20760.66816%20240.64%20652.61568%20240.64%20522.24v-71.68a46.08%2046.08%200%201%200-92.16%200v71.68c0%20181.30944%20145.41824%20330.71104%20322.56%20350.94528V942.08H348.16a40.96%2040.96%200%200%200%200%2081.92h327.68a40.96%2040.96%200%200%200%200-81.92H552.96v-68.89472C730.10176%20852.95104%20875.52%20703.54944%20875.52%20522.24v-71.68a46.08%2046.08%200%201%200-92.16%200v71.68c0%20130.36544-103.90528%20238.42816-230.4%20257.96608v-67.1232C657.8176%20693.83168%20737.28%20601.94816%20737.28%20491.52V235.52c0-124.416-100.864-225.28-225.28-225.28z'%20fill='%23FF7744'%20p-id='4396'%3e%3c/path%3e%3cpath%20d='M737.28%20368.64H286.72V235.52c0-124.416%20100.864-225.28%20225.28-225.28s225.28%20100.864%20225.28%20225.28v133.12z'%20fill='%23E36130'%20p-id='4397'%3e%3c/path%3e%3cpath%20d='M517.12%20102.4a30.72%2030.72%200%200%201%2030.72%2030.72v143.36a30.72%2030.72%200%201%201-61.44%200V133.12a30.72%2030.72%200%200%201%2030.72-30.72zM409.6%20143.36a30.72%2030.72%200%200%201%2030.72%2030.72v81.92a30.72%2030.72%200%201%201-61.44%200v-81.92a30.72%2030.72%200%200%201%2030.72-30.72z%20m245.76%2030.72a30.72%2030.72%200%201%200-61.44%200v81.92a30.72%2030.72%200%201%200%2061.44%200v-81.92z'%20fill='%23FFA17E'%20p-id='4398'%3e%3c/path%3e%3c/svg%3e";
var root$1 = from_html(`<button type="button"><span class="ldv-toolbar-icon svelte-7pay83" aria-hidden="true"><img alt="" class="ldv-toolbar-image svelte-7pay83"/></span></button>`);
function RecordButton($$anchor, $$props) {
push($$props, false);
const $stateStore = () => store_get(stateStore(), "$stateStore", $$stores);
const [$$stores, $$cleanup] = setup_stores();
const state2 = mutable_source();
const isBusy = mutable_source();
const title = mutable_source();
let stateStore = prop($$props, "stateStore", 8);
let onPress = prop($$props, "onPress", 8, () => {
});
function handleClick() {
if (!get$1(isBusy)) {
onPress()();
}
}
legacy_pre_effect(() => $stateStore(), () => {
set(state2, $stateStore());
});
legacy_pre_effect(() => get$1(state2), () => {
set(isBusy, get$1(state2) !== "idle");
});
legacy_pre_effect(() => get$1(state2), () => {
set(title, get$1(state2) === "uploading" ? "语音上传中" : "录制语音消息");
});
legacy_pre_effect_reset();
init();
var button = root$1();
let classes;
var span = child(button);
var img = child(span);
template_effect(() => {
classes = set_class(button, 1, "ldv-toolbar-button toolbar__button svelte-7pay83", null, classes, {
"is-recording": get$1(state2) === "recording",
"is-uploading": get$1(state2) === "uploading"
});
set_attribute(button, "aria-label", get$1(title));
set_attribute(button, "aria-busy", get$1(state2) === "uploading");
set_attribute(button, "title", get$1(title));
button.disabled = get$1(isBusy);
set_attribute(img, "src", microIcon);
});
event("click", button, handleClick);
append($$anchor, button);
pop();
$$cleanup();
}
function debounce(callback, waitMs) {
let timerId;
const debounced = ((...args) => {
if (timerId !== void 0) {
window.clearTimeout(timerId);
}
timerId = window.setTimeout(() => {
timerId = void 0;
callback(...args);
}, waitMs);
});
debounced.cancel = () => {
if (timerId !== void 0) {
window.clearTimeout(timerId);
timerId = void 0;
}
};
return debounced;
}
function toAbsoluteUrl(url) {
return new URL(url, window.location.origin).href;
}
function isInstallGuideLink(anchor) {
return toAbsoluteUrl(anchor.href) === INSTALL_GUIDE_URL;
}
function resolveComposerRoot(toolbar) {
return toolbar.closest(EDITOR_ROOT_SELECTOR) ?? document;
}
function resolveComposerContext(toolbar) {
const root2 = resolveComposerRoot(toolbar);
const wrapper = root2.querySelector(EDITOR_TEXTAREA_WRAPPER_SELECTOR);
const textarea = root2.querySelector(EDITOR_TEXTAREA_SELECTOR);
const richEditor = root2.querySelector(EDITOR_RICH_TEXT_SELECTOR);
const richEditorContainer = root2.querySelector(EDITOR_RICH_TEXT_CONTAINER_SELECTOR);
const mountAnchor = richEditorContainer ?? textarea ?? richEditor;
if (!wrapper || !mountAnchor) {
return null;
}
return {
wrapper,
mountAnchor,
textarea,
richEditor
};
}
const toolbarState = writable("idle");
const mountedToolbars = new Map();
let observer$1 = null;
let activeRecorder = null;
async function closeInlineRecorder() {
if (!activeRecorder) {
toolbarState.set("idle");
return;
}
const mounted = activeRecorder.component;
const host = activeRecorder.host;
const wrapper = activeRecorder.wrapper;
activeRecorder = null;
wrapper.removeAttribute(INLINE_RECORDER_ATTR);
toolbarState.set("idle");
await unmount(mounted);
host.remove();
}
function cleanupDetachedRecorder() {
if (!activeRecorder) {
return;
}
if (activeRecorder.host.isConnected && activeRecorder.wrapper.isConnected) {
return;
}
const mounted = activeRecorder.component;
const wrapper = activeRecorder.wrapper;
activeRecorder = null;
wrapper.removeAttribute(INLINE_RECORDER_ATTR);
toolbarState.set("idle");
void unmount(mounted);
}
function resolveInlineRecorderAnchor(wrapper, mountAnchor) {
let anchor = mountAnchor;
while (anchor && anchor.parentElement !== wrapper) {
anchor = anchor.parentElement;
}
return anchor ?? wrapper.firstElementChild;
}
function openInlineRecorder(toolbar) {
if (activeRecorder) {
if (!activeRecorder.host.isConnected) {
cleanupDetachedRecorder();
}
return;
}
const composerContext = resolveComposerContext(toolbar);
if (!composerContext) {
window.alert("没有找到当前编辑器,无法插入语音消息。");
return;
}
const { mountAnchor, richEditor, textarea, wrapper } = composerContext;
const host = document.createElement("div");
host.className = INLINE_RECORDER_HOST_CLASS;
wrapper.insertBefore(host, resolveInlineRecorderAnchor(wrapper, mountAnchor));
wrapper.setAttribute(INLINE_RECORDER_ATTR, "true");
toolbarState.set("recording");
const component = mount(ComposerRecorder, {
target: host,
props: {
richEditor,
textarea,
onClose: () => {
void closeInlineRecorder();
},
onStateChange: (state2) => {
toolbarState.set(state2);
}
}
});
activeRecorder = {
host,
wrapper,
component
};
}
function injectToolbar(toolbar) {
if (toolbar.getAttribute(EDITOR_INJECTED_ATTR) === "true") {
return;
}
const host = document.createElement("div");
host.className = "ldv-toolbar-button-slot";
const firstToolbarItem = toolbar.firstElementChild;
if (firstToolbarItem) {
toolbar.insertBefore(host, firstToolbarItem.nextSibling);
} else {
toolbar.appendChild(host);
}
const component = mount(RecordButton, {
target: host,
props: {
stateStore: toolbarState,
onPress: () => openInlineRecorder(toolbar)
}
});
toolbar.setAttribute(EDITOR_INJECTED_ATTR, "true");
mountedToolbars.set(toolbar, { host, component });
}
function cleanupDetachedToolbars() {
for (const [toolbar, entry] of mountedToolbars) {
if (toolbar.isConnected) {
continue;
}
void unmount(entry.component);
entry.host.remove();
mountedToolbars.delete(toolbar);
}
}
function scanToolbars() {
cleanupDetachedRecorder();
document.querySelectorAll(EDITOR_TOOLBAR_SELECTOR).forEach((toolbar) => {
injectToolbar(toolbar);
});
cleanupDetachedToolbars();
}
function initEditorInjection() {
if (observer$1) {
return;
}
scanToolbars();
observer$1 = new MutationObserver(() => {
scanToolbars();
});
observer$1.observe(document.body, {
childList: true,
subtree: true
});
}
const contractIcon = "data:image/svg+xml,%3c?xml%20version='1.0'%20standalone='no'?%3e%3c!DOCTYPE%20svg%20PUBLIC%20'-//W3C//DTD%20SVG%201.1//EN'%20'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'%3e%3csvg%20t='1772820604207'%20class='icon'%20viewBox='0%200%201024%201024'%20version='1.1'%20xmlns='http://www.w3.org/2000/svg'%20p-id='20917'%20xmlns:xlink='http://www.w3.org/1999/xlink'%20width='200'%20height='200'%3e%3cpath%20d='M247.168%20222.165333L512%20486.997333l264.832-264.832-60.330667-60.330666L512%20366.336%20307.498667%20161.834667%20247.168%20222.165333z%20m529.664%20579.669334L512%20537.002667l-264.832%20264.832%2060.330667%2060.330666L512%20657.664l204.501333%20204.501333%2060.330667-60.330666z'%20fill='%230088cc'%20p-id='20918'%3e%3c/path%3e%3c/svg%3e";
const expandIcon = "data:image/svg+xml,%3c?xml%20version='1.0'%20standalone='no'?%3e%3c!DOCTYPE%20svg%20PUBLIC%20'-//W3C//DTD%20SVG%201.1//EN'%20'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'%3e%3csvg%20t='1772820426172'%20class='icon'%20viewBox='0%200%201024%201024'%20version='1.1'%20xmlns='http://www.w3.org/2000/svg'%20p-id='20661'%20xmlns:xlink='http://www.w3.org/1999/xlink'%20width='200'%20height='200'%3e%3cpath%20d='M776.832%20385.834667L512%20121.002667%20247.168%20385.834667l60.330667%2060.330666L512%20241.664l204.501333%20204.501333%2060.330667-60.330666zM247.168%20638.165333L512%20902.997333l264.832-264.832-60.330667-60.330666L512%20782.336l-204.501333-204.501333-60.330667%2060.330666z'%20fill='%230088cc'%20p-id='20662'%3e%3c/path%3e%3c/svg%3e";
const replayIcon = "data:image/svg+xml,%3c?xml%20version='1.0'%20standalone='no'?%3e%3c!DOCTYPE%20svg%20PUBLIC%20'-//W3C//DTD%20SVG%201.1//EN'%20'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'%3e%3csvg%20t='1772784631390'%20class='icon'%20viewBox='0%200%201024%201024'%20version='1.1'%20xmlns='http://www.w3.org/2000/svg'%20p-id='6344'%20xmlns:xlink='http://www.w3.org/1999/xlink'%20width='200'%20height='200'%3e%3cpath%20d='M522.24%20168.96V66.56L245.76%20225.28%20522.24%20384V271.36c158.72%205.12%20281.6%20133.12%20281.6%20291.84%200%20163.84-133.12%20291.84-291.84%20291.84-163.84%200-291.84-133.12-291.84-291.84h-102.4c0%20220.16%20179.2%20394.24%20394.24%20394.24s394.24-179.2%20394.24-394.24-168.96-389.12-384-394.24z'%20p-id='6345'%20fill='%2300aeff'%3e%3c/path%3e%3c/svg%3e";
const TRANSCRIPT_CACHE_LIMIT = 200;
const transcriptMemoryCache = new Map();
function readCachedTranscript(url) {
const cachedTranscript = transcriptMemoryCache.get(url);
if (!cachedTranscript) {
return null;
}
transcriptMemoryCache.delete(url);
transcriptMemoryCache.set(url, cachedTranscript);
return cachedTranscript;
}
function writeCachedTranscript(url, text) {
if (!url || !text) {
return;
}
if (transcriptMemoryCache.has(url)) {
transcriptMemoryCache.delete(url);
}
transcriptMemoryCache.set(url, text);
if (transcriptMemoryCache.size > TRANSCRIPT_CACHE_LIMIT) {
const oldestCacheKey = transcriptMemoryCache.keys().next().value;
if (oldestCacheKey) {
transcriptMemoryCache.delete(oldestCacheKey);
}
}
}
var root_1 = from_svg(`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" aria-hidden="true" class="ldv-player-spinner-svg svelte-19h8psz"><circle cx="12" cy="12" r="8.4" opacity="0.25"></circle><path d="M20.4 12a8.4 8.4 0 0 0-8.4-8.4"></path></svg>`);
var root_2 = from_svg(`<svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true" class="svelte-19h8psz"><rect x="7" y="5.5" width="3.2" height="13" rx="1"></rect><rect x="13.8" y="5.5" width="3.2" height="13" rx="1"></rect></svg>`);
var root_3 = from_svg(`<svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true" class="svelte-19h8psz"><path d="M8 6.2v11.6a.8.8 0 0 0 1.22.68l8.5-5.8a.8.8 0 0 0 0-1.32l-8.5-5.8A.8.8 0 0 0 8 6.2Z"></path></svg>`);
var root_4 = from_html(`<span></span>`);
var root_7 = from_html(`<p class="ldv-player-error svelte-19h8psz"> </p>`);
var root_10 = from_html(`<p class="ldv-player-transcript-content is-pending svelte-19h8psz"> </p>`);
var root_9 = from_html(`<p class="ldv-player-transcript-note svelte-19h8psz">正在转写语音,请稍候...</p> <!>`, 1);
var root_11 = from_html(`<p> </p>`);
var root_12 = from_html(`<p class="ldv-player-transcript-note is-error svelte-19h8psz"> </p>`);
var root_8 = from_html(`<div class="ldv-player-transcript-panel svelte-19h8psz"><!></div>`);
var root_6 = from_html(`<div class="ldv-player-secondary-body svelte-19h8psz" aria-live="polite"><!> <!></div>`);
var root_14 = from_html(`<button type="button" class="ldv-player-transcript-action ldv-player-transcript-toggle svelte-19h8psz"><img alt="" aria-hidden="true" class="ldv-player-transcript-toggle-icon svelte-19h8psz"/></button>`);
var root_13 = from_html(`<div class="ldv-player-transcript-actions svelte-19h8psz"><button type="button" class="ldv-player-transcript-action svelte-19h8psz" title="使用浏览器内建语音识别将这条语音转成文字"> </button> <!></div>`);
var root_5 = from_html(`<div><!> <!></div>`);
var root = from_html(`<div class="ldv-player-wrap svelte-19h8psz"><div><div class="ldv-player-primary svelte-19h8psz"><button type="button" class="ldv-player-main svelte-19h8psz"><!></button> <div class="ldv-player-waveform svelte-19h8psz" aria-hidden="true"></div> <span class="ldv-player-time svelte-19h8psz"> </span> <button type="button" class="ldv-player-replay svelte-19h8psz" aria-label="重播语音消息" title="重播语音消息"><img alt="" aria-hidden="true" class="ldv-player-replay-image svelte-19h8psz"/></button></div> <!></div></div>`);
function VoicePlayer($$anchor, $$props) {
push($$props, false);
const progressRatio = mutable_source();
const playedBars = mutable_source();
const displayedDuration = mutable_source();
const showTranscriptPanel = mutable_source();
const showTranscriptToggle = mutable_source();
const hasSecondaryContent = mutable_source();
const showSecondarySection = mutable_source();
const transcriptActionLabel = mutable_source();
const transcriptToggleLabel = mutable_source();
const transcriptToggleIcon = mutable_source();
let audioUrl = prop($$props, "audioUrl", 8, "");
let fileName = prop($$props, "fileName", 8, "语音消息");
const playerId = createShortUuid();
const transcriptPanelId = `${playerId}-transcript`;
const TRANSCRIPT_UNSUPPORTED_MESSAGE = "当前浏览器暂不支持附件语音转写,请使用最新版桌面版 Chrome 或 Edge。";
let audio = null;
let state2 = mutable_source("idle");
let duration = mutable_source(0);
let currentTime = mutable_source(0);
let errorMessage = mutable_source("");
let sourceReady = false;
let sourceLoading = mutable_source(true);
let mounted = false;
let revokeObjectUrl = () => {
};
let abortController = null;
let activeSourceKind = null;
let preparedSourceUrl = null;
let shouldAutoPlayWhenReady = false;
let transcriptState = mutable_source("idle");
let transcriptText = mutable_source("");
let transcriptInterimText = mutable_source("");
let transcriptError = mutable_source("");
let transcriptSupported = mutable_source(false);
let transcriptSupportMessage = TRANSCRIPT_UNSUPPORTED_MESSAGE;
let transcriptCanToggle = mutable_source(false);
let transcriptCollapsed = mutable_source(false);
let transcriptContentElement = mutable_source(null);
let transcriptRunId = 0;
let cancelTranscriptRun = () => {
};
const waveformBars = createWaveformBars(`${audioUrl()}|${fileName()}`, 34);
function getSpeechRecognitionConstructor() {
const speechWindow = window;
return speechWindow.SpeechRecognition ?? speechWindow.webkitSpeechRecognition ?? null;
}
function isDesktopChromiumBrowser() {
const userAgent = navigator.userAgent;
const isMobile = /Android|iPhone|iPad|iPod|Mobile/i.test(userAgent);
const isChromium = /Chrome|Chromium|Edg|OPR\//.test(userAgent);
const isFirefox = /Firefox\//.test(userAgent);
const isSafari = /Safari\//.test(userAgent) && !isChromium;
return !isMobile && isChromium && !isFirefox && !isSafari;
}
function detectTranscriptSupport() {
if (!getSpeechRecognitionConstructor()) {
return { supported: false, message: TRANSCRIPT_UNSUPPORTED_MESSAGE };
}
if (typeof AudioContext === "undefined") {
return { supported: false, message: "当前浏览器缺少音频处理能力,无法转写这条语音。" };
}
if (!isDesktopChromiumBrowser()) {
return { supported: false, message: TRANSCRIPT_UNSUPPORTED_MESSAGE };
}
return { supported: true, message: "" };
}
function resolveRecognitionLanguage() {
const siteLanguage = document.documentElement.lang.trim();
if (siteLanguage) {
return siteLanguage;
}
return navigator.language || "zh-CN";
}
function normalizeTranscript(text) {
return text.replace(/\s+/g, " ").trim();
}
function mapRecognitionError(errorCode) {
switch (errorCode) {
case "aborted":
return "语音转写已取消。";
case "audio-capture":
return "浏览器无法捕获这条语音的音轨。";
case "language-not-supported":
return "当前浏览器不支持这条语音的识别语言。";
case "network":
return "浏览器语音识别服务当前不可用,请稍后重试。";
case "no-speech":
return "没有识别到有效语音内容,请重试。";
case "not-allowed":
case "service-not-allowed":
return "浏览器拒绝了语音识别服务,请检查浏览器权限设置。";
default:
return "语音转写失败,请使用最新版桌面版 Chrome 或 Edge 重试。";
}
}
function mapTranscriptFailure(error) {
if (error instanceof DOMException) {
if (error.name === "InvalidStateError" || error.name === "NotSupportedError") {
return "当前浏览器暂不支持直接转写附件语音,请使用最新版桌面版 Chrome 或 Edge。";
}
if (error.name === "NotAllowedError" || error.name === "SecurityError") {
return "浏览器阻止了语音转写,请检查浏览器权限设置。";
}
}
if (error instanceof Error && error.message) {
return error.message;
}
return "语音转写失败,请稍后重试。";
}
function applyTranscriptPreview(finalText, interimText = "") {
set(transcriptText, normalizeTranscript(finalText));
set(transcriptInterimText, normalizeTranscript(interimText));
}
async function updateTranscriptToggleAvailability() {
await tick();
if (!mounted || get$1(transcriptState) !== "ready" || !get$1(transcriptContentElement)) {
set(transcriptCanToggle, false);
set(transcriptCollapsed, false);
return;
}
const computedStyle = window.getComputedStyle(get$1(transcriptContentElement));
const lineHeight = Number.parseFloat(computedStyle.lineHeight);
const contentHeight = get$1(transcriptContentElement).scrollHeight;
const nextCanToggle = Number.isFinite(lineHeight) && lineHeight > 0 ? contentHeight > lineHeight + 1 : get$1(transcriptContentElement).scrollWidth > get$1(transcriptContentElement).clientWidth + 1;
set(transcriptCanToggle, nextCanToggle);
if (!nextCanToggle) {
set(transcriptCollapsed, false);
}
}
function restoreTranscriptFromCache(url) {
const cachedTranscript = readCachedTranscript(url);
if (!cachedTranscript) {
return;
}
set(transcriptState, "ready");
set(transcriptText, cachedTranscript);
set(transcriptInterimText, "");
set(transcriptError, "");
set(transcriptCanToggle, false);
set(transcriptCollapsed, false);
void updateTranscriptToggleAvailability();
}
function stopTranscriptRun() {
transcriptRunId += 1;
cancelTranscriptRun();
cancelTranscriptRun = () => {
};
}
function isTranscriptRunActive(runId) {
return mounted && transcriptRunId === runId;
}
async function startTranscript(sourceUrl) {
const RecognitionConstructor = getSpeechRecognitionConstructor();
if (!RecognitionConstructor) {
set(transcriptState, "error");
set(transcriptError, TRANSCRIPT_UNSUPPORTED_MESSAGE);
return;
}
stopTranscriptRun();
const runId = transcriptRunId;
set(transcriptState, "loading");
set(transcriptCanToggle, false);
set(transcriptCollapsed, false);
set(transcriptText, "");
set(transcriptInterimText, "");
set(transcriptError, "");
const transcriptionAudio = new Audio(sourceUrl);
transcriptionAudio.preload = "auto";
transcriptionAudio.currentTime = 0;
const recognition = new RecognitionConstructor();
recognition.lang = resolveRecognitionLanguage();
recognition.continuous = true;
recognition.interimResults = true;
recognition.maxAlternatives = 1;
let cleanedUp = false;
let audioContext = null;
let sourceNode = null;
let destinationNode = null;
let silentGainNode = null;
let audioTrack = null;
const cleanup = (abortRecognition = true) => {
if (cleanedUp) {
return;
}
cleanedUp = true;
recognition.onresult = null;
recognition.onerror = null;
recognition.onend = null;
transcriptionAudio.removeEventListener("ended", handleAudioEnded);
transcriptionAudio.removeEventListener("error", handleAudioError);
if (abortRecognition) {
try {
recognition.abort();
} catch {
}
}
transcriptionAudio.pause();
transcriptionAudio.removeAttribute("src");
transcriptionAudio.load();
audioTrack?.stop();
sourceNode?.disconnect();
destinationNode?.disconnect();
silentGainNode?.disconnect();
if (audioContext) {
void audioContext.close().catch(() => void 0);
}
if (cancelTranscriptRun === cancelCurrentRun) {
cancelTranscriptRun = () => {
};
}
};
const finalizeError = (message, abortRecognition = true) => {
if (!isTranscriptRunActive(runId)) {
cleanup(abortRecognition);
return;
}
set(transcriptState, "error");
set(transcriptCanToggle, false);
set(transcriptCollapsed, false);
set(transcriptError, message);
set(transcriptInterimText, "");
cleanup(abortRecognition);
};
const finalizeSuccess = () => {
if (!isTranscriptRunActive(runId)) {
cleanup(false);
return;
}
const resolvedTranscript = normalizeTranscript(get$1(transcriptText) || get$1(transcriptInterimText));
if (!resolvedTranscript) {
finalizeError("浏览器未返回识别结果,请稍后重试。", false);
return;
}
set(transcriptState, "ready");
set(transcriptText, resolvedTranscript);
set(transcriptInterimText, "");
set(transcriptError, "");
set(transcriptCollapsed, false);
writeCachedTranscript(audioUrl(), resolvedTranscript);
void updateTranscriptToggleAvailability();
cleanup(false);
};
const handleAudioEnded = () => {
try {
recognition.stop();
} catch {
finalizeSuccess();
}
};
const handleAudioError = () => {
finalizeError("语音文件加载失败,暂时无法转写。");
};
const cancelCurrentRun = () => {
cleanup(true);
};
cancelTranscriptRun = cancelCurrentRun;
transcriptionAudio.addEventListener("ended", handleAudioEnded);
transcriptionAudio.addEventListener("error", handleAudioError);
recognition.onresult = (event2) => {
if (!isTranscriptRunActive(runId)) {
return;
}
const finalSegments = [];
const interimSegments = [];
for (let index2 = 0; index2 < event2.results.length; index2 += 1) {
const result = event2.results[index2];
const candidate = normalizeTranscript(result[0]?.transcript || "");
if (!candidate) {
continue;
}
if (result.isFinal) {
finalSegments.push(candidate);
} else {
interimSegments.push(candidate);
}
}
applyTranscriptPreview(finalSegments.join(" "), interimSegments.join(" "));
};
recognition.onerror = (event2) => {
finalizeError(mapRecognitionError(event2.error), false);
};
recognition.onend = () => {
finalizeSuccess();
};
try {
audioContext = new AudioContext();
sourceNode = audioContext.createMediaElementSource(transcriptionAudio);
destinationNode = audioContext.createMediaStreamDestination();
silentGainNode = audioContext.createGain();
silentGainNode.gain.value = 0;
sourceNode.connect(destinationNode);
sourceNode.connect(silentGainNode);
silentGainNode.connect(audioContext.destination);
audioTrack = destinationNode.stream.getAudioTracks()[0] ?? null;
if (!audioTrack) {
throw new Error("浏览器无法创建可识别的音频轨道。");
}
recognition.start(audioTrack);
const resumePromise = audioContext.state === "suspended" ? audioContext.resume() : Promise.resolve();
await resumePromise;
await transcriptionAudio.play();
} catch (error) {
finalizeError(mapTranscriptFailure(error));
}
}
function detectAudioMimeType(buffer) {
if (buffer.length >= 4 && buffer[0] === 26 && buffer[1] === 69 && buffer[2] === 223 && buffer[3] === 163) {
return "audio/webm;codecs=opus";
}
if (buffer.length >= 4 && buffer[0] === 79 && buffer[1] === 103 && buffer[2] === 103 && buffer[3] === 83) {
return "audio/ogg;codecs=opus";
}
if (buffer.length >= 3 && buffer[0] === 73 && buffer[1] === 68 && buffer[2] === 51) {
return "audio/mpeg";
}
const boundary2 = Math.min(buffer.length - 1, 48);
for (let index2 = 0; index2 < boundary2; index2 += 1) {
if (buffer[index2] === 255 && (buffer[index2 + 1] & 224) === 224) {
return "audio/mpeg";
}
}
return null;
}
function normalizeFetchedAudioMimeType(value) {
if (!value) {
return null;
}
const normalized = value.trim().toLowerCase();
if (!normalized) {
return null;
}
return normalized.startsWith("audio/") || normalized.startsWith("video/") ? value : null;
}
function applyAudioSource(source2) {
if (!audio) {
return;
}
activeSourceKind = source2.kind;
sourceReady = false;
set(sourceLoading, true);
set(errorMessage, "");
set(currentTime, 0);
if (get$1(state2) === "error" || get$1(state2) === "playing" || get$1(state2) === "paused") {
set(state2, "idle");
}
if (!audio.paused) {
audio.pause();
}
audio.preload = source2.preload;
audio.src = source2.url;
audio.load();
}
function loadPreferredAudioSource(resumePlayback = false) {
if (!audio) {
return false;
}
const nextSource = preparedSourceUrl ? { kind: "prepared-blob", url: preparedSourceUrl } : audioUrl() ? { kind: "direct-url", url: audioUrl() } : null;
if (!nextSource) {
return false;
}
shouldAutoPlayWhenReady = shouldAutoPlayWhenReady || resumePlayback;
applyAudioSource({ kind: nextSource.kind, url: nextSource.url, preload: "auto" });
return true;
}
function resolveTranscriptSourceUrl() {
return preparedSourceUrl || audio?.currentSrc || audio?.getAttribute("src") || audioUrl() || null;
}
async function prepareAudioSource(url) {
abortController = new AbortController();
const response = await fetch(url, { credentials: "same-origin", signal: abortController.signal });
if (!response.ok) {
throw new Error("语音文件加载失败。");
}
const buffer = await response.arrayBuffer();
const mimeType = detectAudioMimeType(new Uint8Array(buffer)) || normalizeFetchedAudioMimeType(response.headers.get("content-type")) || "audio/webm;codecs=opus";
const decodedDuration = await decodeAudioDuration(buffer);
const objectUrl = URL.createObjectURL(new Blob([buffer], { type: mimeType }));
revokeObjectUrl = () => {
URL.revokeObjectURL(objectUrl);
revokeObjectUrl = () => {
};
};
return { objectUrl, decodedDuration };
}
function updateDuration() {
const nextDuration = audio?.duration ?? 0;
if (Number.isFinite(nextDuration) && nextDuration > 0) {
set(duration, nextDuration);
}
}
function maybeAutoPlayReadySource() {
if (!shouldAutoPlayWhenReady) {
return;
}
shouldAutoPlayWhenReady = false;
void playFromCurrent();
}
function isPlaybackAtEnd() {
if (!audio) {
return false;
}
const mediaDuration = audio.duration;
return audio.ended || Number.isFinite(mediaDuration) && mediaDuration > 0 && audio.currentTime >= Math.max(0, mediaDuration - 0.05);
}
function rewindPlaybackPositionIfNeeded() {
if (!audio) {
return;
}
if (!isPlaybackAtEnd()) {
return;
}
try {
audio.currentTime = 0;
} catch {
}
set(currentTime, 0);
}
function isBenignPlayInterruption(error) {
if (error instanceof DOMException && error.name === "AbortError") {
return true;
}
if (error instanceof Error) {
return /play\(\) request was interrupted by a call to pause|play\(\) request was interrupted/i.test(error.message);
}
return false;
}
function pausePlayback() {
audio?.pause();
if (get$1(state2) !== "error") {
set(state2, "paused");
}
}
async function playFromCurrent() {
if (!audio) {
return;
}
if (!sourceReady) {
loadPreferredAudioSource(true);
return;
}
if (activeSourceKind === "prepared-blob" && isPlaybackAtEnd() && loadPreferredAudioSource(true)) {
return;
}
rewindPlaybackPositionIfNeeded();
window.dispatchEvent(new CustomEvent(PLAYER_SYNC_EVENT, { detail: { id: playerId } }));
try {
await audio.play();
set(state2, "playing");
set(errorMessage, "");
shouldAutoPlayWhenReady = false;
} catch (error) {
if (isBenignPlayInterruption(error)) {
shouldAutoPlayWhenReady = false;
return;
}
set(state2, "error");
set(errorMessage, error instanceof Error ? error.message : "音频播放失败");
}
}
function handleMainButtonClick() {
if (get$1(sourceLoading)) {
return;
}
if (get$1(state2) === "error" && loadPreferredAudioSource(true)) {
return;
}
if (get$1(state2) === "playing") {
pausePlayback();
return;
}
void playFromCurrent();
}
function handleReplay(event2) {
event2?.stopPropagation();
if (!audio || get$1(sourceLoading)) {
return;
}
if (activeSourceKind === "prepared-blob" && loadPreferredAudioSource(true)) {
return;
}
if (!sourceReady && loadPreferredAudioSource(true)) {
return;
}
try {
audio.currentTime = 0;
} catch {
}
set(currentTime, 0);
set(errorMessage, "");
if (get$1(state2) === "error") {
set(state2, "idle");
}
void playFromCurrent();
}
function handleTranscriptButtonClick() {
if (get$1(sourceLoading) || get$1(transcriptState) === "loading") {
return;
}
if (!get$1(transcriptSupported)) {
set(transcriptState, "error");
set(transcriptCanToggle, false);
set(transcriptCollapsed, false);
set(transcriptError, transcriptSupportMessage);
return;
}
const sourceUrl = resolveTranscriptSourceUrl();
if (!sourceUrl) {
set(transcriptState, "error");
set(transcriptCanToggle, false);
set(transcriptCollapsed, false);
set(transcriptError, "没有找到可转写的语音来源。");
return;
}
void startTranscript(sourceUrl);
}
function handleTranscriptToggleClick() {
if (!get$1(transcriptCanToggle)) {
return;
}
set(transcriptCollapsed, !get$1(transcriptCollapsed));
}
onMount(() => {
mounted = true;
(($$value) => {
set(transcriptSupported, $$value.supported);
transcriptSupportMessage = $$value.message;
})(detectTranscriptSupport());
if (get$1(transcriptSupported)) {
restoreTranscriptFromCache(audioUrl());
}
audio = new Audio();
audio.preload = "none";
const handleLoadedMetadata = () => {
updateDuration();
};
const handleDurationChange = () => {
updateDuration();
};
const handleCanPlay = () => {
sourceReady = true;
set(sourceLoading, false);
updateDuration();
maybeAutoPlayReadySource();
};
const handleTimeUpdate = () => {
set(currentTime, audio?.currentTime || 0);
};
const handlePause = () => {
if (!audio) {
return;
}
if (audio.ended) {
set(state2, "idle");
set(currentTime, 0);
return;
}
if (get$1(state2) !== "error") {
set(state2, "paused");
}
};
const handleEnded = () => {
set(state2, "idle");
set(currentTime, 0);
};
const handleError = () => {
set(state2, "error");
sourceReady = false;
set(sourceLoading, false);
set(errorMessage, "浏览器无法播放这条语音消息。");
};
const handleExternalActivate = (event2) => {
const customEvent = event2;
if (customEvent.detail?.id !== playerId && !audio?.paused) {
pausePlayback();
}
};
audio.addEventListener("loadedmetadata", handleLoadedMetadata);
audio.addEventListener("durationchange", handleDurationChange);
audio.addEventListener("canplay", handleCanPlay);
audio.addEventListener("timeupdate", handleTimeUpdate);
audio.addEventListener("pause", handlePause);
audio.addEventListener("ended", handleEnded);
audio.addEventListener("error", handleError);
window.addEventListener(PLAYER_SYNC_EVENT, handleExternalActivate);
void prepareAudioSource(audioUrl()).then(({ objectUrl, decodedDuration }) => {
if (!mounted || !audio) {
URL.revokeObjectURL(objectUrl);
return;
}
if (decodedDuration && decodedDuration > 0) {
set(duration, decodedDuration);
}
preparedSourceUrl = objectUrl;
activeSourceKind = "prepared-blob";
set(sourceLoading, false);
sourceReady = false;
}).catch(() => {
if (!mounted || !audio) {
return;
}
activeSourceKind = "direct-url";
sourceReady = false;
set(sourceLoading, false);
});
return () => {
stopTranscriptRun();
abortController?.abort();
audio?.pause();
audio?.removeEventListener("loadedmetadata", handleLoadedMetadata);
audio?.removeEventListener("durationchange", handleDurationChange);
audio?.removeEventListener("canplay", handleCanPlay);
audio?.removeEventListener("timeupdate", handleTimeUpdate);
audio?.removeEventListener("pause", handlePause);
audio?.removeEventListener("ended", handleEnded);
audio?.removeEventListener("error", handleError);
window.removeEventListener(PLAYER_SYNC_EVENT, handleExternalActivate);
revokeObjectUrl();
abortController = null;
audio = null;
};
});
onDestroy(() => {
mounted = false;
stopTranscriptRun();
abortController?.abort();
audio?.pause();
revokeObjectUrl();
});
legacy_pre_effect(() => (get$1(duration), get$1(currentTime)), () => {
set(progressRatio, get$1(duration) > 0 ? clamp(get$1(currentTime) / get$1(duration), 0, 1) : 0);
});
legacy_pre_effect(() => get$1(progressRatio), () => {
set(playedBars, Math.round(get$1(progressRatio) * waveformBars.length));
});
legacy_pre_effect(() => (get$1(currentTime), get$1(duration)), () => {
set(displayedDuration, formatPlaybackRange(get$1(currentTime), get$1(duration)));
});
legacy_pre_effect(() => (get$1(transcriptSupported), get$1(transcriptState)), () => {
set(showTranscriptPanel, get$1(transcriptSupported) && get$1(transcriptState) !== "idle");
});
legacy_pre_effect(
() => (get$1(transcriptSupported), get$1(transcriptState), get$1(transcriptCanToggle)),
() => {
set(showTranscriptToggle, get$1(transcriptSupported) && get$1(transcriptState) === "ready" && get$1(transcriptCanToggle));
}
);
legacy_pre_effect(() => (get$1(state2), get$1(showTranscriptPanel)), () => {
set(hasSecondaryContent, get$1(state2) === "error" || get$1(showTranscriptPanel));
});
legacy_pre_effect(() => (get$1(state2), get$1(transcriptSupported)), () => {
set(showSecondarySection, get$1(state2) === "error" || get$1(transcriptSupported));
});
legacy_pre_effect(() => get$1(transcriptState), () => {
set(transcriptActionLabel, get$1(transcriptState) === "loading" ? "转写中..." : get$1(transcriptState) === "idle" ? "转文字" : "重试转文字");
});
legacy_pre_effect(() => get$1(transcriptCollapsed), () => {
set(transcriptToggleLabel, get$1(transcriptCollapsed) ? "展开转写内容" : "折叠转写内容");
});
legacy_pre_effect(() => (get$1(transcriptCollapsed), contractIcon), () => {
set(transcriptToggleIcon, get$1(transcriptCollapsed) ? expandIcon : contractIcon);
});
legacy_pre_effect_reset();
init();
var div = root();
var div_1 = child(div);
let classes;
var div_2 = child(div_1);
var button = child(div_2);
var node = child(button);
{
var consequent = ($$anchor2) => {
var svg = root_1();
append($$anchor2, svg);
};
var consequent_1 = ($$anchor2) => {
var svg_1 = root_2();
append($$anchor2, svg_1);
};
var alternate = ($$anchor2) => {
var svg_2 = root_3();
append($$anchor2, svg_2);
};
if_block(node, ($$render) => {
if (get$1(sourceLoading)) $$render(consequent);
else if (get$1(state2) === "playing") $$render(consequent_1, 1);
else $$render(alternate, false);
});
}
var div_3 = sibling(button, 2);
each(div_3, 5, () => waveformBars, index, ($$anchor2, bar, index2) => {
var span = root_4();
let classes_1;
template_effect(
($0) => {
classes_1 = set_class(span, 1, "ldv-player-bar svelte-19h8psz", null, classes_1, { "is-played": index2 < get$1(playedBars) });
set_style(span, $0);
},
[
() => (get$1(bar), untrack(() => `height: ${Math.round(8 + get$1(bar) * 16)}px`))
]
);
append($$anchor2, span);
});
var span_1 = sibling(div_3, 2);
var text_1 = child(span_1);
var button_1 = sibling(span_1, 2);
var img = child(button_1);
var node_1 = sibling(div_2, 2);
{
var consequent_11 = ($$anchor2) => {
var div_4 = root_5();
let classes_2;
var node_2 = child(div_4);
{
var consequent_8 = ($$anchor3) => {
var div_5 = root_6();
var node_3 = child(div_5);
{
var consequent_2 = ($$anchor4) => {
var p = root_7();
var text_2 = child(p);
template_effect(() => set_text(text_2, get$1(errorMessage)));
append($$anchor4, p);
};
if_block(node_3, ($$render) => {
if (get$1(state2) === "error") $$render(consequent_2);
});
}
var node_4 = sibling(node_3, 2);
{
var consequent_7 = ($$anchor4) => {
var div_6 = root_8();
var node_5 = child(div_6);
{
var consequent_4 = ($$anchor5) => {
var fragment = root_9();
var node_6 = sibling(first_child(fragment), 2);
{
var consequent_3 = ($$anchor6) => {
var p_1 = root_10();
var text_3 = child(p_1);
template_effect(() => set_text(text_3, get$1(transcriptText) || get$1(transcriptInterimText)));
append($$anchor6, p_1);
};
if_block(node_6, ($$render) => {
if (get$1(transcriptText) || get$1(transcriptInterimText)) $$render(consequent_3);
});
}
append($$anchor5, fragment);
};
var consequent_5 = ($$anchor5) => {
var p_2 = root_11();
let classes_3;
var text_4 = child(p_2);
bind_this(p_2, ($$value) => set(transcriptContentElement, $$value), () => get$1(transcriptContentElement));
template_effect(() => {
classes_3 = set_class(p_2, 1, "ldv-player-transcript-content svelte-19h8psz", null, classes_3, {
"is-collapsed": get$1(transcriptCollapsed) && get$1(transcriptCanToggle)
});
set_text(text_4, get$1(transcriptText));
});
append($$anchor5, p_2);
};
var consequent_6 = ($$anchor5) => {
var p_3 = root_12();
var text_5 = child(p_3);
template_effect(() => set_text(text_5, get$1(transcriptError)));
append($$anchor5, p_3);
};
if_block(node_5, ($$render) => {
if (get$1(transcriptState) === "loading") $$render(consequent_4);
else if (get$1(transcriptState) === "ready") $$render(consequent_5, 1);
else if (get$1(transcriptState) === "error") $$render(consequent_6, 2);
});
}
template_effect(() => set_attribute(div_6, "id", transcriptPanelId));
append($$anchor4, div_6);
};
if_block(node_4, ($$render) => {
if (get$1(showTranscriptPanel)) $$render(consequent_7);
});
}
append($$anchor3, div_5);
};
if_block(node_2, ($$render) => {
if (get$1(hasSecondaryContent)) $$render(consequent_8);
});
}
var node_7 = sibling(node_2, 2);
{
var consequent_10 = ($$anchor3) => {
var div_7 = root_13();
var button_2 = child(div_7);
var text_6 = child(button_2);
var node_8 = sibling(button_2, 2);
{
var consequent_9 = ($$anchor4) => {
var button_3 = root_14();
var img_1 = child(button_3);
template_effect(() => {
set_attribute(button_3, "aria-controls", transcriptPanelId);
set_attribute(button_3, "aria-expanded", !get$1(transcriptCollapsed));
set_attribute(button_3, "aria-label", get$1(transcriptToggleLabel));
set_attribute(button_3, "title", get$1(transcriptToggleLabel));
set_attribute(img_1, "src", get$1(transcriptToggleIcon));
});
event("click", button_3, handleTranscriptToggleClick);
append($$anchor4, button_3);
};
if_block(node_8, ($$render) => {
if (get$1(showTranscriptToggle)) $$render(consequent_9);
});
}
template_effect(() => {
button_2.disabled = get$1(sourceLoading) || get$1(transcriptState) === "loading";
set_text(text_6, get$1(transcriptActionLabel));
});
event("click", button_2, handleTranscriptButtonClick);
append($$anchor3, div_7);
};
if_block(node_7, ($$render) => {
if (get$1(transcriptSupported)) $$render(consequent_10);
});
}
template_effect(() => classes_2 = set_class(div_4, 1, "ldv-player-secondary svelte-19h8psz", null, classes_2, { "is-compact": !get$1(hasSecondaryContent) }));
append($$anchor2, div_4);
};
if_block(node_1, ($$render) => {
if (get$1(showSecondarySection)) $$render(consequent_11);
});
}
template_effect(() => {
set_attribute(div, "data-file-name", fileName());
classes = set_class(div_1, 1, "ldv-player-card svelte-19h8psz", null, classes, {
"is-playing": get$1(state2) === "playing",
"is-paused": get$1(state2) === "paused"
});
set_attribute(button, "aria-label", get$1(state2) === "playing" ? "暂停语音消息" : "播放语音消息");
set_attribute(button, "title", get$1(state2) === "playing" ? "暂停语音消息" : "播放语音消息");
button.disabled = get$1(sourceLoading);
set_text(text_1, get$1(displayedDuration));
button_1.disabled = get$1(sourceLoading);
set_attribute(img, "src", replayIcon);
});
event("click", button, handleMainButtonClick);
event("click", button_1, handleReplay);
append($$anchor, div);
pop();
}
const mountedPlayers = new Map();
let observer = null;
function cleanupDetachedPlayers() {
for (const [host, component] of mountedPlayers) {
if (host.isConnected) {
continue;
}
void unmount(component);
mountedPlayers.delete(host);
}
}
function findVoiceAttachmentMatches() {
const attachments = Array.from(document.querySelectorAll(ATTACHMENT_SELECTOR));
return attachments.flatMap((attachmentLink) => {
if (attachmentLink.textContent?.trim() !== "语音消息") {
return [];
}
const container = attachmentLink.closest("p, li");
if (!container || attachmentLink.getAttribute(VOICE_PROCESSED_ATTR) === "true") {
return [];
}
const guideLink = Array.from(container.querySelectorAll("a")).find((anchor) => {
if (!isInstallGuideLink(anchor)) {
return false;
}
return Boolean(attachmentLink.compareDocumentPosition(anchor) & Node.DOCUMENT_POSITION_FOLLOWING);
});
if (!guideLink) {
return [];
}
return [
{
attachmentLink,
guideLink,
audioUrl: toAbsoluteUrl(attachmentLink.getAttribute("href") || attachmentLink.href),
fileName: attachmentLink.getAttribute("title") || attachmentLink.getAttribute("data-orig-href") || attachmentLink.getAttribute("href") || "语音消息"
}
];
});
}
function mountPlayer(match) {
match.attachmentLink.setAttribute(VOICE_PROCESSED_ATTR, "true");
match.guideLink.setAttribute(VOICE_PROCESSED_ATTR, "true");
const host = document.createElement("span");
host.className = VOICE_PLAYER_HOST_CLASS;
const range = document.createRange();
range.setStartBefore(match.attachmentLink);
range.setEndAfter(match.guideLink);
range.deleteContents();
range.insertNode(host);
range.detach();
const component = mount(VoicePlayer, {
target: host,
props: {
audioUrl: match.audioUrl,
fileName: match.fileName
}
});
mountedPlayers.set(host, component);
}
function scanVoiceMessages() {
cleanupDetachedPlayers();
for (const match of findVoiceAttachmentMatches()) {
mountPlayer(match);
}
}
function initVoiceDetection() {
if (observer) {
return;
}
const debouncedScan = debounce(scanVoiceMessages, DETECT_SCAN_DEBOUNCE_MS);
scanVoiceMessages();
observer = new MutationObserver(() => {
debouncedScan();
});
observer.observe(document.body, {
childList: true,
subtree: true
});
}
function bootstrap() {
initEditorInjection();
initVoiceDetection();
}
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", bootstrap, { once: true });
} else {
bootstrap();
}
})();