(function () { 'use strict'; // generated during release, do not modify const PUBLIC_VERSION = '5'; if (typeof window !== 'undefined') { // @ts-expect-error ((window.__svelte ??= {}).v ??= new Set()).add(PUBLIC_VERSION); } let legacy_mode_flag = false; let tracing_mode_flag = false; function enable_legacy_mode_flag() { legacy_mode_flag = true; } enable_legacy_mode_flag(); const EACH_ITEM_REACTIVE = 1; const EACH_INDEX_REACTIVE = 1 << 1; const EACH_ITEM_IMMUTABLE = 1 << 4; const TEMPLATE_FRAGMENT = 1; const TEMPLATE_USE_IMPORT_NODE = 1 << 1; const UNINITIALIZED = Symbol(); var DEV = false; // Store the references to globals in case someone tries to monkey patch these, causing the below // to de-opt (this occurs often when using popular extensions). var is_array = Array.isArray; var index_of = Array.prototype.indexOf; var array_from = Array.from; var get_descriptors = Object.getOwnPropertyDescriptors; var get_prototype_of = Object.getPrototypeOf; // Adapted from https://github.com/then/is-promise/blob/master/index.js // Distributed under MIT License https://github.com/then/is-promise/blob/master/LICENSE /** * @template [T=any] * @param {any} value * @returns {value is PromiseLike} */ function is_promise(value) { return typeof value?.then === 'function'; } /** @param {Function} fn */ function run(fn) { return fn(); } /** @param {Array<() => void>} arr */ function run_all(arr) { for (var i = 0; i < arr.length; i++) { arr[i](); } } const DERIVED = 1 << 1; const EFFECT = 1 << 2; const RENDER_EFFECT = 1 << 3; const BLOCK_EFFECT = 1 << 4; const BRANCH_EFFECT = 1 << 5; const ROOT_EFFECT = 1 << 6; const BOUNDARY_EFFECT = 1 << 7; const UNOWNED = 1 << 8; const DISCONNECTED = 1 << 9; const CLEAN = 1 << 10; const DIRTY = 1 << 11; const MAYBE_DIRTY = 1 << 12; const INERT = 1 << 13; const DESTROYED = 1 << 14; const EFFECT_RAN = 1 << 15; /** 'Transparent' effects do not create a transition boundary */ const EFFECT_TRANSPARENT = 1 << 16; const HEAD_EFFECT = 1 << 19; const EFFECT_HAS_DERIVED = 1 << 20; const EFFECT_IS_UPDATING = 1 << 21; const STATE_SYMBOL = Symbol('$state'); /** @import { Equals } from '#client' */ /** @type {Equals} */ function equals(value) { return value === this.v; } /** * @param {unknown} a * @param {unknown} b * @returns {boolean} */ function safe_not_equal(a, b) { return a != a ? b == b : a !== b || (a !== null && typeof a === 'object') || typeof a === 'function'; } /** @type {Equals} */ function safe_equals(value) { return !safe_not_equal(value, this.v); } /* This file is generated by scripts/process-messages/index.js. Do not edit! */ /** * `%rune%` cannot be used inside an effect cleanup function * @param {string} rune * @returns {never} */ function effect_in_teardown(rune) { { throw new Error(`https://svelte.dev/e/effect_in_teardown`); } } /** * Effect cannot be created inside a `$derived` value that was not itself created inside an effect * @returns {never} */ function effect_in_unowned_derived() { { throw new Error(`https://svelte.dev/e/effect_in_unowned_derived`); } } /** * `%rune%` can only be used inside an effect (e.g. during component initialisation) * @param {string} rune * @returns {never} */ function effect_orphan(rune) { { throw new Error(`https://svelte.dev/e/effect_orphan`); } } /** * Maximum update depth exceeded. This can happen when a reactive block or effect repeatedly sets a new value. Svelte limits the number of nested updates to prevent infinite loops * @returns {never} */ function effect_update_depth_exceeded() { { throw new Error(`https://svelte.dev/e/effect_update_depth_exceeded`); } } /** @import { ComponentContext } from '#client' */ /** @type {ComponentContext | null} */ let component_context = null; /** @param {ComponentContext | null} context */ function set_component_context(context) { component_context = context; } /** * @param {Record} props * @param {any} runes * @param {Function} [fn] * @returns {void} */ function push(props, runes = false, fn) { var ctx = (component_context = { p: component_context, c: null, d: false, e: null, m: false, s: props, x: null, l: null }); if (legacy_mode_flag && !runes) { component_context.l = { s: null, u: null, r1: [], r2: source(false) }; } teardown(() => { /** @type {ComponentContext} */ (ctx).d = true; }); } /** * @template {Record} T * @param {T} [component] * @returns {T} */ function pop(component) { const context_stack_item = component_context; if (context_stack_item !== null) { const component_effects = context_stack_item.e; if (component_effects !== null) { var previous_effect = active_effect; var previous_reaction = active_reaction; context_stack_item.e = null; try { for (var i = 0; i < component_effects.length; i++) { var component_effect = component_effects[i]; set_active_effect(component_effect.effect); set_active_reaction(component_effect.reaction); effect(component_effect.fn); } } finally { set_active_effect(previous_effect); set_active_reaction(previous_reaction); } } component_context = context_stack_item.p; context_stack_item.m = true; } // Micro-optimization: Don't set .a above to the empty object // so it can be garbage-collected when the return here is unused return /** @type {T} */ ({}); } /** @returns {boolean} */ function is_runes() { return !legacy_mode_flag || (component_context !== null && component_context.l === null); } /** @import { Derived, Effect } from '#client' */ /** * @template V * @param {() => V} fn * @returns {Derived} */ /*#__NO_SIDE_EFFECTS__*/ function derived(fn) { var flags = DERIVED | DIRTY; var parent_derived = active_reaction !== null && (active_reaction.f & DERIVED) !== 0 ? /** @type {Derived} */ (active_reaction) : null; if (active_effect === null || (parent_derived !== null && (parent_derived.f & UNOWNED) !== 0)) { flags |= UNOWNED; } else { // Since deriveds are evaluated lazily, any effects created inside them are // created too late to ensure that the parent effect is added to the tree active_effect.f |= EFFECT_HAS_DERIVED; } /** @type {Derived} */ const signal = { ctx: component_context, deps: null, effects: null, equals, f: flags, fn, reactions: null, rv: 0, v: /** @type {V} */ (null), wv: 0, parent: parent_derived ?? active_effect }; return signal; } /** * @template V * @param {() => V} fn * @returns {Derived} */ /*#__NO_SIDE_EFFECTS__*/ function derived_safe_equal(fn) { const signal = derived(fn); signal.equals = safe_equals; return signal; } /** * @param {Derived} derived * @returns {void} */ function destroy_derived_effects(derived) { var effects = derived.effects; if (effects !== null) { derived.effects = null; for (var i = 0; i < effects.length; i += 1) { destroy_effect(/** @type {Effect} */ (effects[i])); } } } /** * @param {Derived} derived * @returns {Effect | null} */ function get_derived_parent_effect(derived) { var parent = derived.parent; while (parent !== null) { if ((parent.f & DERIVED) === 0) { return /** @type {Effect} */ (parent); } parent = parent.parent; } return null; } /** * @template T * @param {Derived} derived * @returns {T} */ function execute_derived(derived) { var value; var prev_active_effect = active_effect; set_active_effect(get_derived_parent_effect(derived)); { try { destroy_derived_effects(derived); value = update_reaction(derived); } finally { set_active_effect(prev_active_effect); } } return value; } /** * @param {Derived} derived * @returns {void} */ function update_derived(derived) { var value = execute_derived(derived); if (!derived.equals(value)) { derived.v = value; derived.wv = increment_write_version(); } // don't mark derived clean if we're reading it inside a // cleanup function, or it will cache a stale value if (is_destroying_effect) return; var status = (skip_reaction || (derived.f & UNOWNED) !== 0) && derived.deps !== null ? MAYBE_DIRTY : CLEAN; set_signal_status(derived, status); } /** @import { Derived, Effect, Source, Value } from '#client' */ const old_values = new Map(); /** * @template V * @param {V} v * @param {Error | null} [stack] * @returns {Source} */ // TODO rename this to `state` throughout the codebase function source(v, stack) { /** @type {Value} */ var signal = { f: 0, // TODO ideally we could skip this altogether, but it causes type errors v, reactions: null, equals, rv: 0, wv: 0 }; return signal; } /** * @template V * @param {V} initial_value * @param {boolean} [immutable] * @returns {Source} */ /*#__NO_SIDE_EFFECTS__*/ function mutable_source(initial_value, immutable = false) { const s = source(initial_value); if (!immutable) { s.equals = safe_equals; } // bind the signal to the component context, in case we need to // track updates to trigger beforeUpdate/afterUpdate callbacks if (legacy_mode_flag && component_context !== null && component_context.l !== null) { (component_context.l.s ??= []).push(s); } return s; } /** * @template V * @param {Source} source * @param {V} value * @returns {V} */ function internal_set(source, value) { if (!source.equals(value)) { var old_value = source.v; if (is_destroying_effect) { old_values.set(source, value); } else { old_values.set(source, old_value); } source.v = value; if ((source.f & DERIVED) !== 0) { // if we are assigning to a dirty derived we set it to clean/maybe dirty but we also eagerly execute it to track the dependencies if ((source.f & DIRTY) !== 0) { execute_derived(/** @type {Derived} */ (source)); } set_signal_status(source, (source.f & UNOWNED) === 0 ? CLEAN : MAYBE_DIRTY); } source.wv = increment_write_version(); mark_reactions(source, DIRTY); // It's possible that the current reaction might not have up-to-date dependencies // whilst it's actively running. So in the case of ensuring it registers the reaction // properly for itself, we need to ensure the current effect actually gets // scheduled. i.e: `$effect(() => x++)` 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([source]); } else { untracked_writes.push(source); } } } return value; } /** * @param {Value} signal * @param {number} status should be DIRTY or MAYBE_DIRTY * @returns {void} */ 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 flags = reaction.f; // Skip any effects that are already dirty if ((flags & DIRTY) !== 0) continue; // In legacy mode, skip the current effect to prevent infinite loops if (!runes && reaction === active_effect) continue; set_signal_status(reaction, status); // If the signal a) was previously clean or b) is an unowned derived, then mark it if ((flags & (CLEAN | UNOWNED)) !== 0) { if ((flags & DERIVED) !== 0) { mark_reactions(/** @type {Derived} */ (reaction), MAYBE_DIRTY); } else { schedule_effect(/** @type {Effect} */ (reaction)); } } } } /** @import { TemplateNode } from '#client' */ /** * Use this variable to guard everything related to hydration code so it can be treeshaken out * if the user doesn't use the `hydrate` method and these code paths are therefore not needed. */ let hydrating = false; /** @import { TemplateNode } from '#client' */ /** @type {boolean} */ var is_firefox; /** @type {() => Node | null} */ var first_child_getter; /** @type {() => Node | null} */ var next_sibling_getter; /** * @param {string} value * @returns {Text} */ function create_text(value = '') { return document.createTextNode(value); } /** * @template {Node} N * @param {N} node * @returns {Node | null} */ /*@__NO_SIDE_EFFECTS__*/ function get_first_child(node) { return first_child_getter.call(node); } /** * @template {Node} N * @param {N} node * @returns {Node | null} */ /*@__NO_SIDE_EFFECTS__*/ function get_next_sibling(node) { return next_sibling_getter.call(node); } /** * Don't mark this as side-effect-free, hydration needs to walk all nodes * @template {Node} N * @param {N} node * @param {boolean} is_text * @returns {Node | null} */ function child(node, is_text) { { return get_first_child(node); } } /** * Don't mark this as side-effect-free, hydration needs to walk all nodes * @param {DocumentFragment | TemplateNode[]} fragment * @param {boolean} is_text * @returns {Node | null} */ function first_child(fragment, is_text) { { // when not hydrating, `fragment` is a `DocumentFragment` (the result of calling `open_frag`) var first = /** @type {DocumentFragment} */ (get_first_child(/** @type {Node} */ (fragment))); // TODO prevent user comments with the empty string when preserveComments is true if (first instanceof Comment && first.data === '') return get_next_sibling(first); return first; } } /** * Don't mark this as side-effect-free, hydration needs to walk all nodes * @param {TemplateNode} node * @param {number} count * @param {boolean} is_text * @returns {Node | null} */ function sibling(node, count = 1, is_text = false) { let next_sibling = node; while (count--) { next_sibling = /** @type {TemplateNode} */ (get_next_sibling(next_sibling)); } { return next_sibling; } } /** * @template {Node} N * @param {N} node * @returns {void} */ function clear_text_content(node) { node.textContent = ''; } /** @import { ComponentContext, ComponentContextLegacy, Derived, Effect, TemplateNode, TransitionManager } from '#client' */ /** * @param {'$effect' | '$effect.pre' | '$inspect'} rune */ function validate_effect(rune) { if (active_effect === null && active_reaction === null) { effect_orphan(); } if (active_reaction !== null && (active_reaction.f & UNOWNED) !== 0 && active_effect === null) { effect_in_unowned_derived(); } if (is_destroying_effect) { effect_in_teardown(); } } /** * @param {Effect} effect * @param {Effect} parent_effect */ function push_effect(effect, parent_effect) { var parent_last = parent_effect.last; if (parent_last === null) { parent_effect.last = parent_effect.first = effect; } else { parent_last.next = effect; effect.prev = parent_last; parent_effect.last = effect; } } /** * @param {number} type * @param {null | (() => void | (() => void))} fn * @param {boolean} sync * @param {boolean} push * @returns {Effect} */ function create_effect(type, fn, sync, push = true) { var parent = active_effect; /** @type {Effect} */ var effect = { ctx: component_context, deps: null, nodes_start: null, nodes_end: null, f: type | DIRTY, first: null, fn, last: null, next: null, parent, prev: null, teardown: null, transitions: null, wv: 0 }; if (sync) { try { update_effect(effect); effect.f |= EFFECT_RAN; } catch (e) { destroy_effect(effect); throw e; } } else if (fn !== null) { schedule_effect(effect); } // if an effect has no dependencies, no DOM and no teardown function, // don't bother adding it to the effect tree var inert = sync && effect.deps === null && effect.first === null && effect.nodes_start === null && effect.teardown === null && (effect.f & (EFFECT_HAS_DERIVED | BOUNDARY_EFFECT)) === 0; if (!inert && push) { if (parent !== null) { push_effect(effect, parent); } // if we're in a derived, add the effect there too if (active_reaction !== null && (active_reaction.f & DERIVED) !== 0) { var derived = /** @type {Derived} */ (active_reaction); (derived.effects ??= []).push(effect); } } return effect; } /** * @param {() => void} fn */ function teardown(fn) { const effect = create_effect(RENDER_EFFECT, null, false); set_signal_status(effect, CLEAN); effect.teardown = fn; return effect; } /** * Internal representation of `$effect(...)` * @param {() => void | (() => void)} fn */ function user_effect(fn) { validate_effect(); // Non-nested `$effect(...)` in a component should be deferred // until the component is mounted var defer = active_effect !== null && (active_effect.f & BRANCH_EFFECT) !== 0 && component_context !== null && !component_context.m; if (defer) { var context = /** @type {ComponentContext} */ (component_context); (context.e ??= []).push({ fn, effect: active_effect, reaction: active_reaction }); } else { var signal = effect(fn); return signal; } } /** * Internal representation of `$effect.pre(...)` * @param {() => void | (() => void)} fn * @returns {Effect} */ function user_pre_effect(fn) { validate_effect(); return render_effect(fn); } /** * @param {() => void | (() => void)} fn * @returns {Effect} */ function effect(fn) { return create_effect(EFFECT, fn, false); } /** * @param {() => void | (() => void)} fn * @returns {Effect} */ function render_effect(fn) { return create_effect(RENDER_EFFECT, fn, true); } /** * @param {(...expressions: any) => void | (() => void)} fn * @param {Array<() => any>} thunks * @returns {Effect} */ function template_effect(fn, thunks = [], d = derived) { const deriveds = thunks.map(d); const effect = () => fn(...deriveds.map(get)); return block(effect); } /** * @param {(() => void)} fn * @param {number} flags */ function block(fn, flags = 0) { return create_effect(RENDER_EFFECT | BLOCK_EFFECT | flags, fn, true); } /** * @param {(() => void)} fn * @param {boolean} [push] */ function branch(fn, push = true) { return create_effect(RENDER_EFFECT | BRANCH_EFFECT, fn, true, push); } /** * @param {Effect} effect */ function execute_effect_teardown(effect) { var teardown = effect.teardown; if (teardown !== null) { const previously_destroying_effect = is_destroying_effect; const previous_reaction = active_reaction; set_is_destroying_effect(true); set_active_reaction(null); try { teardown.call(null); } finally { set_is_destroying_effect(previously_destroying_effect); set_active_reaction(previous_reaction); } } } /** * @param {Effect} signal * @param {boolean} remove_dom * @returns {void} */ function destroy_effect_children(signal, remove_dom = false) { var effect = signal.first; signal.first = signal.last = null; while (effect !== null) { var next = effect.next; if ((effect.f & ROOT_EFFECT) !== 0) { // this is now an independent root effect.parent = null; } else { destroy_effect(effect, remove_dom); } effect = next; } } /** * @param {Effect} signal * @returns {void} */ function destroy_block_effect_children(signal) { var effect = signal.first; while (effect !== null) { var next = effect.next; if ((effect.f & BRANCH_EFFECT) === 0) { destroy_effect(effect); } effect = next; } } /** * @param {Effect} effect * @param {boolean} [remove_dom] * @returns {void} */ function destroy_effect(effect, remove_dom = true) { var removed = false; if ((remove_dom || (effect.f & HEAD_EFFECT) !== 0) && effect.nodes_start !== null) { remove_effect_dom(effect.nodes_start, /** @type {TemplateNode} */ (effect.nodes_end)); removed = true; } destroy_effect_children(effect, remove_dom && !removed); remove_reactions(effect, 0); set_signal_status(effect, DESTROYED); var transitions = effect.transitions; if (transitions !== null) { for (const transition of transitions) { transition.stop(); } } execute_effect_teardown(effect); var parent = effect.parent; // If the parent doesn't have any children, then skip this work altogether if (parent !== null && parent.first !== null) { unlink_effect(effect); } // `first` and `child` are nulled out in destroy_effect_children // we don't null out `parent` so that error propagation can work correctly effect.next = effect.prev = effect.teardown = effect.ctx = effect.deps = effect.fn = effect.nodes_start = effect.nodes_end = null; } /** * * @param {TemplateNode | null} node * @param {TemplateNode} end */ function remove_effect_dom(node, end) { while (node !== null) { /** @type {TemplateNode | null} */ var next = node === end ? null : /** @type {TemplateNode} */ (get_next_sibling(node)); node.remove(); node = next; } } /** * Detach an effect from the effect tree, freeing up memory and * reducing the amount of work that happens on subsequent traversals * @param {Effect} effect */ function unlink_effect(effect) { var parent = effect.parent; var prev = effect.prev; var next = effect.next; if (prev !== null) prev.next = next; if (next !== null) next.prev = prev; if (parent !== null) { if (parent.first === effect) parent.first = next; if (parent.last === effect) parent.last = prev; } } /** * When a block effect is removed, we don't immediately destroy it or yank it * out of the DOM, because it might have transitions. Instead, we 'pause' it. * It stays around (in memory, and in the DOM) until outro transitions have * completed, and if the state change is reversed then we _resume_ it. * A paused effect does not update, and the DOM subtree becomes inert. * @param {Effect} effect * @param {() => void} [callback] */ function pause_effect(effect, callback) { /** @type {TransitionManager[]} */ var transitions = []; pause_children(effect, transitions, true); run_out_transitions(transitions, () => { destroy_effect(effect); if (callback) callback(); }); } /** * @param {TransitionManager[]} transitions * @param {() => void} fn */ function run_out_transitions(transitions, fn) { var remaining = transitions.length; if (remaining > 0) { var check = () => --remaining || fn(); for (var transition of transitions) { transition.out(check); } } else { fn(); } } /** * @param {Effect} effect * @param {TransitionManager[]} transitions * @param {boolean} local */ function pause_children(effect, transitions, local) { if ((effect.f & INERT) !== 0) return; effect.f ^= INERT; if (effect.transitions !== null) { for (const transition of effect.transitions) { if (transition.is_global || local) { transitions.push(transition); } } } var child = effect.first; while (child !== null) { var sibling = child.next; var transparent = (child.f & EFFECT_TRANSPARENT) !== 0 || (child.f & BRANCH_EFFECT) !== 0; // TODO we don't need to call pause_children recursively with a linked list in place // it's slightly more involved though as we have to account for `transparent` changing // through the tree. pause_children(child, transitions, transparent ? local : false); child = sibling; } } /** * The opposite of `pause_effect`. We call this if (for example) * `x` becomes falsy then truthy: `{#if x}...{/if}` * @param {Effect} effect */ function resume_effect(effect) { resume_children(effect, true); } /** * @param {Effect} effect * @param {boolean} local */ function resume_children(effect, local) { if ((effect.f & INERT) === 0) return; effect.f ^= INERT; // Ensure the effect is marked as clean again so that any dirty child // effects can schedule themselves for execution if ((effect.f & CLEAN) === 0) { effect.f ^= CLEAN; } // If a dependency of this effect changed while it was paused, // schedule the effect to update if (check_dirtiness(effect)) { set_signal_status(effect, DIRTY); schedule_effect(effect); } var child = effect.first; while (child !== null) { var sibling = child.next; var transparent = (child.f & EFFECT_TRANSPARENT) !== 0 || (child.f & BRANCH_EFFECT) !== 0; // TODO we don't need to call resume_children recursively with a linked list in place // it's slightly more involved though as we have to account for `transparent` changing // through the tree. resume_children(child, transparent ? local : false); child = sibling; } if (effect.transitions !== null) { for (const transition of effect.transitions) { if (transition.is_global || local) { transition.in(); } } } } /** @type {Array<() => void>} */ let micro_tasks = []; /** @type {Array<() => void>} */ let idle_tasks = []; function run_micro_tasks() { var tasks = micro_tasks; micro_tasks = []; run_all(tasks); } function run_idle_tasks() { var tasks = idle_tasks; idle_tasks = []; run_all(tasks); } /** * @param {() => void} fn */ function queue_micro_task(fn) { if (micro_tasks.length === 0) { queueMicrotask(run_micro_tasks); } micro_tasks.push(fn); } /** * Synchronously run any queued tasks. */ function flush_tasks() { if (micro_tasks.length > 0) { run_micro_tasks(); } if (idle_tasks.length > 0) { run_idle_tasks(); } } /** @import { ComponentContext, Derived, Effect, Reaction, Signal, Source, Value } from '#client' */ let is_throwing_error = false; let is_flushing = false; /** @type {Effect | null} */ let last_scheduled_effect = null; let is_updating_effect = false; let is_destroying_effect = false; /** @param {boolean} value */ function set_is_destroying_effect(value) { is_destroying_effect = value; } // Handle effect queues /** @type {Effect[]} */ let queued_root_effects = []; /** @type {Effect[]} Stack of effects, dev only */ let dev_effect_stack = []; // Handle signal reactivity tree dependencies and reactions /** @type {null | Reaction} */ let active_reaction = null; let untracking = false; /** @param {null | Reaction} reaction */ function set_active_reaction(reaction) { active_reaction = reaction; } /** @type {null | Effect} */ let active_effect = null; /** @param {null | Effect} effect */ function set_active_effect(effect) { active_effect = effect; } /** * When sources are created within a reaction, reading and writing * them should not cause a re-run * @type {null | Source[]} */ let reaction_sources = null; /** * The dependencies of the reaction that is currently being executed. In many cases, * the dependencies are unchanged between runs, and so this will be `null` unless * and until a new dependency is accessed — we track this via `skipped_deps` * @type {null | Value[]} */ let new_deps = null; let skipped_deps = 0; /** * Tracks writes that the effect it's executed in doesn't listen to yet, * so that the dependency can be added to the effect later on if it then reads it * @type {null | Source[]} */ let untracked_writes = null; /** @param {null | Source[]} value */ function set_untracked_writes(value) { untracked_writes = value; } /** * @type {number} Used by sources and deriveds for handling updates. * Version starts from 1 so that unowned deriveds differentiate between a created effect and a run one for tracing **/ let write_version = 1; /** @type {number} Used to version each read of a source of derived to avoid duplicating depedencies inside a reaction */ let read_version = 0; // If we are working with a get() chain that has no active container, // to prevent memory leaks, we skip adding the reaction. let skip_reaction = false; function increment_write_version() { return ++write_version; } /** * Determines whether a derived or effect is dirty. * If it is MAYBE_DIRTY, will set the status to CLEAN * @param {Reaction} reaction * @returns {boolean} */ function check_dirtiness(reaction) { var flags = reaction.f; if ((flags & DIRTY) !== 0) { return true; } if ((flags & MAYBE_DIRTY) !== 0) { var dependencies = reaction.deps; var is_unowned = (flags & UNOWNED) !== 0; if (dependencies !== null) { var i; var dependency; var is_disconnected = (flags & DISCONNECTED) !== 0; var is_unowned_connected = is_unowned && active_effect !== null && !skip_reaction; var length = dependencies.length; // If we are working with a disconnected or an unowned signal that is now connected (due to an active effect) // then we need to re-connect the reaction to the dependency if (is_disconnected || is_unowned_connected) { var derived = /** @type {Derived} */ (reaction); var parent = derived.parent; for (i = 0; i < length; i++) { dependency = dependencies[i]; // We always re-add all reactions (even duplicates) if the derived was // previously disconnected, however we don't if it was unowned as we // de-duplicate dependencies in that case if (is_disconnected || !dependency?.reactions?.includes(derived)) { (dependency.reactions ??= []).push(derived); } } if (is_disconnected) { derived.f ^= DISCONNECTED; } // If the unowned derived is now fully connected to the graph again (it's unowned and reconnected, has a parent // and the parent is not unowned), then we can mark it as connected again, removing the need for the unowned // flag if (is_unowned_connected && parent !== null && (parent.f & UNOWNED) === 0) { derived.f ^= UNOWNED; } } for (i = 0; i < length; i++) { dependency = dependencies[i]; if (check_dirtiness(/** @type {Derived} */ (dependency))) { update_derived(/** @type {Derived} */ (dependency)); } if (dependency.wv > reaction.wv) { return true; } } } // Unowned signals should never be marked as clean unless they // are used within an active_effect without skip_reaction if (!is_unowned || (active_effect !== null && !skip_reaction)) { set_signal_status(reaction, CLEAN); } } return false; } /** * @param {unknown} error * @param {Effect} effect */ function propagate_error(error, effect) { /** @type {Effect | null} */ var current = effect; while (current !== null) { if ((current.f & BOUNDARY_EFFECT) !== 0) { try { // @ts-expect-error current.fn(error); return; } catch { // Remove boundary flag from effect current.f ^= BOUNDARY_EFFECT; } } current = current.parent; } is_throwing_error = false; throw error; } /** * @param {Effect} effect */ function should_rethrow_error(effect) { return ( (effect.f & DESTROYED) === 0 && (effect.parent === null || (effect.parent.f & BOUNDARY_EFFECT) === 0) ); } /** * @param {unknown} error * @param {Effect} effect * @param {Effect | null} previous_effect * @param {ComponentContext | null} component_context */ function handle_error(error, effect, previous_effect, component_context) { if (is_throwing_error) { if (previous_effect === null) { is_throwing_error = false; } if (should_rethrow_error(effect)) { throw error; } return; } if (previous_effect !== null) { is_throwing_error = true; } propagate_error(error, effect); if (should_rethrow_error(effect)) { throw error; } } /** * @param {Value} signal * @param {Effect} effect * @param {boolean} [root] */ function schedule_possible_effect_self_invalidation(signal, effect, root = true) { var reactions = signal.reactions; if (reactions === null) return; for (var i = 0; i < reactions.length; i++) { var reaction = reactions[i]; if (reaction_sources?.includes(signal)) continue; if ((reaction.f & DERIVED) !== 0) { schedule_possible_effect_self_invalidation(/** @type {Derived} */ (reaction), effect, false); } else if (effect === reaction) { if (root) { set_signal_status(reaction, DIRTY); } else if ((reaction.f & CLEAN) !== 0) { set_signal_status(reaction, MAYBE_DIRTY); } schedule_effect(/** @type {Effect} */ (reaction)); } } } /** * @template V * @param {Reaction} reaction * @returns {V} */ 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_skip_reaction = skip_reaction; var previous_reaction_sources = reaction_sources; var previous_component_context = component_context; var previous_untracking = untracking; var flags = reaction.f; new_deps = /** @type {null | Value[]} */ (null); skipped_deps = 0; untracked_writes = null; skip_reaction = (flags & UNOWNED) !== 0 && (untracking || !is_updating_effect || active_reaction === null); active_reaction = (flags & (BRANCH_EFFECT | ROOT_EFFECT)) === 0 ? reaction : null; reaction_sources = null; set_component_context(reaction.ctx); untracking = false; read_version++; reaction.f |= EFFECT_IS_UPDATING; try { var result = /** @type {Function} */ (0, reaction.fn)(); var deps = reaction.deps; if (new_deps !== null) { var i; 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 (!skip_reaction) { for (i = skipped_deps; i < deps.length; i++) { (deps[i].reactions ??= []).push(reaction); } } } else if (deps !== null && skipped_deps < deps.length) { remove_reactions(reaction, skipped_deps); deps.length = skipped_deps; } // If we're inside an effect and we have untracked writes, then we need to // ensure that if any of those untracked writes result in re-invalidation // of the current effect, then that happens accordingly if ( is_runes() && untracked_writes !== null && !untracking && deps !== null && (reaction.f & (DERIVED | MAYBE_DIRTY | DIRTY)) === 0 ) { for (i = 0; i < /** @type {Source[]} */ (untracked_writes).length; i++) { schedule_possible_effect_self_invalidation( untracked_writes[i], /** @type {Effect} */ (reaction) ); } } // If we are returning to an previous reaction then // we need to increment the read version to ensure that // any dependencies in this reaction aren't marked with // the same version if (previous_reaction !== null && previous_reaction !== reaction) { read_version++; if (untracked_writes !== null) { if (previous_untracked_writes === null) { previous_untracked_writes = untracked_writes; } else { previous_untracked_writes.push(.../** @type {Source[]} */ (untracked_writes)); } } } return result; } finally { new_deps = previous_deps; skipped_deps = previous_skipped_deps; untracked_writes = previous_untracked_writes; active_reaction = previous_reaction; skip_reaction = previous_skip_reaction; reaction_sources = previous_reaction_sources; set_component_context(previous_component_context); untracking = previous_untracking; reaction.f ^= EFFECT_IS_UPDATING; } } /** * @template V * @param {Reaction} signal * @param {Value} dependency * @returns {void} */ function remove_reaction(signal, dependency) { let reactions = dependency.reactions; if (reactions !== null) { var index = index_of.call(reactions, signal); if (index !== -1) { var new_length = reactions.length - 1; if (new_length === 0) { reactions = dependency.reactions = null; } else { // Swap with last element and then remove. reactions[index] = reactions[new_length]; reactions.pop(); } } } // If the derived has no reactions, then we can disconnect it from the graph, // allowing it to either reconnect in the future, or be GC'd by the VM. if ( reactions === null && (dependency.f & DERIVED) !== 0 && // Destroying a child effect while updating a parent effect can cause a dependency to appear // to be unused, when in fact it is used by the currently-updating parent. Checking `new_deps` // allows us to skip the expensive work of disconnecting and immediately reconnecting it (new_deps === null || !new_deps.includes(dependency)) ) { set_signal_status(dependency, MAYBE_DIRTY); // If we are working with a derived that is owned by an effect, then mark it as being // disconnected. if ((dependency.f & (UNOWNED | DISCONNECTED)) === 0) { dependency.f ^= DISCONNECTED; } // Disconnect any reactions owned by this reaction destroy_derived_effects(/** @type {Derived} **/ (dependency)); remove_reactions(/** @type {Derived} **/ (dependency), 0); } } /** * @param {Reaction} signal * @param {number} start_index * @returns {void} */ 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]); } } /** * @param {Effect} effect * @returns {void} */ function update_effect(effect) { var flags = effect.f; if ((flags & DESTROYED) !== 0) { return; } set_signal_status(effect, CLEAN); var previous_effect = active_effect; var previous_component_context = component_context; var was_updating_effect = is_updating_effect; active_effect = effect; is_updating_effect = true; try { if ((flags & BLOCK_EFFECT) !== 0) { destroy_block_effect_children(effect); } else { destroy_effect_children(effect); } execute_effect_teardown(effect); var teardown = update_reaction(effect); effect.teardown = typeof teardown === 'function' ? teardown : null; effect.wv = write_version; var deps = effect.deps; // In DEV, we need to handle a case where $inspect.trace() might // incorrectly state a source dependency has not changed when it has. // That's beacuse that source was changed by the same effect, causing // the versions to match. We can avoid this by incrementing the version var dep; if (DEV && tracing_mode_flag && (effect.f & DIRTY) !== 0 && deps !== null) ; if (DEV) ; } catch (error) { handle_error(error, effect, previous_effect, previous_component_context || effect.ctx); } finally { is_updating_effect = was_updating_effect; active_effect = previous_effect; } } function infinite_loop_guard() { try { effect_update_depth_exceeded(); } catch (error) { // Try and handle the error so it can be caught at a boundary, that's // if there's an effect available from when it was last scheduled if (last_scheduled_effect !== null) { { handle_error(error, last_scheduled_effect, null); } } else { throw error; } } } function flush_queued_root_effects() { var was_updating_effect = is_updating_effect; try { var flush_count = 0; is_updating_effect = true; while (queued_root_effects.length > 0) { if (flush_count++ > 1000) { infinite_loop_guard(); } var root_effects = queued_root_effects; var length = root_effects.length; queued_root_effects = []; for (var i = 0; i < length; i++) { var collected_effects = process_effects(root_effects[i]); flush_queued_effects(collected_effects); } old_values.clear(); } } finally { is_flushing = false; is_updating_effect = was_updating_effect; last_scheduled_effect = null; } } /** * @param {Array} effects * @returns {void} */ function flush_queued_effects(effects) { var length = effects.length; if (length === 0) return; for (var i = 0; i < length; i++) { var effect = effects[i]; if ((effect.f & (DESTROYED | INERT)) === 0) { try { if (check_dirtiness(effect)) { update_effect(effect); // Effects with no dependencies or teardown do not get added to the effect tree. // Deferred effects (e.g. `$effect(...)`) _are_ added to the tree because we // don't know if we need to keep them until they are executed. Doing the check // here (rather than in `update_effect`) allows us to skip the work for // immediate effects. if (effect.deps === null && effect.first === null && effect.nodes_start === null) { if (effect.teardown === null) { // remove this effect from the graph unlink_effect(effect); } else { // keep the effect in the graph, but free up some memory effect.fn = null; } } } } catch (error) { handle_error(error, effect, null, effect.ctx); } } } } /** * @param {Effect} signal * @returns {void} */ function schedule_effect(signal) { if (!is_flushing) { is_flushing = true; queueMicrotask(flush_queued_root_effects); } var effect = (last_scheduled_effect = signal); while (effect.parent !== null) { effect = effect.parent; var flags = effect.f; if ((flags & (ROOT_EFFECT | BRANCH_EFFECT)) !== 0) { if ((flags & CLEAN) === 0) return; effect.f ^= CLEAN; } } queued_root_effects.push(effect); } /** * * This function both runs render effects and collects user effects in topological order * from the starting effect passed in. Effects will be collected when they match the filtered * bitwise flag passed in only. The collected effects array will be populated with all the user * effects to be flushed. * * @param {Effect} root * @returns {Effect[]} */ function process_effects(root) { /** @type {Effect[]} */ var effects = []; /** @type {Effect | null} */ var effect = root; while (effect !== null) { var flags = effect.f; var is_branch = (flags & (BRANCH_EFFECT | ROOT_EFFECT)) !== 0; var is_skippable_branch = is_branch && (flags & CLEAN) !== 0; if (!is_skippable_branch && (flags & INERT) === 0) { if ((flags & EFFECT) !== 0) { effects.push(effect); } else if (is_branch) { effect.f ^= CLEAN; } else { try { if (check_dirtiness(effect)) { update_effect(effect); } } catch (error) { handle_error(error, effect, null, effect.ctx); } } /** @type {Effect | null} */ var child = effect.first; if (child !== null) { effect = child; continue; } } var parent = effect.parent; effect = effect.next; while (effect === null && parent !== null) { effect = parent.next; parent = parent.parent; } } return effects; } /** * Synchronously flush any pending updates. * Returns void if no callback is provided, otherwise returns the result of calling the callback. * @template [T=void] * @param {(() => T) | undefined} [fn] * @returns {T} */ function flushSync(fn) { var result; while (true) { flush_tasks(); if (queued_root_effects.length === 0) { return /** @type {T} */ (result); } is_flushing = true; flush_queued_root_effects(); } } /** * @template V * @param {Value} signal * @returns {V} */ function get(signal) { var flags = signal.f; var is_derived = (flags & DERIVED) !== 0; // Register the dependency on the current reaction signal. if (active_reaction !== null && !untracking) { if (!reaction_sources?.includes(signal)) { var deps = active_reaction.deps; if (signal.rv < read_version) { signal.rv = read_version; // If the signal is accessing the same dependencies in the same // order as it did last time, increment `skipped_deps` // rather than updating `new_deps`, which creates GC cost if (new_deps === null && deps !== null && deps[skipped_deps] === signal) { skipped_deps++; } else if (new_deps === null) { new_deps = [signal]; } else if (!skip_reaction || !new_deps.includes(signal)) { // Normally we can push duplicated dependencies to `new_deps`, but if we're inside // an unowned derived because skip_reaction is true, then we need to ensure that // we don't have duplicates new_deps.push(signal); } } } } else if ( is_derived && /** @type {Derived} */ (signal).deps === null && /** @type {Derived} */ (signal).effects === null ) { var derived = /** @type {Derived} */ (signal); var parent = derived.parent; if (parent !== null && (parent.f & UNOWNED) === 0) { // If the derived is owned by another derived then mark it as unowned // as the derived value might have been referenced in a different context // since and thus its parent might not be its true owner anymore derived.f ^= UNOWNED; } } if (is_derived) { derived = /** @type {Derived} */ (signal); if (check_dirtiness(derived)) { update_derived(derived); } } if (is_destroying_effect && old_values.has(signal)) { return old_values.get(signal); } return signal.v; } /** * When used inside a [`$derived`](https://svelte.dev/docs/svelte/$derived) or [`$effect`](https://svelte.dev/docs/svelte/$effect), * any state read inside `fn` will not be treated as a dependency. * * ```ts * $effect(() => { * // this will run when `data` changes, but not when `time` changes * save(data, { * timestamp: untrack(() => time) * }); * }); * ``` * @template T * @param {() => T} fn * @returns {T} */ function untrack(fn) { var previous_untracking = untracking; try { untracking = true; return fn(); } finally { untracking = previous_untracking; } } const STATUS_MASK = -7169; /** * @param {Signal} signal * @param {number} status * @returns {void} */ function set_signal_status(signal, status) { signal.f = (signal.f & STATUS_MASK) | status; } /** * Possibly traverse an object and read all its properties so that they're all reactive in case this is `$state`. * Does only check first level of an object for performance reasons (heuristic should be good for 99% of all cases). * @param {any} value * @returns {void} */ 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 prop = value[key]; if (typeof prop === 'object' && prop && STATE_SYMBOL in prop) { deep_read(prop); } } } } /** * Deeply traverse an object and read all its properties * so that they're all reactive in case this is `$state` * @param {any} value * @param {Set} visited * @returns {void} */ function deep_read(value, visited = new Set()) { if ( typeof value === 'object' && value !== null && // We don't want to traverse DOM elements !(value instanceof EventTarget) && !visited.has(value) ) { visited.add(value); // When working with a possible SvelteDate, this // will ensure we capture changes to it. if (value instanceof Date) { value.getTime(); } for (let key in value) { try { deep_read(value[key], visited); } catch (e) { // continue } } 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 get = descriptors[key].get; if (get) { try { get.call(value); } catch (e) { // continue } } } } } } /** @param {string} html */ function create_fragment_from_html(html) { var elem = document.createElement('template'); elem.innerHTML = html.replaceAll('', ''); // XHTML compliance return elem.content; } /** @import { Effect, TemplateNode } from '#client' */ /** @import { TemplateStructure } from './types' */ /** * @param {TemplateNode} start * @param {TemplateNode | null} end */ function assign_nodes(start, end) { var effect = /** @type {Effect} */ (active_effect); if (effect.nodes_start === null) { effect.nodes_start = start; effect.nodes_end = end; } } /** * @param {string} content * @param {number} flags * @returns {() => Node | Node[]} */ /*#__NO_SIDE_EFFECTS__*/ function from_html(content, flags) { var is_fragment = (flags & TEMPLATE_FRAGMENT) !== 0; var use_import_node = (flags & TEMPLATE_USE_IMPORT_NODE) !== 0; /** @type {Node} */ var node; /** * Whether or not the first item is a text/element node. If not, we need to * create an additional comment node to act as `effect.nodes.start` */ var has_start = !content.startsWith(''); return () => { if (node === undefined) { node = create_fragment_from_html(has_start ? content : '' + content); if (!is_fragment) node = /** @type {Node} */ (get_first_child(node)); } var clone = /** @type {TemplateNode} */ ( use_import_node || is_firefox ? document.importNode(node, true) : node.cloneNode(true) ); if (is_fragment) { var start = /** @type {TemplateNode} */ (get_first_child(clone)); var end = /** @type {TemplateNode} */ (clone.lastChild); assign_nodes(start, end); } else { assign_nodes(clone, clone); } return clone; }; } function comment() { var frag = document.createDocumentFragment(); var start = document.createComment(''); var anchor = create_text(); frag.append(start, anchor); assign_nodes(start, anchor); return frag; } /** * Assign the created (or in hydration mode, traversed) dom elements to the current block * and insert the elements into the dom (in client mode). * @param {Text | Comment | Element} anchor * @param {DocumentFragment | Element} dom */ function append(anchor, dom) { if (anchor === null) { // edge case — void `` with content return; } anchor.before(/** @type {Node} */ (dom)); } /** @import { ComponentContext, Effect, TemplateNode } from '#client' */ /** @import { Component, ComponentType, SvelteComponent, MountOptions } from '../../index.js' */ /** * @param {Element} text * @param {string} value * @returns {void} */ function set_text(text, value) { // For objects, we apply string coercion (which might make things like $state array references in the template reactive) before diffing var str = value == null ? '' : typeof value === 'object' ? value + '' : value; // @ts-expect-error if (str !== (text.__t ??= text.nodeValue)) { // @ts-expect-error text.__t = str; text.nodeValue = str + ''; } } /** @import { Effect, Source, TemplateNode } from '#client' */ const PENDING = 0; const THEN = 1; const CATCH = 2; /** * @template V * @param {TemplateNode} node * @param {(() => Promise)} get_input * @param {null | ((anchor: Node) => void)} pending_fn * @param {null | ((anchor: Node, value: Source) => void)} then_fn * @param {null | ((anchor: Node, error: unknown) => void)} catch_fn * @returns {void} */ function await_block(node, get_input, pending_fn, then_fn, catch_fn) { var anchor = node; var runes = is_runes(); var active_component_context = component_context; /** @type {V | Promise | typeof UNINITIALIZED} */ var input = UNINITIALIZED; /** @type {Effect | null} */ var pending_effect; /** @type {Effect | null} */ var then_effect; /** @type {Effect | null} */ var catch_effect; var input_source = (runes ? source : mutable_source)(/** @type {V} */ (undefined)); var error_source = (runes ? source : mutable_source)(undefined); var resolved = false; /** * @param {PENDING | THEN | CATCH} state * @param {boolean} restore */ function update(state, restore) { resolved = true; if (restore) { set_active_effect(effect); set_active_reaction(effect); // TODO do we need both? set_component_context(active_component_context); } try { if (state === PENDING && pending_fn) { if (pending_effect) resume_effect(pending_effect); else pending_effect = branch(() => pending_fn(anchor)); } if (state === THEN && then_fn) { if (then_effect) resume_effect(then_effect); else then_effect = branch(() => then_fn(anchor, input_source)); } if (state === CATCH && catch_fn) { if (catch_effect) resume_effect(catch_effect); else catch_effect = branch(() => catch_fn(anchor, error_source)); } if (state !== PENDING && pending_effect) { pause_effect(pending_effect, () => (pending_effect = null)); } if (state !== THEN && then_effect) { pause_effect(then_effect, () => (then_effect = null)); } if (state !== CATCH && catch_effect) { pause_effect(catch_effect, () => (catch_effect = null)); } } finally { if (restore) { set_component_context(null); set_active_reaction(null); set_active_effect(null); // without this, the DOM does not update until two ticks after the promise // resolves, which is unexpected behaviour (and somewhat irksome to test) flushSync(); } } } var effect = block(() => { if (input === (input = get_input())) return; if (is_promise(input)) { var promise = input; resolved = false; promise.then( (value) => { if (promise !== input) return; // we technically could use `set` here since it's on the next microtick // but let's use internal_set for consistency and just to be safe internal_set(input_source, value); update(THEN, true); }, (error) => { if (promise !== input) return; // we technically could use `set` here since it's on the next microtick // but let's use internal_set for consistency and just to be safe internal_set(error_source, error); update(CATCH, true); if (!catch_fn) { // Rethrow the error if no catch block exists throw error_source.v; } } ); { // Wait a microtask before checking if we should show the pending state as // the promise might have resolved by the next microtask. queue_micro_task(() => { if (!resolved) update(PENDING, true); }); } } else { internal_set(input_source, input); update(THEN, false); } // Set the input to something else, in order to disable the promise callbacks return () => (input = UNINITIALIZED); }); } /** @import { Effect, TemplateNode } from '#client' */ /** * @param {TemplateNode} node * @param {(branch: (fn: (anchor: Node, elseif?: [number,number]) => void, flag?: boolean) => void) => void} fn * @param {[number,number]} [elseif] * @returns {void} */ function if_block(node, fn, [root_index, hydrate_index] = [0, 0]) { var anchor = node; /** @type {Effect | null} */ var consequent_effect = null; /** @type {Effect | null} */ var alternate_effect = null; /** @type {UNINITIALIZED | boolean | null} */ var condition = UNINITIALIZED; var flags = root_index > 0 ? EFFECT_TRANSPARENT : 0; var has_branch = false; const set_branch = ( /** @type {(anchor: Node, elseif?: [number,number]) => void} */ fn, flag = true ) => { has_branch = true; update_branch(flag, fn); }; const update_branch = ( /** @type {boolean | null} */ new_condition, /** @type {null | ((anchor: Node, elseif?: [number,number]) => void)} */ fn ) => { if (condition === (condition = new_condition)) return; if (condition) { if (consequent_effect) { resume_effect(consequent_effect); } else if (fn) { consequent_effect = branch(() => fn(anchor)); } if (alternate_effect) { pause_effect(alternate_effect, () => { alternate_effect = null; }); } } else { if (alternate_effect) { resume_effect(alternate_effect); } else if (fn) { alternate_effect = branch(() => fn(anchor, [root_index + 1, hydrate_index])); } if (consequent_effect) { pause_effect(consequent_effect, () => { consequent_effect = null; }); } } }; block(() => { has_branch = false; fn(set_branch); if (!has_branch) { update_branch(null, null); } }, flags); } /** @import { EachItem, EachState, Effect, MaybeSource, Source, TemplateNode, TransitionManager, Value } from '#client' */ /** * @param {any} _ * @param {number} i */ function index(_, i) { return i; } /** * Pause multiple effects simultaneously, and coordinate their * subsequent destruction. Used in each blocks * @param {EachState} state * @param {EachItem[]} items * @param {null | Node} controlled_anchor * @param {Map} items_map */ function pause_effects(state, items, controlled_anchor, items_map) { /** @type {TransitionManager[]} */ var transitions = []; var length = items.length; for (var i = 0; i < length; i++) { pause_children(items[i].e, transitions, true); } var is_controlled = length > 0 && transitions.length === 0 && controlled_anchor !== null; // If we have a controlled anchor, it means that the each block is inside a single // DOM element, so we can apply a fast-path for clearing the contents of the element. if (is_controlled) { var parent_node = /** @type {Element} */ ( /** @type {Element} */ (controlled_anchor).parentNode ); clear_text_content(parent_node); parent_node.append(/** @type {Element} */ (controlled_anchor)); items_map.clear(); link(state, items[0].prev, items[length - 1].next); } run_out_transitions(transitions, () => { for (var i = 0; i < length; i++) { var item = items[i]; if (!is_controlled) { items_map.delete(item.k); link(state, item.prev, item.next); } destroy_effect(item.e, !is_controlled); } }); } /** * @template V * @param {Element | Comment} node The next sibling node, or the parent node if this is a 'controlled' block * @param {number} flags * @param {() => V[]} get_collection * @param {(value: V, index: number) => any} get_key * @param {(anchor: Node, item: MaybeSource, index: MaybeSource) => void} render_fn * @param {null | ((anchor: Node) => void)} fallback_fn * @returns {void} */ function each(node, flags, get_collection, get_key, render_fn, fallback_fn = null) { var anchor = node; /** @type {EachState} */ var state = { flags, items: new Map(), first: null }; /** @type {Effect | null} */ var fallback = null; var was_empty = false; // TODO: ideally we could use derived for runes mode but because of the ability // to use a store which can be mutated, we can't do that here as mutating a store // will still result in the collection array being the same from the store var each_array = derived_safe_equal(() => { var collection = get_collection(); return is_array(collection) ? collection : collection == null ? [] : array_from(collection); }); block(() => { var array = get(each_array); var length = array.length; if (was_empty && length === 0) { // ignore updates if the array is empty, // and it already was empty on previous run return; } was_empty = length === 0; { reconcile(array, state, anchor, render_fn, flags, get_key, get_collection); } if (fallback_fn !== null) { if (length === 0) { if (fallback) { resume_effect(fallback); } else { fallback = branch(() => fallback_fn(anchor)); } } else if (fallback !== null) { pause_effect(fallback, () => { fallback = null; }); } } // When we mount the each block for the first time, the collection won't be // connected to this effect as the effect hasn't finished running yet and its deps // won't be assigned. However, it's possible that when reconciling the each block // that a mutation occurred and it's made the collection MAYBE_DIRTY, so reading the // collection again can provide consistency to the reactive graph again as the deriveds // will now be `CLEAN`. get(each_array); }); } /** * Add, remove, or reorder items output by an each block as its input changes * @template V * @param {Array} array * @param {EachState} state * @param {Element | Comment | Text} anchor * @param {(anchor: Node, item: MaybeSource, index: number | Source, collection: () => V[]) => void} render_fn * @param {number} flags * @param {(value: V, index: number) => any} get_key * @param {() => V[]} get_collection * @returns {void} */ function reconcile(array, state, anchor, render_fn, flags, get_key, get_collection) { var length = array.length; var items = state.items; var first = state.first; var current = first; /** @type {undefined | Set} */ var seen; /** @type {EachItem | null} */ var prev = null; /** @type {EachItem[]} */ var matched = []; /** @type {EachItem[]} */ var stashed = []; /** @type {V} */ var value; /** @type {any} */ var key; /** @type {EachItem | undefined} */ var item; /** @type {number} */ var i; for (i = 0; i < length; i += 1) { value = array[i]; key = get_key(value, i); item = items.get(key); if (item === undefined) { var child_anchor = current ? /** @type {TemplateNode} */ (current.e.nodes_start) : anchor; prev = create_item( child_anchor, state, prev, prev === null ? state.first : prev.next, value, key, i, render_fn, flags, get_collection ); items.set(key, prev); matched = []; stashed = []; current = prev.next; continue; } { update_item(item, value, i); } if ((item.e.f & INERT) !== 0) { resume_effect(item.e); } if (item !== current) { if (seen !== undefined && seen.has(item)) { if (matched.length < stashed.length) { // more efficient to move later items to the front 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(state, a.prev, b.next); link(state, prev, a); link(state, b, start); current = start; prev = b; i -= 1; matched = []; stashed = []; } else { // more efficient to move earlier items to the back seen.delete(item); move(item, current, anchor); link(state, item.prev, item.next); link(state, item, prev === null ? state.first : prev.next); link(state, prev, item); prev = item; } continue; } matched = []; stashed = []; while (current !== null && current.k !== key) { // If the each block isn't inert and an item has an effect that is already inert, // skip over adding it to our seen Set as the item is already being handled if ((current.e.f & INERT) === 0) { (seen ??= new Set()).add(current); } stashed.push(current); current = current.next; } if (current === null) { continue; } item = current; } matched.push(item); prev = item; current = item.next; } if (current !== null || seen !== undefined) { var to_destroy = seen === undefined ? [] : array_from(seen); while (current !== null) { // If the each block isn't inert, then inert effects are currently outroing and will be removed once the transition is finished if ((current.e.f & INERT) === 0) { to_destroy.push(current); } current = current.next; } var destroy_length = to_destroy.length; if (destroy_length > 0) { var controlled_anchor = null; pause_effects(state, to_destroy, controlled_anchor, items); } } /** @type {Effect} */ (active_effect).first = state.first && state.first.e; /** @type {Effect} */ (active_effect).last = prev && prev.e; } /** * @param {EachItem} item * @param {any} value * @param {number} index * @param {number} type * @returns {void} */ function update_item(item, value, index, type) { { internal_set(item.v, value); } { item.i = index; } } /** * @template V * @param {Node} anchor * @param {EachState} state * @param {EachItem | null} prev * @param {EachItem | null} next * @param {V} value * @param {unknown} key * @param {number} index * @param {(anchor: Node, item: V | Source, index: number | Value, collection: () => V[]) => void} render_fn * @param {number} flags * @param {() => V[]} get_collection * @returns {EachItem} */ function create_item( anchor, state, prev, next, value, key, index, render_fn, flags, get_collection ) { var reactive = (flags & EACH_ITEM_REACTIVE) !== 0; var mutable = (flags & EACH_ITEM_IMMUTABLE) === 0; var v = reactive ? (mutable ? mutable_source(value) : source(value)) : value; var i = (flags & EACH_INDEX_REACTIVE) === 0 ? index : source(index); /** @type {EachItem} */ var item = { i, v, k: key, a: null, // @ts-expect-error e: null, prev, next }; try { item.e = branch(() => render_fn(anchor, v, i, get_collection), hydrating); item.e.prev = prev && prev.e; item.e.next = next && next.e; if (prev === null) { state.first = item; } else { prev.next = item; prev.e.next = item.e; } if (next !== null) { next.prev = item; next.e.prev = item.e; } return item; } finally { } } /** * @param {EachItem} item * @param {EachItem | null} next * @param {Text | Element | Comment} anchor */ function move(item, next, anchor) { var end = item.next ? /** @type {TemplateNode} */ (item.next.e.nodes_start) : anchor; var dest = next ? /** @type {TemplateNode} */ (next.e.nodes_start) : anchor; var node = /** @type {TemplateNode} */ (item.e.nodes_start); while (node !== end) { var next_node = /** @type {TemplateNode} */ (get_next_sibling(node)); dest.before(node); node = next_node; } } /** * @param {EachState} state * @param {EachItem | null} prev * @param {EachItem | null} next */ function link(state, prev, next) { if (prev === null) { state.first = next; } else { prev.next = next; prev.e.next = next && next.e; } if (next !== null) { next.prev = prev; next.e.prev = prev && prev.e; } } /** @import { ComponentContextLegacy } from '#client' */ /** * Legacy-mode only: Call `onMount` callbacks and set up `beforeUpdate`/`afterUpdate` effects * @param {boolean} [immutable] */ function init(immutable = false) { const context = /** @type {ComponentContextLegacy} */ (component_context); const callbacks = context.l.u; if (!callbacks) return; let props = () => deep_read_state(context.s); if (immutable) { let version = 0; let prev = /** @type {Record} */ ({}); // In legacy immutable mode, before/afterUpdate only fire if the object identity of a prop changes const d = derived(() => { let changed = false; const props = context.s; for (const key in props) { if (props[key] !== prev[key]) { prev[key] = props[key]; changed = true; } } if (changed) version++; return version; }); props = () => get(d); } // beforeUpdate if (callbacks.b.length) { user_pre_effect(() => { observe_all(context, props); run_all(callbacks.b); }); } // onMount (must run before afterUpdate) user_effect(() => { const fns = untrack(() => callbacks.m.map(run)); return () => { for (const fn of fns) { if (typeof fn === 'function') { fn(); } } }; }); // afterUpdate if (callbacks.a.length) { user_effect(() => { observe_all(context, props); run_all(callbacks.a); }); } } /** * Invoke the getter of all signals associated with a component * so they can be registered to the effect this function is called in. * @param {ComponentContextLegacy} context * @param {(() => void)} props */ function observe_all(context, props) { if (context.l.s) { for (const signal of context.l.s) get(signal); } props(); } var root_1$8 = from_html(`

Left data is null

`); var root_2$2 = from_html(`
  • `); function Left($$anchor, $$props) { push($$props, true); var fragment = comment(); var node = first_child(fragment); { var consequent = ($$anchor) => { var p = root_1$8(); append($$anchor, p); }; var alternate = ($$anchor) => { var li = root_2$2(); var text = child(li); template_effect(() => set_text(text, `Left: ${$$props.data.RelativePath ?? ''} - ${$$props.data.Size ?? ''} - ${$$props.data.Ticks ?? ''}`)); append($$anchor, li); }; if_block(node, ($$render) => { if (!$$props.data) $$render(consequent); else $$render(alternate, false); }); } append($$anchor, fragment); pop(); } var root_1$7 = from_html(`

    Right data is null

    `); var root_2$1 = from_html(`
  • `); function Right($$anchor, $$props) { push($$props, true); var fragment = comment(); var node = first_child(fragment); { var consequent = ($$anchor) => { var p = root_1$7(); append($$anchor, p); }; var alternate = ($$anchor) => { var li = root_2$1(); var text = child(li); template_effect(() => set_text(text, `Right: ${$$props.data.RelativePath ?? ''} - ${$$props.data.Size ?? ''} - ${$$props.data.Ticks ?? ''}`)); append($$anchor, li); }; if_block(node, ($$render) => { if (!$$props.data) $$render(consequent); else $$render(alternate, false); }); } append($$anchor, fragment); pop(); } var root_1$6 = from_html(`

    AreEqual data is null

    `); var root_3$7 = from_html(`

    AreEqual data is empty

    `); var root_5$7 = from_html(`AreEqual: `, 1); function AreEqual($$anchor, $$props) { push($$props, true); var fragment = comment(); var node = first_child(fragment); { var consequent = ($$anchor) => { var p = root_1$6(); append($$anchor, p); }; var alternate = ($$anchor, $$elseif) => { { var consequent_1 = ($$anchor) => { var p_1 = root_3$7(); append($$anchor, p_1); }; var alternate_1 = ($$anchor) => { var fragment_1 = comment(); var node_1 = first_child(fragment_1); each(node_1, 17, () => $$props.data, index, ($$anchor, segment) => { var fragment_2 = root_5$7(); var node_2 = sibling(first_child(fragment_2)); Left(node_2, { get data() { return get(segment).Left; } }); var node_3 = sibling(node_2, 2); Right(node_3, { get data() { return get(segment).Right; } }); append($$anchor, fragment_2); }); append($$anchor, fragment_1); }; if_block( $$anchor, ($$render) => { if ($$props.data.length === 0) $$render(consequent_1); else $$render(alternate_1, false); }, $$elseif ); } }; if_block(node, ($$render) => { if (!$$props.data) $$render(consequent); else $$render(alternate, false); }); } append($$anchor, fragment); pop(); } var root_1$5 = from_html(`

    LeftSideIsNewer data is null

    `); var root_3$6 = from_html(`

    LeftSideIsNewer data is empty

    `); var root_5$6 = from_html(`LeftSideIsNewer: `, 1); function LeftSideIsNewer($$anchor, $$props) { push($$props, true); var fragment = comment(); var node = first_child(fragment); { var consequent = ($$anchor) => { var p = root_1$5(); append($$anchor, p); }; var alternate = ($$anchor, $$elseif) => { { var consequent_1 = ($$anchor) => { var p_1 = root_3$6(); append($$anchor, p_1); }; var alternate_1 = ($$anchor) => { var fragment_1 = comment(); var node_1 = first_child(fragment_1); each(node_1, 17, () => $$props.data, index, ($$anchor, segment) => { var fragment_2 = root_5$6(); var node_2 = sibling(first_child(fragment_2)); Left(node_2, { get data() { return get(segment).Left; } }); var node_3 = sibling(node_2, 2); Right(node_3, { get data() { return get(segment).Right; } }); append($$anchor, fragment_2); }); append($$anchor, fragment_1); }; if_block( $$anchor, ($$render) => { if ($$props.data.length === 0) $$render(consequent_1); else $$render(alternate_1, false); }, $$elseif ); } }; if_block(node, ($$render) => { if (!$$props.data) $$render(consequent); else $$render(alternate, false); }); } append($$anchor, fragment); pop(); } var root_1$4 = from_html(`

    LeftSideOnly data is null

    `); var root_3$5 = from_html(`

    LeftSideOnly data is empty

    `); var root_5$5 = from_html(`LeftSideOnly: `, 1); function LeftSideOnly($$anchor, $$props) { push($$props, true); var fragment = comment(); var node = first_child(fragment); { var consequent = ($$anchor) => { var p = root_1$4(); append($$anchor, p); }; var alternate = ($$anchor, $$elseif) => { { var consequent_1 = ($$anchor) => { var p_1 = root_3$5(); append($$anchor, p_1); }; var alternate_1 = ($$anchor) => { var fragment_1 = comment(); var node_1 = first_child(fragment_1); each(node_1, 17, () => $$props.data, index, ($$anchor, segment) => { var fragment_2 = root_5$5(); var node_2 = sibling(first_child(fragment_2)); Left(node_2, { get data() { return get(segment).Left; } }); var node_3 = sibling(node_2, 2); Right(node_3, { get data() { return get(segment).Right; } }); append($$anchor, fragment_2); }); append($$anchor, fragment_1); }; if_block( $$anchor, ($$render) => { if ($$props.data.length === 0) $$render(consequent_1); else $$render(alternate_1, false); }, $$elseif ); } }; if_block(node, ($$render) => { if (!$$props.data) $$render(consequent); else $$render(alternate, false); }); } append($$anchor, fragment); pop(); } var root_1$3 = from_html(`

    NotEqualBut data is null

    `); var root_3$4 = from_html(`

    NotEqualBut data is empty

    `); var root_5$4 = from_html(`NotEqualBut: `, 1); function NotEqualBut($$anchor, $$props) { push($$props, true); var fragment = comment(); var node = first_child(fragment); { var consequent = ($$anchor) => { var p = root_1$3(); append($$anchor, p); }; var alternate = ($$anchor, $$elseif) => { { var consequent_1 = ($$anchor) => { var p_1 = root_3$4(); append($$anchor, p_1); }; var alternate_1 = ($$anchor) => { var fragment_1 = comment(); var node_1 = first_child(fragment_1); each(node_1, 17, () => $$props.data, index, ($$anchor, segment) => { var fragment_2 = root_5$4(); var node_2 = sibling(first_child(fragment_2)); Left(node_2, { get data() { return get(segment).Left; } }); var node_3 = sibling(node_2, 2); Right(node_3, { get data() { return get(segment).Right; } }); append($$anchor, fragment_2); }); append($$anchor, fragment_1); }; if_block( $$anchor, ($$render) => { if ($$props.data.length === 0) $$render(consequent_1); else $$render(alternate_1, false); }, $$elseif ); } }; if_block(node, ($$render) => { if (!$$props.data) $$render(consequent); else $$render(alternate, false); }); } append($$anchor, fragment); pop(); } var root_1$2 = from_html(`

    Records data is null

    `); var root_3$3 = from_html(`

    Records data is empty

    `); var root_5$3 = from_html(`
  • `); var root_4$1 = from_html(`Records: `, 1); function Records($$anchor, $$props) { push($$props, true); var fragment = comment(); var node = first_child(fragment); { var consequent = ($$anchor) => { var p = root_1$2(); append($$anchor, p); }; var alternate = ($$anchor, $$elseif) => { { var consequent_1 = ($$anchor) => { var p_1 = root_3$3(); append($$anchor, p_1); }; var alternate_1 = ($$anchor) => { var fragment_1 = root_4$1(); var node_1 = sibling(first_child(fragment_1)); each(node_1, 17, () => $$props.data, index, ($$anchor, record) => { var li = root_5$3(); var text = child(li); template_effect(() => set_text(text, get(record).Left.Records)); append($$anchor, li); }); append($$anchor, fragment_1); }; if_block( $$anchor, ($$render) => { if ($$props.data.length === 0) $$render(consequent_1); else $$render(alternate_1, false); }, $$elseif ); } }; if_block(node, ($$render) => { if (!$$props.data) $$render(consequent); else $$render(alternate, false); }); } append($$anchor, fragment); pop(); } var root_1$1 = from_html(`

    RightSideIsNewer data is null

    `); var root_3$2 = from_html(`

    RightSideIsNewer data is empty

    `); var root_5$2 = from_html(`RightSideIsNewer: `, 1); function RightSideIsNewer($$anchor, $$props) { push($$props, true); var fragment = comment(); var node = first_child(fragment); { var consequent = ($$anchor) => { var p = root_1$1(); append($$anchor, p); }; var alternate = ($$anchor, $$elseif) => { { var consequent_1 = ($$anchor) => { var p_1 = root_3$2(); append($$anchor, p_1); }; var alternate_1 = ($$anchor) => { var fragment_1 = comment(); var node_1 = first_child(fragment_1); each(node_1, 17, () => $$props.data, index, ($$anchor, segment) => { var fragment_2 = root_5$2(); var node_2 = sibling(first_child(fragment_2)); Left(node_2, { get data() { return get(segment).Left; } }); var node_3 = sibling(node_2, 2); Right(node_3, { get data() { return get(segment).Right; } }); append($$anchor, fragment_2); }); append($$anchor, fragment_1); }; if_block( $$anchor, ($$render) => { if ($$props.data.length === 0) $$render(consequent_1); else $$render(alternate_1, false); }, $$elseif ); } }; if_block(node, ($$render) => { if (!$$props.data) $$render(consequent); else $$render(alternate, false); }); } append($$anchor, fragment); pop(); } var root_1 = from_html(`

    RightSideOnly data is null

    `); var root_3$1 = from_html(`

    RightSideOnly data is empty

    `); var root_5$1 = from_html(`RightSideOnly: `, 1); function RightSideOnly($$anchor, $$props) { push($$props, true); var fragment = comment(); var node = first_child(fragment); { var consequent = ($$anchor) => { var p = root_1(); append($$anchor, p); }; var alternate = ($$anchor, $$elseif) => { { var consequent_1 = ($$anchor) => { var p_1 = root_3$1(); append($$anchor, p_1); }; var alternate_1 = ($$anchor) => { var fragment_1 = comment(); var node_1 = first_child(fragment_1); each(node_1, 17, () => $$props.data, index, ($$anchor, segment) => { var fragment_2 = root_5$1(); var node_2 = sibling(first_child(fragment_2)); Left(node_2, { get data() { return get(segment).Left; } }); var node_3 = sibling(node_2, 2); Right(node_3, { get data() { return get(segment).Right; } }); append($$anchor, fragment_2); }); append($$anchor, fragment_1); }; if_block( $$anchor, ($$render) => { if ($$props.data.length === 0) $$render(consequent_1); else $$render(alternate_1, false); }, $$elseif ); } }; if_block(node, ($$render) => { if (!$$props.data) $$render(consequent); else $$render(alternate, false); }); } append($$anchor, fragment); pop(); } var root_2 = from_html(`

    Review data is null

    `); var root_3 = from_html(`

    Review:

    `, 1); var root_4 = from_html(` `); var root_5 = from_html(`waiting`); function Review($$anchor, $$props) { push($$props, false); let promise = fetch("http://localhost:5004/api/SyncV1/?", { method: "POST", body: ` { "LeftDirectory": "D:/Tmp/phares/VisualStudioCodeLeft", "RightDirectory": "D:/Tmp/phares/VisualStudioCode", "Records": [ { "RelativePath": "D:/Tmp/phares/VisualStudioCode", "Size": 0, "Ticks": 0 }, { "RelativePath": "z-exclude-patterns.nsv", "Size": 230, "Ticks": 638843891271017574 }, { "RelativePath": "z-include-patterns.nsv", "Size": 4, "Ticks": 638796666663591762 } ] } `, headers: { "Content-Type": "application/json" } }).then((x) => x.json()); init(); var fragment = comment(); var node = first_child(fragment); await_block( node, () => promise, ($$anchor) => { var span_1 = root_5(); append($$anchor, span_1); }, ($$anchor, data) => { var fragment_1 = comment(); var node_1 = first_child(fragment_1); { var consequent = ($$anchor) => { var p = root_2(); append($$anchor, p); }; var alternate = ($$anchor) => { var fragment_2 = root_3(); var node_2 = sibling(first_child(fragment_2), 2); AreEqual(node_2, { get data() { return get(data).AreEqual; } }); var node_3 = sibling(node_2, 2); LeftSideIsNewer(node_3, { get data() { return get(data).LeftSideIsNewer; } }); var node_4 = sibling(node_3, 2); LeftSideOnly(node_4, { get data() { return get(data).LeftSideOnly; } }); var node_5 = sibling(node_4, 2); NotEqualBut(node_5, { get data() { return get(data).NotEqualBut; } }); var node_6 = sibling(node_5, 2); Records(node_6, { get data() { return get(data).Records; } }); var node_7 = sibling(node_6, 2); RightSideIsNewer(node_7, { get data() { return get(data).RightSideIsNewer; } }); var node_8 = sibling(node_7, 2); RightSideOnly(node_8, { get data() { return get(data).RightSideOnly; } }); append($$anchor, fragment_2); }; if_block(node_1, ($$render) => { if (!get(data)) $$render(consequent); else $$render(alternate, false); }); } append($$anchor, fragment_1); }, ($$anchor, error) => { var span = root_4(); var text = child(span); template_effect(() => set_text(text, get(error))); append($$anchor, span); } ); append($$anchor, fragment); pop(); } let div = document.createElement("div"); let script = document.currentScript; script.parentNode.insertBefore(div, script); new Review({ target: div, props: {}, }); })();