/* THIS IS A GENERATED/BUNDLED FILE BY ESBUILD if you want to view the source, please visit the github repository of this plugin */ "use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); // src/main.ts var main_exports = {}; __export(main_exports, { default: () => TrashExplorerPlugin }); module.exports = __toCommonJS(main_exports); var import_obsidian3 = require("obsidian"); // src/models.ts var import_obsidian = require("obsidian"); // src/path.ts var nodePath = __toESM(require("path"), 1); var isNodeAvailable = typeof (nodePath == null ? void 0 : nodePath.basename) === "function"; var basename2 = isNodeAvailable ? nodePath.basename : (path) => { var _a; return ((_a = path.match(/([^/]+)\/?$/)) == null ? void 0 : _a.at(1)) || path; }; var dirname2 = isNodeAvailable ? nodePath.dirname : (path) => { var _a; return ((_a = path.match(/^(.+)\/.+/)) == null ? void 0 : _a.at(1)) || "."; }; // src/models.ts var TRASH_ROOT = (0, import_obsidian.normalizePath)(".trash"); var Trash = class { constructor(vault) { this.vault = vault; this.root = new TrashedFolder( this.vault, TRASH_ROOT, null, null ); this.collator = new Intl.Collator(void 0, { sensitivity: "base" }); this.compareName = (a, b) => this.collator.compare(a, b); } get items() { return this.root.children; } get isEmpty() { return this.root.isEmpty; } async refresh() { if (await this.vault.adapter.exists(this.root.path)) { const trashedFiles = await this.vault.adapter.list(this.root.path); this.root.children = await this.buildItems(trashedFiles, this.root); } else { this.root.children = []; } } async empty() { if (await this.vault.adapter.exists(this.root.path)) { await this.root.remove(); } this.root.children = []; } async buildItems(trashedFiles, parent) { const items = []; for (const path of trashedFiles.folders.sort(this.compareName)) { const files = await this.vault.adapter.list(path); const stat = await this.vault.adapter.stat(path); const trashedFolder = new TrashedFolder( this.vault, path, stat, parent ); items.push(trashedFolder); trashedFolder.children = await this.buildItems( files, trashedFolder ); } for (const path of trashedFiles.files.sort(this.compareName)) { const stat = await this.vault.adapter.stat(path); const trashedFile = new TrashedFile(this.vault, path, stat, parent); items.push(trashedFile); } return items; } }; var TrashedBase = class { constructor(vault, path, stat, parent) { this.vault = vault; this.parent = parent; this.path = (0, import_obsidian.normalizePath)(path); this.basename = basename2(this.path); this.size = (stat == null ? void 0 : stat.size) || 0; } async restore() { const restorePath = (0, import_obsidian.normalizePath)( this.path.replace(`${TRASH_ROOT}/`, "") ); if (await this.vault.adapter.exists(restorePath)) { return false; } const restoreParentDir = dirname2(restorePath); if (!await this.vault.adapter.exists(restoreParentDir)) { await this.vault.adapter.mkdir(restoreParentDir); } await this.vault.adapter.rename(this.path, restorePath); return true; } }; var TrashedFile = class extends TrashedBase { constructor() { super(...arguments); this.kind = "file"; } async restore() { var _a; const restored = await super.restore(); if (restored) { (_a = this.parent) == null ? void 0 : _a.removeChild(this); } return restored; } async remove() { var _a; await this.vault.adapter.remove(this.path); (_a = this.parent) == null ? void 0 : _a.removeChild(this); } }; var TrashedFolder = class extends TrashedBase { constructor() { super(...arguments); this.kind = "folder"; this.children = []; } get isEmpty() { return this.children.length === 0; } async restore() { var _a; const restored = await super.restore(); if (restored) { (_a = this.parent) == null ? void 0 : _a.removeChild(this); } return restored; } async remove() { var _a; await this.vault.adapter.rmdir(this.path, true); (_a = this.parent) == null ? void 0 : _a.removeChild(this); } removeChild(child) { const index = this.children.indexOf(child); if (index !== -1) { this.children.splice(index, 1); } } }; // src/view.ts var import_obsidian2 = require("obsidian"); // node_modules/svelte/src/runtime/internal/utils.js function noop() { } function run(fn) { return fn(); } function blank_object() { return /* @__PURE__ */ Object.create(null); } function run_all(fns) { fns.forEach(run); } function is_function(thing) { return typeof thing === "function"; } function safe_not_equal(a, b) { return a != a ? b == b : a !== b || a && typeof a === "object" || typeof a === "function"; } function is_empty(obj) { return Object.keys(obj).length === 0; } // node_modules/svelte/src/runtime/internal/globals.js var globals = typeof window !== "undefined" ? window : typeof globalThis !== "undefined" ? globalThis : ( // @ts-ignore Node typings have this global ); // node_modules/svelte/src/runtime/internal/ResizeObserverSingleton.js var ResizeObserverSingleton = class _ResizeObserverSingleton { /** @param {ResizeObserverOptions} options */ constructor(options) { /** * @private * @readonly * @type {WeakMap} */ __publicField(this, "_listeners", "WeakMap" in globals ? /* @__PURE__ */ new WeakMap() : void 0); /** * @private * @type {ResizeObserver} */ __publicField(this, "_observer"); /** @type {ResizeObserverOptions} */ __publicField(this, "options"); this.options = options; } /** * @param {Element} element * @param {import('./private.js').Listener} listener * @returns {() => void} */ observe(element2, listener) { this._listeners.set(element2, listener); this._getObserver().observe(element2, this.options); return () => { this._listeners.delete(element2); this._observer.unobserve(element2); }; } /** * @private */ _getObserver() { var _a; return (_a = this._observer) != null ? _a : this._observer = new ResizeObserver((entries) => { var _a2; for (const entry of entries) { _ResizeObserverSingleton.entries.set(entry.target, entry); (_a2 = this._listeners.get(entry.target)) == null ? void 0 : _a2(entry); } }); } }; ResizeObserverSingleton.entries = "WeakMap" in globals ? /* @__PURE__ */ new WeakMap() : void 0; // node_modules/svelte/src/runtime/internal/dom.js var is_hydrating = false; function start_hydrating() { is_hydrating = true; } function end_hydrating() { is_hydrating = false; } function append(target, node) { target.appendChild(node); } function append_styles(target, style_sheet_id, styles) { const append_styles_to = get_root_for_style(target); if (!append_styles_to.getElementById(style_sheet_id)) { const style = element("style"); style.id = style_sheet_id; style.textContent = styles; append_stylesheet(append_styles_to, style); } } function get_root_for_style(node) { if (!node) return document; const root = node.getRootNode ? node.getRootNode() : node.ownerDocument; if (root && /** @type {ShadowRoot} */ root.host) { return ( /** @type {ShadowRoot} */ root ); } return node.ownerDocument; } function append_stylesheet(node, style) { append( /** @type {Document} */ node.head || node, style ); return style.sheet; } function insert(target, node, anchor) { target.insertBefore(node, anchor || null); } function detach(node) { if (node.parentNode) { node.parentNode.removeChild(node); } } function destroy_each(iterations, detaching) { for (let i = 0; i < iterations.length; i += 1) { if (iterations[i]) iterations[i].d(detaching); } } function element(name) { return document.createElement(name); } function text(data) { return document.createTextNode(data); } function space() { return text(" "); } function empty() { return text(""); } function listen(node, event, handler, options) { node.addEventListener(event, handler, options); return () => node.removeEventListener(event, handler, options); } function attr(node, attribute, value) { if (value == null) node.removeAttribute(attribute); else if (node.getAttribute(attribute) !== value) node.setAttribute(attribute, value); } function children(element2) { return Array.from(element2.childNodes); } function set_data(text2, data) { data = "" + data; if (text2.data === data) return; text2.data = /** @type {string} */ data; } function set_input_value(input, value) { input.value = value == null ? "" : value; } function set_style(node, key, value, important) { if (value == null) { node.style.removeProperty(key); } else { node.style.setProperty(key, value, important ? "important" : ""); } } function custom_event(type, detail, { bubbles = false, cancelable = false } = {}) { return new CustomEvent(type, { detail, bubbles, cancelable }); } function get_custom_elements_slots(element2) { const result = {}; element2.childNodes.forEach( /** @param {Element} node */ (node) => { result[node.slot || "default"] = true; } ); return result; } // node_modules/svelte/src/runtime/internal/lifecycle.js var current_component; function set_current_component(component) { current_component = component; } function get_current_component() { if (!current_component) throw new Error("Function called outside component initialization"); return current_component; } function createEventDispatcher() { const component = get_current_component(); return (type, detail, { cancelable = false } = {}) => { const callbacks = component.$$.callbacks[type]; if (callbacks) { const event = custom_event( /** @type {string} */ type, detail, { cancelable } ); callbacks.slice().forEach((fn) => { fn.call(component, event); }); return !event.defaultPrevented; } return true; }; } function bubble(component, event) { const callbacks = component.$$.callbacks[event.type]; if (callbacks) { callbacks.slice().forEach((fn) => fn.call(this, event)); } } // node_modules/svelte/src/runtime/internal/scheduler.js var dirty_components = []; var binding_callbacks = []; var render_callbacks = []; var flush_callbacks = []; var resolved_promise = /* @__PURE__ */ Promise.resolve(); var update_scheduled = false; function schedule_update() { if (!update_scheduled) { update_scheduled = true; resolved_promise.then(flush); } } function add_render_callback(fn) { render_callbacks.push(fn); } function add_flush_callback(fn) { flush_callbacks.push(fn); } var seen_callbacks = /* @__PURE__ */ new Set(); var flushidx = 0; function flush() { if (flushidx !== 0) { return; } const saved_component = current_component; do { try { while (flushidx < dirty_components.length) { const component = dirty_components[flushidx]; flushidx++; set_current_component(component); update(component.$$); } } catch (e) { dirty_components.length = 0; flushidx = 0; throw e; } set_current_component(null); dirty_components.length = 0; flushidx = 0; while (binding_callbacks.length) binding_callbacks.pop()(); for (let i = 0; i < render_callbacks.length; i += 1) { const callback = render_callbacks[i]; if (!seen_callbacks.has(callback)) { seen_callbacks.add(callback); callback(); } } render_callbacks.length = 0; } while (dirty_components.length); while (flush_callbacks.length) { flush_callbacks.pop()(); } update_scheduled = false; seen_callbacks.clear(); set_current_component(saved_component); } function update($$) { if ($$.fragment !== null) { $$.update(); run_all($$.before_update); const dirty = $$.dirty; $$.dirty = [-1]; $$.fragment && $$.fragment.p($$.ctx, dirty); $$.after_update.forEach(add_render_callback); } } function flush_render_callbacks(fns) { const filtered = []; const targets = []; render_callbacks.forEach((c) => fns.indexOf(c) === -1 ? filtered.push(c) : targets.push(c)); targets.forEach((c) => c()); render_callbacks = filtered; } // node_modules/svelte/src/runtime/internal/transitions.js var outroing = /* @__PURE__ */ new Set(); var outros; function group_outros() { outros = { r: 0, c: [], p: outros // parent group }; } function check_outros() { if (!outros.r) { run_all(outros.c); } outros = outros.p; } function transition_in(block, local) { if (block && block.i) { outroing.delete(block); block.i(local); } } function transition_out(block, local, detach2, callback) { if (block && block.o) { if (outroing.has(block)) return; outroing.add(block); outros.c.push(() => { outroing.delete(block); if (callback) { if (detach2) block.d(1); callback(); } }); block.o(local); } else if (callback) { callback(); } } // node_modules/svelte/src/runtime/internal/each.js function ensure_array_like(array_like_or_iterator) { return (array_like_or_iterator == null ? void 0 : array_like_or_iterator.length) !== void 0 ? array_like_or_iterator : Array.from(array_like_or_iterator); } // node_modules/svelte/src/shared/boolean_attributes.js var _boolean_attributes = ( /** @type {const} */ [ "allowfullscreen", "allowpaymentrequest", "async", "autofocus", "autoplay", "checked", "controls", "default", "defer", "disabled", "formnovalidate", "hidden", "inert", "ismap", "loop", "multiple", "muted", "nomodule", "novalidate", "open", "playsinline", "readonly", "required", "reversed", "selected" ] ); var boolean_attributes = /* @__PURE__ */ new Set([..._boolean_attributes]); // node_modules/svelte/src/runtime/internal/Component.js function bind(component, name, callback) { const index = component.$$.props[name]; if (index !== void 0) { component.$$.bound[index] = callback; callback(component.$$.ctx[index]); } } function create_component(block) { block && block.c(); } function mount_component(component, target, anchor) { const { fragment, after_update } = component.$$; fragment && fragment.m(target, anchor); add_render_callback(() => { const new_on_destroy = component.$$.on_mount.map(run).filter(is_function); if (component.$$.on_destroy) { component.$$.on_destroy.push(...new_on_destroy); } else { run_all(new_on_destroy); } component.$$.on_mount = []; }); after_update.forEach(add_render_callback); } function destroy_component(component, detaching) { const $$ = component.$$; if ($$.fragment !== null) { flush_render_callbacks($$.after_update); run_all($$.on_destroy); $$.fragment && $$.fragment.d(detaching); $$.on_destroy = $$.fragment = null; $$.ctx = []; } } function make_dirty(component, i) { if (component.$$.dirty[0] === -1) { dirty_components.push(component); schedule_update(); component.$$.dirty.fill(0); } component.$$.dirty[i / 31 | 0] |= 1 << i % 31; } function init(component, options, instance4, create_fragment4, not_equal, props, append_styles2 = null, dirty = [-1]) { const parent_component = current_component; set_current_component(component); const $$ = component.$$ = { fragment: null, ctx: [], // state props, update: noop, not_equal, bound: blank_object(), // lifecycle on_mount: [], on_destroy: [], on_disconnect: [], before_update: [], after_update: [], context: new Map(options.context || (parent_component ? parent_component.$$.context : [])), // everything else callbacks: blank_object(), dirty, skip_bound: false, root: options.target || parent_component.$$.root }; append_styles2 && append_styles2($$.root); let ready = false; $$.ctx = instance4 ? instance4(component, options.props || {}, (i, ret, ...rest) => { const value = rest.length ? rest[0] : ret; if ($$.ctx && not_equal($$.ctx[i], $$.ctx[i] = value)) { if (!$$.skip_bound && $$.bound[i]) $$.bound[i](value); if (ready) make_dirty(component, i); } return ret; }) : []; $$.update(); ready = true; run_all($$.before_update); $$.fragment = create_fragment4 ? create_fragment4($$.ctx) : false; if (options.target) { if (options.hydrate) { start_hydrating(); const nodes = children(options.target); $$.fragment && $$.fragment.l(nodes); nodes.forEach(detach); } else { $$.fragment && $$.fragment.c(); } if (options.intro) transition_in(component.$$.fragment); mount_component(component, options.target, options.anchor); end_hydrating(); flush(); } set_current_component(parent_component); } var SvelteElement; if (typeof HTMLElement === "function") { SvelteElement = class extends HTMLElement { constructor($$componentCtor, $$slots, use_shadow_dom) { super(); /** The Svelte component constructor */ __publicField(this, "$$ctor"); /** Slots */ __publicField(this, "$$s"); /** The Svelte component instance */ __publicField(this, "$$c"); /** Whether or not the custom element is connected */ __publicField(this, "$$cn", false); /** Component props data */ __publicField(this, "$$d", {}); /** `true` if currently in the process of reflecting component props back to attributes */ __publicField(this, "$$r", false); /** @type {Record} Props definition (name, reflected, type etc) */ __publicField(this, "$$p_d", {}); /** @type {Record} Event listeners */ __publicField(this, "$$l", {}); /** @type {Map} Event listener unsubscribe functions */ __publicField(this, "$$l_u", /* @__PURE__ */ new Map()); this.$$ctor = $$componentCtor; this.$$s = $$slots; if (use_shadow_dom) { this.attachShadow({ mode: "open" }); } } addEventListener(type, listener, options) { this.$$l[type] = this.$$l[type] || []; this.$$l[type].push(listener); if (this.$$c) { const unsub = this.$$c.$on(type, listener); this.$$l_u.set(listener, unsub); } super.addEventListener(type, listener, options); } removeEventListener(type, listener, options) { super.removeEventListener(type, listener, options); if (this.$$c) { const unsub = this.$$l_u.get(listener); if (unsub) { unsub(); this.$$l_u.delete(listener); } } } async connectedCallback() { this.$$cn = true; if (!this.$$c) { let create_slot = function(name) { return () => { let node; const obj = { c: function create() { node = element("slot"); if (name !== "default") { attr(node, "name", name); } }, /** * @param {HTMLElement} target * @param {HTMLElement} [anchor] */ m: function mount(target, anchor) { insert(target, node, anchor); }, d: function destroy(detaching) { if (detaching) { detach(node); } } }; return obj; }; }; await Promise.resolve(); if (!this.$$cn || this.$$c) { return; } const $$slots = {}; const existing_slots = get_custom_elements_slots(this); for (const name of this.$$s) { if (name in existing_slots) { $$slots[name] = [create_slot(name)]; } } for (const attribute of this.attributes) { const name = this.$$g_p(attribute.name); if (!(name in this.$$d)) { this.$$d[name] = get_custom_element_value(name, attribute.value, this.$$p_d, "toProp"); } } for (const key in this.$$p_d) { if (!(key in this.$$d) && this[key] !== void 0) { this.$$d[key] = this[key]; delete this[key]; } } this.$$c = new this.$$ctor({ target: this.shadowRoot || this, props: { ...this.$$d, $$slots, $$scope: { ctx: [] } } }); const reflect_attributes = () => { this.$$r = true; for (const key in this.$$p_d) { this.$$d[key] = this.$$c.$$.ctx[this.$$c.$$.props[key]]; if (this.$$p_d[key].reflect) { const attribute_value = get_custom_element_value( key, this.$$d[key], this.$$p_d, "toAttribute" ); if (attribute_value == null) { this.removeAttribute(this.$$p_d[key].attribute || key); } else { this.setAttribute(this.$$p_d[key].attribute || key, attribute_value); } } } this.$$r = false; }; this.$$c.$$.after_update.push(reflect_attributes); reflect_attributes(); for (const type in this.$$l) { for (const listener of this.$$l[type]) { const unsub = this.$$c.$on(type, listener); this.$$l_u.set(listener, unsub); } } this.$$l = {}; } } // We don't need this when working within Svelte code, but for compatibility of people using this outside of Svelte // and setting attributes through setAttribute etc, this is helpful attributeChangedCallback(attr2, _oldValue, newValue) { var _a; if (this.$$r) return; attr2 = this.$$g_p(attr2); this.$$d[attr2] = get_custom_element_value(attr2, newValue, this.$$p_d, "toProp"); (_a = this.$$c) == null ? void 0 : _a.$set({ [attr2]: this.$$d[attr2] }); } disconnectedCallback() { this.$$cn = false; Promise.resolve().then(() => { if (!this.$$cn && this.$$c) { this.$$c.$destroy(); this.$$c = void 0; } }); } $$g_p(attribute_name) { return Object.keys(this.$$p_d).find( (key) => this.$$p_d[key].attribute === attribute_name || !this.$$p_d[key].attribute && key.toLowerCase() === attribute_name ) || attribute_name; } }; } function get_custom_element_value(prop, value, props_definition, transform) { var _a; const type = (_a = props_definition[prop]) == null ? void 0 : _a.type; value = type === "Boolean" && typeof value !== "boolean" ? value != null : value; if (!transform || !props_definition[prop]) { return value; } else if (transform === "toAttribute") { switch (type) { case "Object": case "Array": return value == null ? null : JSON.stringify(value); case "Boolean": return value ? "" : null; case "Number": return value == null ? null : value; default: return value; } } else { switch (type) { case "Object": case "Array": return value && JSON.parse(value); case "Boolean": return value; case "Number": return value != null ? +value : value; default: return value; } } } var SvelteComponent = class { constructor() { /** * ### PRIVATE API * * Do not use, may change at any time * * @type {any} */ __publicField(this, "$$"); /** * ### PRIVATE API * * Do not use, may change at any time * * @type {any} */ __publicField(this, "$$set"); } /** @returns {void} */ $destroy() { destroy_component(this, 1); this.$destroy = noop; } /** * @template {Extract} K * @param {K} type * @param {((e: Events[K]) => void) | null | undefined} callback * @returns {() => void} */ $on(type, callback) { if (!is_function(callback)) { return noop; } const callbacks = this.$$.callbacks[type] || (this.$$.callbacks[type] = []); callbacks.push(callback); return () => { const index = callbacks.indexOf(callback); if (index !== -1) callbacks.splice(index, 1); }; } /** * @param {Partial} props * @returns {void} */ $set(props) { if (this.$$set && !is_empty(props)) { this.$$.skip_bound = true; this.$$set(props); this.$$.skip_bound = false; } } }; // node_modules/svelte/src/shared/version.js var PUBLIC_VERSION = "4"; // node_modules/svelte/src/runtime/internal/disclose-version/index.js if (typeof window !== "undefined") (window.__svelte || (window.__svelte = { v: /* @__PURE__ */ new Set() })).v.add(PUBLIC_VERSION); // src/views/SearchInput.svelte function add_css(target) { append_styles(target, "svelte-p3qvn0", `.search-input-container.svelte-p3qvn0.svelte-p3qvn0.svelte-p3qvn0{flex-grow:1;position:relative}.search-input-container.svelte-p3qvn0.svelte-p3qvn0.svelte-p3qvn0:before{top:calc((var(--input-height) - var(--search-icon-size)) / 2);left:8px;position:absolute;content:"";height:var(--search-icon-size);width:var(--search-icon-size);display:block;background-color:var(--search-icon-color);mask-image:url("data:image/svg+xml,");-webkit-mask-image:url("data:image/svg+xml,");mask-repeat:no-repeat;-webkit-mask-repeat:no-repeat}.search-input-container.svelte-p3qvn0 input.svelte-p3qvn0.svelte-p3qvn0{padding-right:56px;display:block;width:100%;padding-right:28px;padding-left:36px}.search-input-container.svelte-p3qvn0 input.svelte-p3qvn0:placeholder-shown~.search-input-clear-button.svelte-p3qvn0{display:none}.search-input-clear-button.svelte-p3qvn0.svelte-p3qvn0.svelte-p3qvn0{position:absolute;background:transparent;border-radius:50%;color:var(--search-clear-button-color);cursor:var(--cursor);top:0px;right:2px;bottom:0px;line-height:0;height:var(--input-height);width:28px;margin:auto;padding:0 0;text-align:center;display:flex;justify-content:center;align-items:center;transition:color 0.15s ease-in-out}.search-input-clear-button.svelte-p3qvn0.svelte-p3qvn0.svelte-p3qvn0:after{content:"";height:var(--search-clear-button-size);width:var(--search-clear-button-size);display:block;background-color:currentColor;mask-image:url("data:image/svg+xml,");-webkit-mask-image:url("data:image/svg+xml,");mask-repeat:no-repeat;-webkit-mask-repeat:no-repeat}`); } function create_fragment(ctx) { let div1; let input; let t; let div0; let mounted; let dispose; return { c() { div1 = element("div"); input = element("input"); t = space(); div0 = element("div"); attr(input, "type", "search"); attr(input, "enterkeyhint", "search"); attr(input, "spellcheck", "false"); attr( input, "placeholder", /*placeholder*/ ctx[1] ); attr(input, "class", "svelte-p3qvn0"); attr(div0, "class", "search-input-clear-button svelte-p3qvn0"); attr(div0, "aria-label", "Clear search"); attr(div0, "role", "button"); attr(div0, "tabindex", "-1"); attr(div1, "class", "search-input-container svelte-p3qvn0"); }, m(target, anchor) { insert(target, div1, anchor); append(div1, input); set_input_value( input, /*query*/ ctx[0] ); append(div1, t); append(div1, div0); if (!mounted) { dispose = [ listen( input, "input", /*input_input_handler*/ ctx[3] ), listen( input, "keydown", /*keydown_handler*/ ctx[4] ), listen( div0, "keydown", /*keydown_handler_1*/ ctx[5] ), listen( div0, "click", /*click_handler*/ ctx[6] ) ]; mounted = true; } }, p(ctx2, [dirty]) { if (dirty & /*placeholder*/ 2) { attr( input, "placeholder", /*placeholder*/ ctx2[1] ); } if (dirty & /*query*/ 1 && input.value !== /*query*/ ctx2[0]) { set_input_value( input, /*query*/ ctx2[0] ); } }, i: noop, o: noop, d(detaching) { if (detaching) { detach(div1); } mounted = false; run_all(dispose); } }; } function instance($$self, $$props, $$invalidate) { let { query = "" } = $$props; let { placeholder = "" } = $$props; function clear() { $$invalidate(0, query = ""); } function input_input_handler() { query = this.value; $$invalidate(0, query); } const keydown_handler = (e) => e.key === "Escape" && clear(); const keydown_handler_1 = (e) => e.key === "Enter" && clear(); const click_handler = () => clear(); $$self.$$set = ($$props2) => { if ("query" in $$props2) $$invalidate(0, query = $$props2.query); if ("placeholder" in $$props2) $$invalidate(1, placeholder = $$props2.placeholder); }; return [ query, placeholder, clear, input_input_handler, keydown_handler, keydown_handler_1, click_handler ]; } var SearchInput = class extends SvelteComponent { constructor(options) { super(); init(this, options, instance, create_fragment, safe_not_equal, { query: 0, placeholder: 1 }, add_css); } }; var SearchInput_default = SearchInput; // src/formatting.ts var units = [ { size: 0, name: "B", digits: 0 }, { size: 1024, name: "KB", digits: 1 }, { size: 1024 * 1024, name: "MB", digits: 1 }, { size: 1024 * 1024 * 1024, name: "GB", digits: 1 } ]; function formatItemStats(item) { if (item.kind === "folder") { const fileCount = item.children.reduce( (count, child) => child.kind === "file" ? count + 1 : count, 0 ); const folderCount = item.children.length - fileCount; const fileWord = fileCount === 1 ? "file" : "files"; const folderWord = folderCount === 1 ? "folder" : "folders"; return `${fileCount} ${fileWord}, ${folderCount} ${folderWord}`; } const bestUnit = units.reduce( (best, unit) => item.size >= unit.size ? unit : best ); const displaySize = item.size / (bestUnit.size || 1); return `${displaySize.toFixed(bestUnit.digits)} ${bestUnit.name}`; } // src/views/TrashItemView.svelte function add_css2(target) { append_styles(target, "svelte-yg1um6", ".trash-item.svelte-yg1um6{margin-bottom:var(--size-2-1);border-radius:var(--radius-s);cursor:var(--cursor);color:var(--nav-item-color);font-size:var(--nav-item-size);font-weight:var(--nav-item-weight);line-height:var(--line-height-tight);padding:var(--nav-item-padding);padding-left:0;padding-right:0;display:flex;align-items:center}.textcontainer.svelte-yg1um6{display:flex;flex-direction:column;overflow:hidden}.name.svelte-yg1um6{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.info.svelte-yg1um6{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--text-faint);font-size:var(--font-ui-small)}.buttons.svelte-yg1um6{margin-left:auto;display:flex;gap:3px;padding-left:3px}"); } function get_each_context(ctx, list, i) { const child_ctx = ctx.slice(); child_ctx[8] = list[i]; return child_ctx; } function create_if_block(ctx) { let div; let current; let each_value = ensure_array_like( /*viewNode*/ ctx[0].nodes ); let each_blocks = []; for (let i = 0; i < each_value.length; i += 1) { each_blocks[i] = create_each_block(get_each_context(ctx, each_value, i)); } const out = (i) => transition_out(each_blocks[i], 1, 1, () => { each_blocks[i] = null; }); return { c() { div = element("div"); for (let i = 0; i < each_blocks.length; i += 1) { each_blocks[i].c(); } set_style(div, "padding-left", "1em"); }, m(target, anchor) { insert(target, div, anchor); for (let i = 0; i < each_blocks.length; i += 1) { if (each_blocks[i]) { each_blocks[i].m(div, null); } } current = true; }, p(ctx2, dirty) { if (dirty & /*viewNode*/ 1) { each_value = ensure_array_like( /*viewNode*/ ctx2[0].nodes ); let i; for (i = 0; i < each_value.length; i += 1) { const child_ctx = get_each_context(ctx2, each_value, i); if (each_blocks[i]) { each_blocks[i].p(child_ctx, dirty); transition_in(each_blocks[i], 1); } else { each_blocks[i] = create_each_block(child_ctx); each_blocks[i].c(); transition_in(each_blocks[i], 1); each_blocks[i].m(div, null); } } group_outros(); for (i = each_value.length; i < each_blocks.length; i += 1) { out(i); } check_outros(); } }, i(local) { if (current) return; for (let i = 0; i < each_value.length; i += 1) { transition_in(each_blocks[i]); } current = true; }, o(local) { each_blocks = each_blocks.filter(Boolean); for (let i = 0; i < each_blocks.length; i += 1) { transition_out(each_blocks[i]); } current = false; }, d(detaching) { if (detaching) { detach(div); } destroy_each(each_blocks, detaching); } }; } function create_each_block(ctx) { let trashitemview; let current; trashitemview = new TrashItemView({ props: { viewNode: ( /*childNode*/ ctx[8] ) } }); trashitemview.$on( "restore", /*restore_handler*/ ctx[6] ); trashitemview.$on( "delete", /*delete_handler*/ ctx[7] ); return { c() { create_component(trashitemview.$$.fragment); }, m(target, anchor) { mount_component(trashitemview, target, anchor); current = true; }, p(ctx2, dirty) { const trashitemview_changes = {}; if (dirty & /*viewNode*/ 1) trashitemview_changes.viewNode = /*childNode*/ ctx2[8]; trashitemview.$set(trashitemview_changes); }, i(local) { if (current) return; transition_in(trashitemview.$$.fragment, local); current = true; }, o(local) { transition_out(trashitemview.$$.fragment, local); current = false; }, d(detaching) { destroy_component(trashitemview, detaching); } }; } function create_fragment2(ctx) { let div4; let div2; let div0; let t0_value = ( /*item*/ ctx[1].basename + "" ); let t0; let div0_aria_label_value; let t1; let div1; let t2; let t3; let div3; let button0; let t4; let button1; let t5; let if_block_anchor; let current; let mounted; let dispose; let if_block = ( /*viewNode*/ ctx[0].nodes.length && create_if_block(ctx) ); return { c() { div4 = element("div"); div2 = element("div"); div0 = element("div"); t0 = text(t0_value); t1 = space(); div1 = element("div"); t2 = text( /*itemStats*/ ctx[2] ); t3 = space(); div3 = element("div"); button0 = element("button"); button0.innerHTML = ``; t4 = space(); button1 = element("button"); button1.innerHTML = ``; t5 = space(); if (if_block) if_block.c(); if_block_anchor = empty(); attr(div0, "class", "name svelte-yg1um6"); attr(div0, "aria-label", div0_aria_label_value = /*item*/ ctx[1].basename); attr(div1, "class", "info svelte-yg1um6"); attr(div2, "class", "textcontainer svelte-yg1um6"); attr(button0, "aria-label", "Restore"); attr(button1, "aria-label", "Delete permanently"); attr(button1, "class", "mod-warning"); attr(div3, "class", "buttons svelte-yg1um6"); attr(div4, "class", "trash-item svelte-yg1um6"); }, m(target, anchor) { insert(target, div4, anchor); append(div4, div2); append(div2, div0); append(div0, t0); append(div2, t1); append(div2, div1); append(div1, t2); append(div4, t3); append(div4, div3); append(div3, button0); append(div3, t4); append(div3, button1); insert(target, t5, anchor); if (if_block) if_block.m(target, anchor); insert(target, if_block_anchor, anchor); current = true; if (!mounted) { dispose = [ listen( button0, "click", /*click_handler*/ ctx[4] ), listen( button1, "click", /*click_handler_1*/ ctx[5] ) ]; mounted = true; } }, p(ctx2, [dirty]) { if ((!current || dirty & /*item*/ 2) && t0_value !== (t0_value = /*item*/ ctx2[1].basename + "")) set_data(t0, t0_value); if (!current || dirty & /*item*/ 2 && div0_aria_label_value !== (div0_aria_label_value = /*item*/ ctx2[1].basename)) { attr(div0, "aria-label", div0_aria_label_value); } if (!current || dirty & /*itemStats*/ 4) set_data( t2, /*itemStats*/ ctx2[2] ); if ( /*viewNode*/ ctx2[0].nodes.length ) { if (if_block) { if_block.p(ctx2, dirty); if (dirty & /*viewNode*/ 1) { transition_in(if_block, 1); } } else { if_block = create_if_block(ctx2); if_block.c(); transition_in(if_block, 1); if_block.m(if_block_anchor.parentNode, if_block_anchor); } } else if (if_block) { group_outros(); transition_out(if_block, 1, 1, () => { if_block = null; }); check_outros(); } }, i(local) { if (current) return; transition_in(if_block); current = true; }, o(local) { transition_out(if_block); current = false; }, d(detaching) { if (detaching) { detach(div4); detach(t5); detach(if_block_anchor); } if (if_block) if_block.d(detaching); mounted = false; run_all(dispose); } }; } function instance2($$self, $$props, $$invalidate) { let item; let itemStats; let { viewNode } = $$props; const dispatch = createEventDispatcher(); const click_handler = () => dispatch("restore", item); const click_handler_1 = () => dispatch("delete", item); function restore_handler(event) { bubble.call(this, $$self, event); } function delete_handler(event) { bubble.call(this, $$self, event); } $$self.$$set = ($$props2) => { if ("viewNode" in $$props2) $$invalidate(0, viewNode = $$props2.viewNode); }; $$self.$$.update = () => { if ($$self.$$.dirty & /*viewNode*/ 1) { $: $$invalidate(1, item = viewNode.item); } if ($$self.$$.dirty & /*item*/ 2) { $: $$invalidate(2, itemStats = formatItemStats(item)); } }; return [ viewNode, item, itemStats, dispatch, click_handler, click_handler_1, restore_handler, delete_handler ]; } var TrashItemView = class extends SvelteComponent { constructor(options) { super(); init(this, options, instance2, create_fragment2, safe_not_equal, { viewNode: 0 }, add_css2); } }; var TrashItemView_default = TrashItemView; // src/views/TrashView.svelte function add_css3(target) { append_styles(target, "svelte-70qt8d", ".container.svelte-70qt8d{height:100%;display:flex;flex-direction:column}.node-list.svelte-70qt8d{margin-top:1em;overflow-y:auto}"); } function get_each_context2(ctx, list, i) { const child_ctx = ctx.slice(); child_ctx[6] = list[i]; return child_ctx; } function create_else_block(ctx) { let div0; let searchinput; let updating_query; let t; let div1; let current; function searchinput_query_binding(value) { ctx[3](value); } let searchinput_props = { placeholder: "Filter by name..." }; if ( /*searchQuery*/ ctx[1] !== void 0 ) { searchinput_props.query = /*searchQuery*/ ctx[1]; } searchinput = new SearchInput_default({ props: searchinput_props }); binding_callbacks.push(() => bind(searchinput, "query", searchinput_query_binding)); let each_value = ensure_array_like( /*viewNodes*/ ctx[2] ); let each_blocks = []; for (let i = 0; i < each_value.length; i += 1) { each_blocks[i] = create_each_block2(get_each_context2(ctx, each_value, i)); } const out = (i) => transition_out(each_blocks[i], 1, 1, () => { each_blocks[i] = null; }); let each_1_else = null; if (!each_value.length) { each_1_else = create_else_block_1(ctx); } return { c() { div0 = element("div"); create_component(searchinput.$$.fragment); t = space(); div1 = element("div"); for (let i = 0; i < each_blocks.length; i += 1) { each_blocks[i].c(); } if (each_1_else) { each_1_else.c(); } attr(div1, "class", "node-list svelte-70qt8d"); }, m(target, anchor) { insert(target, div0, anchor); mount_component(searchinput, div0, null); insert(target, t, anchor); insert(target, div1, anchor); for (let i = 0; i < each_blocks.length; i += 1) { if (each_blocks[i]) { each_blocks[i].m(div1, null); } } if (each_1_else) { each_1_else.m(div1, null); } current = true; }, p(ctx2, dirty) { const searchinput_changes = {}; if (!updating_query && dirty & /*searchQuery*/ 2) { updating_query = true; searchinput_changes.query = /*searchQuery*/ ctx2[1]; add_flush_callback(() => updating_query = false); } searchinput.$set(searchinput_changes); if (dirty & /*viewNodes*/ 4) { each_value = ensure_array_like( /*viewNodes*/ ctx2[2] ); let i; for (i = 0; i < each_value.length; i += 1) { const child_ctx = get_each_context2(ctx2, each_value, i); if (each_blocks[i]) { each_blocks[i].p(child_ctx, dirty); transition_in(each_blocks[i], 1); } else { each_blocks[i] = create_each_block2(child_ctx); each_blocks[i].c(); transition_in(each_blocks[i], 1); each_blocks[i].m(div1, null); } } group_outros(); for (i = each_value.length; i < each_blocks.length; i += 1) { out(i); } check_outros(); if (!each_value.length && each_1_else) { each_1_else.p(ctx2, dirty); } else if (!each_value.length) { each_1_else = create_else_block_1(ctx2); each_1_else.c(); each_1_else.m(div1, null); } else if (each_1_else) { each_1_else.d(1); each_1_else = null; } } }, i(local) { if (current) return; transition_in(searchinput.$$.fragment, local); for (let i = 0; i < each_value.length; i += 1) { transition_in(each_blocks[i]); } current = true; }, o(local) { transition_out(searchinput.$$.fragment, local); each_blocks = each_blocks.filter(Boolean); for (let i = 0; i < each_blocks.length; i += 1) { transition_out(each_blocks[i]); } current = false; }, d(detaching) { if (detaching) { detach(div0); detach(t); detach(div1); } destroy_component(searchinput); destroy_each(each_blocks, detaching); if (each_1_else) each_1_else.d(); } }; } function create_if_block2(ctx) { let div; return { c() { div = element("div"); div.textContent = "The trash is empty."; attr(div, "class", "pane-empty"); }, m(target, anchor) { insert(target, div, anchor); }, p: noop, i: noop, o: noop, d(detaching) { if (detaching) { detach(div); } } }; } function create_else_block_1(ctx) { let div; return { c() { div = element("div"); div.textContent = "Filter matched no files."; attr(div, "class", "pane-empty"); }, m(target, anchor) { insert(target, div, anchor); }, p: noop, d(detaching) { if (detaching) { detach(div); } } }; } function create_each_block2(ctx) { let trashitemview; let current; trashitemview = new TrashItemView_default({ props: { viewNode: ( /*viewNode*/ ctx[6] ) } }); trashitemview.$on( "restore", /*restore_handler*/ ctx[4] ); trashitemview.$on( "delete", /*delete_handler*/ ctx[5] ); return { c() { create_component(trashitemview.$$.fragment); }, m(target, anchor) { mount_component(trashitemview, target, anchor); current = true; }, p(ctx2, dirty) { const trashitemview_changes = {}; if (dirty & /*viewNodes*/ 4) trashitemview_changes.viewNode = /*viewNode*/ ctx2[6]; trashitemview.$set(trashitemview_changes); }, i(local) { if (current) return; transition_in(trashitemview.$$.fragment, local); current = true; }, o(local) { transition_out(trashitemview.$$.fragment, local); current = false; }, d(detaching) { destroy_component(trashitemview, detaching); } }; } function create_fragment3(ctx) { let div; let current_block_type_index; let if_block; let current; const if_block_creators = [create_if_block2, create_else_block]; const if_blocks = []; function select_block_type(ctx2, dirty) { if ( /*trash*/ ctx2[0].isEmpty ) return 0; return 1; } current_block_type_index = select_block_type(ctx, -1); if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx); return { c() { div = element("div"); if_block.c(); attr(div, "class", "container svelte-70qt8d"); }, m(target, anchor) { insert(target, div, anchor); if_blocks[current_block_type_index].m(div, null); current = true; }, p(ctx2, [dirty]) { let previous_block_index = current_block_type_index; current_block_type_index = select_block_type(ctx2, dirty); if (current_block_type_index === previous_block_index) { if_blocks[current_block_type_index].p(ctx2, dirty); } else { group_outros(); transition_out(if_blocks[previous_block_index], 1, 1, () => { if_blocks[previous_block_index] = null; }); check_outros(); if_block = if_blocks[current_block_type_index]; if (!if_block) { if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx2); if_block.c(); } else { if_block.p(ctx2, dirty); } transition_in(if_block, 1); if_block.m(div, null); } }, i(local) { if (current) return; transition_in(if_block); current = true; }, o(local) { transition_out(if_block); current = false; }, d(detaching) { if (detaching) { detach(div); } if_blocks[current_block_type_index].d(); } }; } function buildViewNodes(items, filter) { const nodes = []; for (const item of items) { const childNodes = item.kind === "folder" ? buildViewNodes(item.children, filter) : []; if (childNodes.length || matchesFilter(item, filter)) { nodes.push({ item, nodes: childNodes }); } } return nodes; } function matchesFilter(item, filter) { return !filter || item.path.toLocaleUpperCase().includes(filter); } function instance3($$self, $$props, $$invalidate) { let viewNodes; let { trash } = $$props; let searchQuery = ""; function searchinput_query_binding(value) { searchQuery = value; $$invalidate(1, searchQuery); } function restore_handler(event) { bubble.call(this, $$self, event); } function delete_handler(event) { bubble.call(this, $$self, event); } $$self.$$set = ($$props2) => { if ("trash" in $$props2) $$invalidate(0, trash = $$props2.trash); }; $$self.$$.update = () => { if ($$self.$$.dirty & /*trash, searchQuery*/ 3) { $: $$invalidate(2, viewNodes = buildViewNodes(trash.items, searchQuery.trim().toLocaleUpperCase())); } }; return [ trash, searchQuery, viewNodes, searchinput_query_binding, restore_handler, delete_handler ]; } var TrashView = class extends SvelteComponent { constructor(options) { super(); init(this, options, instance3, create_fragment3, safe_not_equal, { trash: 0 }, add_css3); } }; var TrashView_default = TrashView; // src/view.ts var VIEW_TYPE = "trash-explorer"; var TrashExplorerView = class extends import_obsidian2.ItemView { constructor(leaf, trash) { super(leaf); this.trash = trash; this.icon = "trash"; this.navigation = false; } getViewType() { return VIEW_TYPE; } getDisplayText() { return "Trash explorer"; } async onOpen() { this.component = new TrashView_default({ target: this.contentEl, props: { trash: this.trash } }); this.component.$on("restore", async (event) => { if (await this.restoreFile(event.detail)) { this.refresh(); } }); this.component.$on("delete", async (event) => { if (await this.deleteFile(event.detail)) { this.refresh(); } }); await this.refresh(); } async onClose() { var _a; (_a = this.component) == null ? void 0 : _a.$destroy(); } async refresh() { var _a; (_a = this.component) == null ? void 0 : _a.$set({ trash: this.trash }); } async restoreFile(item) { if (await item.restore()) { new import_obsidian2.Notice(`Restored "${item.basename}" from trash`); return true; } new import_obsidian2.Notice( `Unable to restore "${item.basename}": the path already exists`, 10 * 1e3 ); return false; } async deleteFile(item) { const title = item.kind === "folder" ? "Delete folder" : "Delete file"; const message = `Are you sure you want to permanently delete "${item.basename}"?`; return new Promise((resolve) => { const confirmModal = new ConfirmModal( this.app, title, message, "Delete", async () => { await item.remove(); new import_obsidian2.Notice(`Permanently deleted "${item.basename}"`); confirmModal.close(); resolve(true); } ); confirmModal.open(); }); } }; var ConfirmModal = class extends import_obsidian2.Modal { constructor(app, title, message, submitText, onSubmit) { super(app); this.title = title; this.message = message; this.submitText = submitText; this.onSubmit = onSubmit; } onOpen() { this.titleEl.setText(this.title); this.contentEl.createEl("p", { text: this.message }); new import_obsidian2.Setting(this.contentEl).addButton( (button) => button.setButtonText(this.submitText).setWarning().onClick(() => { this.onSubmit(); this.close(); }) ).addButton( (button) => button.setButtonText("Cancel").onClick(() => { this.close(); }) ); } onClose() { this.contentEl.empty(); } }; // src/main.ts var TrashExplorerPlugin = class extends import_obsidian3.Plugin { async onload() { this.trash = new Trash(this.app.vault); await this.trash.refresh(); this.registerView( VIEW_TYPE, (leaf) => new TrashExplorerView(leaf, this.trash) ); this.addRibbonIcon( "trash", "Open trash explorer", () => this.activateView() ); this.addCommand({ id: "show-trash-explorer", name: "Show trash explorer", callback: () => this.activateView() }); this.addCommand({ id: "empty-trash", name: "Empty trash", callback: () => this.emptyTrash() }); this.registerEvent( this.app.vault.on("delete", async () => { await this.trash.refresh(); await this.refreshOpenLeaves(); }) ); } onunload() { this.app.workspace.detachLeavesOfType(VIEW_TYPE); } async activateView() { var _a; let leaf = this.app.workspace.getLeavesOfType(VIEW_TYPE)[0]; if (!leaf) { await ((_a = this.app.workspace.getLeftLeaf(false)) == null ? void 0 : _a.setViewState({ type: VIEW_TYPE, active: true })); leaf = this.app.workspace.getLeavesOfType(VIEW_TYPE)[0]; } await this.trash.refresh(); await this.app.workspace.revealLeaf(leaf); await leaf.view.refresh(); } async refreshOpenLeaves() { const leaves = this.app.workspace.getLeavesOfType(VIEW_TYPE); for (const leaf of leaves) { if (leaf.view instanceof TrashExplorerView) { await leaf.view.refresh(); } } } emptyTrash() { const title = "Empty trash"; const message = `Are you sure you want to empty the trash? All files in the "${TRASH_ROOT}" folder will be permanently deleted!`; return new Promise((resolve) => { const confirmModal = new ConfirmModal( this.app, title, message, "Empty trash", async () => { await this.trash.empty(); await this.refreshOpenLeaves(); new import_obsidian3.Notice(`Emptied the trash`); confirmModal.close(); resolve(); } ); confirmModal.open(); }); } }; /* nosourcemap */