/* THIS IS A GENERATED/BUNDLED FILE BY ESBUILD if you want to view the source, please visit the github repository of this plugin */ var __create = Object.create; var __defProp = Object.defineProperty; var __defProps = Object.defineProperties; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropDescs = Object.getOwnPropertyDescriptors; var __getOwnPropNames = Object.getOwnPropertyNames; var __getOwnPropSymbols = Object.getOwnPropertySymbols; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __propIsEnum = Object.prototype.propertyIsEnumerable; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp.call(b, prop)) __defNormalProp(a, prop, b[prop]); if (__getOwnPropSymbols) for (var prop of __getOwnPropSymbols(b)) { if (__propIsEnum.call(b, prop)) __defNormalProp(a, prop, b[prop]); } return a; }; var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); var __markAsModule = (target) => __defProp(target, "__esModule", { value: true }); var __export = (target, all) => { __markAsModule(target); for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __reExport = (target, module2, desc) => { if (module2 && typeof module2 === "object" || typeof module2 === "function") { for (let key of __getOwnPropNames(module2)) if (!__hasOwnProp.call(target, key) && key !== "default") __defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable }); } return target; }; var __toModule = (module2) => { return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2); }; var __async = (__this, __arguments, generator) => { return new Promise((resolve, reject) => { var fulfilled = (value) => { try { step(generator.next(value)); } catch (e) { reject(e); } }; var rejected = (value) => { try { step(generator.throw(value)); } catch (e) { reject(e); } }; var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); step((generator = generator.apply(__this, __arguments)).next()); }); }; // src/main.ts __export(exports, { default: () => MediaDbPlugin }); var import_obsidian10 = __toModule(require("obsidian")); // src/settings/Settings.ts var import_obsidian4 = __toModule(require("obsidian")); // src/settings/suggesters/FolderSuggest.ts var import_obsidian2 = __toModule(require("obsidian")); // src/settings/suggesters/Suggest.ts var import_obsidian = __toModule(require("obsidian")); // node_modules/@popperjs/core/lib/enums.js var top = "top"; var bottom = "bottom"; var right = "right"; var left = "left"; var auto = "auto"; var basePlacements = [top, bottom, right, left]; var start = "start"; var end = "end"; var clippingParents = "clippingParents"; var viewport = "viewport"; var popper = "popper"; var reference = "reference"; var variationPlacements = /* @__PURE__ */ basePlacements.reduce(function(acc, placement) { return acc.concat([placement + "-" + start, placement + "-" + end]); }, []); var placements = /* @__PURE__ */ [].concat(basePlacements, [auto]).reduce(function(acc, placement) { return acc.concat([placement, placement + "-" + start, placement + "-" + end]); }, []); var beforeRead = "beforeRead"; var read = "read"; var afterRead = "afterRead"; var beforeMain = "beforeMain"; var main = "main"; var afterMain = "afterMain"; var beforeWrite = "beforeWrite"; var write = "write"; var afterWrite = "afterWrite"; var modifierPhases = [beforeRead, read, afterRead, beforeMain, main, afterMain, beforeWrite, write, afterWrite]; // node_modules/@popperjs/core/lib/dom-utils/getNodeName.js function getNodeName(element) { return element ? (element.nodeName || "").toLowerCase() : null; } // node_modules/@popperjs/core/lib/dom-utils/getWindow.js function getWindow(node) { if (node == null) { return window; } if (node.toString() !== "[object Window]") { var ownerDocument = node.ownerDocument; return ownerDocument ? ownerDocument.defaultView || window : window; } return node; } // node_modules/@popperjs/core/lib/dom-utils/instanceOf.js function isElement(node) { var OwnElement = getWindow(node).Element; return node instanceof OwnElement || node instanceof Element; } function isHTMLElement(node) { var OwnElement = getWindow(node).HTMLElement; return node instanceof OwnElement || node instanceof HTMLElement; } function isShadowRoot(node) { if (typeof ShadowRoot === "undefined") { return false; } var OwnElement = getWindow(node).ShadowRoot; return node instanceof OwnElement || node instanceof ShadowRoot; } // node_modules/@popperjs/core/lib/modifiers/applyStyles.js function applyStyles(_ref) { var state = _ref.state; Object.keys(state.elements).forEach(function(name) { var style = state.styles[name] || {}; var attributes = state.attributes[name] || {}; var element = state.elements[name]; if (!isHTMLElement(element) || !getNodeName(element)) { return; } Object.assign(element.style, style); Object.keys(attributes).forEach(function(name2) { var value = attributes[name2]; if (value === false) { element.removeAttribute(name2); } else { element.setAttribute(name2, value === true ? "" : value); } }); }); } function effect(_ref2) { var state = _ref2.state; var initialStyles = { popper: { position: state.options.strategy, left: "0", top: "0", margin: "0" }, arrow: { position: "absolute" }, reference: {} }; Object.assign(state.elements.popper.style, initialStyles.popper); state.styles = initialStyles; if (state.elements.arrow) { Object.assign(state.elements.arrow.style, initialStyles.arrow); } return function() { Object.keys(state.elements).forEach(function(name) { var element = state.elements[name]; var attributes = state.attributes[name] || {}; var styleProperties = Object.keys(state.styles.hasOwnProperty(name) ? state.styles[name] : initialStyles[name]); var style = styleProperties.reduce(function(style2, property) { style2[property] = ""; return style2; }, {}); if (!isHTMLElement(element) || !getNodeName(element)) { return; } Object.assign(element.style, style); Object.keys(attributes).forEach(function(attribute) { element.removeAttribute(attribute); }); }); }; } var applyStyles_default = { name: "applyStyles", enabled: true, phase: "write", fn: applyStyles, effect, requires: ["computeStyles"] }; // node_modules/@popperjs/core/lib/utils/getBasePlacement.js function getBasePlacement(placement) { return placement.split("-")[0]; } // node_modules/@popperjs/core/lib/utils/math.js var max = Math.max; var min = Math.min; var round = Math.round; // node_modules/@popperjs/core/lib/dom-utils/getBoundingClientRect.js function getBoundingClientRect(element, includeScale) { if (includeScale === void 0) { includeScale = false; } var rect = element.getBoundingClientRect(); var scaleX = 1; var scaleY = 1; if (isHTMLElement(element) && includeScale) { var offsetHeight = element.offsetHeight; var offsetWidth = element.offsetWidth; if (offsetWidth > 0) { scaleX = round(rect.width) / offsetWidth || 1; } if (offsetHeight > 0) { scaleY = round(rect.height) / offsetHeight || 1; } } return { width: rect.width / scaleX, height: rect.height / scaleY, top: rect.top / scaleY, right: rect.right / scaleX, bottom: rect.bottom / scaleY, left: rect.left / scaleX, x: rect.left / scaleX, y: rect.top / scaleY }; } // node_modules/@popperjs/core/lib/dom-utils/getLayoutRect.js function getLayoutRect(element) { var clientRect = getBoundingClientRect(element); var width = element.offsetWidth; var height = element.offsetHeight; if (Math.abs(clientRect.width - width) <= 1) { width = clientRect.width; } if (Math.abs(clientRect.height - height) <= 1) { height = clientRect.height; } return { x: element.offsetLeft, y: element.offsetTop, width, height }; } // node_modules/@popperjs/core/lib/dom-utils/contains.js function contains(parent, child) { var rootNode = child.getRootNode && child.getRootNode(); if (parent.contains(child)) { return true; } else if (rootNode && isShadowRoot(rootNode)) { var next = child; do { if (next && parent.isSameNode(next)) { return true; } next = next.parentNode || next.host; } while (next); } return false; } // node_modules/@popperjs/core/lib/dom-utils/getComputedStyle.js function getComputedStyle(element) { return getWindow(element).getComputedStyle(element); } // node_modules/@popperjs/core/lib/dom-utils/isTableElement.js function isTableElement(element) { return ["table", "td", "th"].indexOf(getNodeName(element)) >= 0; } // node_modules/@popperjs/core/lib/dom-utils/getDocumentElement.js function getDocumentElement(element) { return ((isElement(element) ? element.ownerDocument : element.document) || window.document).documentElement; } // node_modules/@popperjs/core/lib/dom-utils/getParentNode.js function getParentNode(element) { if (getNodeName(element) === "html") { return element; } return element.assignedSlot || element.parentNode || (isShadowRoot(element) ? element.host : null) || getDocumentElement(element); } // node_modules/@popperjs/core/lib/dom-utils/getOffsetParent.js function getTrueOffsetParent(element) { if (!isHTMLElement(element) || getComputedStyle(element).position === "fixed") { return null; } return element.offsetParent; } function getContainingBlock(element) { var isFirefox = navigator.userAgent.toLowerCase().indexOf("firefox") !== -1; var isIE = navigator.userAgent.indexOf("Trident") !== -1; if (isIE && isHTMLElement(element)) { var elementCss = getComputedStyle(element); if (elementCss.position === "fixed") { return null; } } var currentNode = getParentNode(element); if (isShadowRoot(currentNode)) { currentNode = currentNode.host; } while (isHTMLElement(currentNode) && ["html", "body"].indexOf(getNodeName(currentNode)) < 0) { var css = getComputedStyle(currentNode); if (css.transform !== "none" || css.perspective !== "none" || css.contain === "paint" || ["transform", "perspective"].indexOf(css.willChange) !== -1 || isFirefox && css.willChange === "filter" || isFirefox && css.filter && css.filter !== "none") { return currentNode; } else { currentNode = currentNode.parentNode; } } return null; } function getOffsetParent(element) { var window2 = getWindow(element); var offsetParent = getTrueOffsetParent(element); while (offsetParent && isTableElement(offsetParent) && getComputedStyle(offsetParent).position === "static") { offsetParent = getTrueOffsetParent(offsetParent); } if (offsetParent && (getNodeName(offsetParent) === "html" || getNodeName(offsetParent) === "body" && getComputedStyle(offsetParent).position === "static")) { return window2; } return offsetParent || getContainingBlock(element) || window2; } // node_modules/@popperjs/core/lib/utils/getMainAxisFromPlacement.js function getMainAxisFromPlacement(placement) { return ["top", "bottom"].indexOf(placement) >= 0 ? "x" : "y"; } // node_modules/@popperjs/core/lib/utils/within.js function within(min2, value, max2) { return max(min2, min(value, max2)); } function withinMaxClamp(min2, value, max2) { var v = within(min2, value, max2); return v > max2 ? max2 : v; } // node_modules/@popperjs/core/lib/utils/getFreshSideObject.js function getFreshSideObject() { return { top: 0, right: 0, bottom: 0, left: 0 }; } // node_modules/@popperjs/core/lib/utils/mergePaddingObject.js function mergePaddingObject(paddingObject) { return Object.assign({}, getFreshSideObject(), paddingObject); } // node_modules/@popperjs/core/lib/utils/expandToHashMap.js function expandToHashMap(value, keys) { return keys.reduce(function(hashMap, key) { hashMap[key] = value; return hashMap; }, {}); } // node_modules/@popperjs/core/lib/modifiers/arrow.js var toPaddingObject = function toPaddingObject2(padding, state) { padding = typeof padding === "function" ? padding(Object.assign({}, state.rects, { placement: state.placement })) : padding; return mergePaddingObject(typeof padding !== "number" ? padding : expandToHashMap(padding, basePlacements)); }; function arrow(_ref) { var _state$modifiersData$; var state = _ref.state, name = _ref.name, options = _ref.options; var arrowElement = state.elements.arrow; var popperOffsets2 = state.modifiersData.popperOffsets; var basePlacement = getBasePlacement(state.placement); var axis = getMainAxisFromPlacement(basePlacement); var isVertical = [left, right].indexOf(basePlacement) >= 0; var len = isVertical ? "height" : "width"; if (!arrowElement || !popperOffsets2) { return; } var paddingObject = toPaddingObject(options.padding, state); var arrowRect = getLayoutRect(arrowElement); var minProp = axis === "y" ? top : left; var maxProp = axis === "y" ? bottom : right; var endDiff = state.rects.reference[len] + state.rects.reference[axis] - popperOffsets2[axis] - state.rects.popper[len]; var startDiff = popperOffsets2[axis] - state.rects.reference[axis]; var arrowOffsetParent = getOffsetParent(arrowElement); var clientSize = arrowOffsetParent ? axis === "y" ? arrowOffsetParent.clientHeight || 0 : arrowOffsetParent.clientWidth || 0 : 0; var centerToReference = endDiff / 2 - startDiff / 2; var min2 = paddingObject[minProp]; var max2 = clientSize - arrowRect[len] - paddingObject[maxProp]; var center = clientSize / 2 - arrowRect[len] / 2 + centerToReference; var offset2 = within(min2, center, max2); var axisProp = axis; state.modifiersData[name] = (_state$modifiersData$ = {}, _state$modifiersData$[axisProp] = offset2, _state$modifiersData$.centerOffset = offset2 - center, _state$modifiersData$); } function effect2(_ref2) { var state = _ref2.state, options = _ref2.options; var _options$element = options.element, arrowElement = _options$element === void 0 ? "[data-popper-arrow]" : _options$element; if (arrowElement == null) { return; } if (typeof arrowElement === "string") { arrowElement = state.elements.popper.querySelector(arrowElement); if (!arrowElement) { return; } } if (true) { if (!isHTMLElement(arrowElement)) { console.error(['Popper: "arrow" element must be an HTMLElement (not an SVGElement).', "To use an SVG arrow, wrap it in an HTMLElement that will be used as", "the arrow."].join(" ")); } } if (!contains(state.elements.popper, arrowElement)) { if (true) { console.error(['Popper: "arrow" modifier\'s `element` must be a child of the popper', "element."].join(" ")); } return; } state.elements.arrow = arrowElement; } var arrow_default = { name: "arrow", enabled: true, phase: "main", fn: arrow, effect: effect2, requires: ["popperOffsets"], requiresIfExists: ["preventOverflow"] }; // node_modules/@popperjs/core/lib/utils/getVariation.js function getVariation(placement) { return placement.split("-")[1]; } // node_modules/@popperjs/core/lib/modifiers/computeStyles.js var unsetSides = { top: "auto", right: "auto", bottom: "auto", left: "auto" }; function roundOffsetsByDPR(_ref) { var x = _ref.x, y = _ref.y; var win = window; var dpr = win.devicePixelRatio || 1; return { x: round(x * dpr) / dpr || 0, y: round(y * dpr) / dpr || 0 }; } function mapToStyles(_ref2) { var _Object$assign2; var popper2 = _ref2.popper, popperRect = _ref2.popperRect, placement = _ref2.placement, variation = _ref2.variation, offsets = _ref2.offsets, position = _ref2.position, gpuAcceleration = _ref2.gpuAcceleration, adaptive = _ref2.adaptive, roundOffsets = _ref2.roundOffsets, isFixed = _ref2.isFixed; var _offsets$x = offsets.x, x = _offsets$x === void 0 ? 0 : _offsets$x, _offsets$y = offsets.y, y = _offsets$y === void 0 ? 0 : _offsets$y; var _ref3 = typeof roundOffsets === "function" ? roundOffsets({ x, y }) : { x, y }; x = _ref3.x; y = _ref3.y; var hasX = offsets.hasOwnProperty("x"); var hasY = offsets.hasOwnProperty("y"); var sideX = left; var sideY = top; var win = window; if (adaptive) { var offsetParent = getOffsetParent(popper2); var heightProp = "clientHeight"; var widthProp = "clientWidth"; if (offsetParent === getWindow(popper2)) { offsetParent = getDocumentElement(popper2); if (getComputedStyle(offsetParent).position !== "static" && position === "absolute") { heightProp = "scrollHeight"; widthProp = "scrollWidth"; } } offsetParent = offsetParent; if (placement === top || (placement === left || placement === right) && variation === end) { sideY = bottom; var offsetY = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.height : offsetParent[heightProp]; y -= offsetY - popperRect.height; y *= gpuAcceleration ? 1 : -1; } if (placement === left || (placement === top || placement === bottom) && variation === end) { sideX = right; var offsetX = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.width : offsetParent[widthProp]; x -= offsetX - popperRect.width; x *= gpuAcceleration ? 1 : -1; } } var commonStyles = Object.assign({ position }, adaptive && unsetSides); var _ref4 = roundOffsets === true ? roundOffsetsByDPR({ x, y }) : { x, y }; x = _ref4.x; y = _ref4.y; if (gpuAcceleration) { var _Object$assign; return Object.assign({}, commonStyles, (_Object$assign = {}, _Object$assign[sideY] = hasY ? "0" : "", _Object$assign[sideX] = hasX ? "0" : "", _Object$assign.transform = (win.devicePixelRatio || 1) <= 1 ? "translate(" + x + "px, " + y + "px)" : "translate3d(" + x + "px, " + y + "px, 0)", _Object$assign)); } return Object.assign({}, commonStyles, (_Object$assign2 = {}, _Object$assign2[sideY] = hasY ? y + "px" : "", _Object$assign2[sideX] = hasX ? x + "px" : "", _Object$assign2.transform = "", _Object$assign2)); } function computeStyles(_ref5) { var state = _ref5.state, options = _ref5.options; var _options$gpuAccelerat = options.gpuAcceleration, gpuAcceleration = _options$gpuAccelerat === void 0 ? true : _options$gpuAccelerat, _options$adaptive = options.adaptive, adaptive = _options$adaptive === void 0 ? true : _options$adaptive, _options$roundOffsets = options.roundOffsets, roundOffsets = _options$roundOffsets === void 0 ? true : _options$roundOffsets; if (true) { var transitionProperty = getComputedStyle(state.elements.popper).transitionProperty || ""; if (adaptive && ["transform", "top", "right", "bottom", "left"].some(function(property) { return transitionProperty.indexOf(property) >= 0; })) { console.warn(["Popper: Detected CSS transitions on at least one of the following", 'CSS properties: "transform", "top", "right", "bottom", "left".', "\n\n", 'Disable the "computeStyles" modifier\'s `adaptive` option to allow', "for smooth transitions, or remove these properties from the CSS", "transition declaration on the popper element if only transitioning", "opacity or background-color for example.", "\n\n", "We recommend using the popper element as a wrapper around an inner", "element that can have any CSS property transitioned for animations."].join(" ")); } } var commonStyles = { placement: getBasePlacement(state.placement), variation: getVariation(state.placement), popper: state.elements.popper, popperRect: state.rects.popper, gpuAcceleration, isFixed: state.options.strategy === "fixed" }; if (state.modifiersData.popperOffsets != null) { state.styles.popper = Object.assign({}, state.styles.popper, mapToStyles(Object.assign({}, commonStyles, { offsets: state.modifiersData.popperOffsets, position: state.options.strategy, adaptive, roundOffsets }))); } if (state.modifiersData.arrow != null) { state.styles.arrow = Object.assign({}, state.styles.arrow, mapToStyles(Object.assign({}, commonStyles, { offsets: state.modifiersData.arrow, position: "absolute", adaptive: false, roundOffsets }))); } state.attributes.popper = Object.assign({}, state.attributes.popper, { "data-popper-placement": state.placement }); } var computeStyles_default = { name: "computeStyles", enabled: true, phase: "beforeWrite", fn: computeStyles, data: {} }; // node_modules/@popperjs/core/lib/modifiers/eventListeners.js var passive = { passive: true }; function effect3(_ref) { var state = _ref.state, instance = _ref.instance, options = _ref.options; var _options$scroll = options.scroll, scroll = _options$scroll === void 0 ? true : _options$scroll, _options$resize = options.resize, resize = _options$resize === void 0 ? true : _options$resize; var window2 = getWindow(state.elements.popper); var scrollParents = [].concat(state.scrollParents.reference, state.scrollParents.popper); if (scroll) { scrollParents.forEach(function(scrollParent) { scrollParent.addEventListener("scroll", instance.update, passive); }); } if (resize) { window2.addEventListener("resize", instance.update, passive); } return function() { if (scroll) { scrollParents.forEach(function(scrollParent) { scrollParent.removeEventListener("scroll", instance.update, passive); }); } if (resize) { window2.removeEventListener("resize", instance.update, passive); } }; } var eventListeners_default = { name: "eventListeners", enabled: true, phase: "write", fn: function fn() { }, effect: effect3, data: {} }; // node_modules/@popperjs/core/lib/utils/getOppositePlacement.js var hash = { left: "right", right: "left", bottom: "top", top: "bottom" }; function getOppositePlacement(placement) { return placement.replace(/left|right|bottom|top/g, function(matched) { return hash[matched]; }); } // node_modules/@popperjs/core/lib/utils/getOppositeVariationPlacement.js var hash2 = { start: "end", end: "start" }; function getOppositeVariationPlacement(placement) { return placement.replace(/start|end/g, function(matched) { return hash2[matched]; }); } // node_modules/@popperjs/core/lib/dom-utils/getWindowScroll.js function getWindowScroll(node) { var win = getWindow(node); var scrollLeft = win.pageXOffset; var scrollTop = win.pageYOffset; return { scrollLeft, scrollTop }; } // node_modules/@popperjs/core/lib/dom-utils/getWindowScrollBarX.js function getWindowScrollBarX(element) { return getBoundingClientRect(getDocumentElement(element)).left + getWindowScroll(element).scrollLeft; } // node_modules/@popperjs/core/lib/dom-utils/getViewportRect.js function getViewportRect(element) { var win = getWindow(element); var html = getDocumentElement(element); var visualViewport = win.visualViewport; var width = html.clientWidth; var height = html.clientHeight; var x = 0; var y = 0; if (visualViewport) { width = visualViewport.width; height = visualViewport.height; if (!/^((?!chrome|android).)*safari/i.test(navigator.userAgent)) { x = visualViewport.offsetLeft; y = visualViewport.offsetTop; } } return { width, height, x: x + getWindowScrollBarX(element), y }; } // node_modules/@popperjs/core/lib/dom-utils/getDocumentRect.js function getDocumentRect(element) { var _element$ownerDocumen; var html = getDocumentElement(element); var winScroll = getWindowScroll(element); var body = (_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body; var width = max(html.scrollWidth, html.clientWidth, body ? body.scrollWidth : 0, body ? body.clientWidth : 0); var height = max(html.scrollHeight, html.clientHeight, body ? body.scrollHeight : 0, body ? body.clientHeight : 0); var x = -winScroll.scrollLeft + getWindowScrollBarX(element); var y = -winScroll.scrollTop; if (getComputedStyle(body || html).direction === "rtl") { x += max(html.clientWidth, body ? body.clientWidth : 0) - width; } return { width, height, x, y }; } // node_modules/@popperjs/core/lib/dom-utils/isScrollParent.js function isScrollParent(element) { var _getComputedStyle = getComputedStyle(element), overflow = _getComputedStyle.overflow, overflowX = _getComputedStyle.overflowX, overflowY = _getComputedStyle.overflowY; return /auto|scroll|overlay|hidden/.test(overflow + overflowY + overflowX); } // node_modules/@popperjs/core/lib/dom-utils/getScrollParent.js function getScrollParent(node) { if (["html", "body", "#document"].indexOf(getNodeName(node)) >= 0) { return node.ownerDocument.body; } if (isHTMLElement(node) && isScrollParent(node)) { return node; } return getScrollParent(getParentNode(node)); } // node_modules/@popperjs/core/lib/dom-utils/listScrollParents.js function listScrollParents(element, list) { var _element$ownerDocumen; if (list === void 0) { list = []; } var scrollParent = getScrollParent(element); var isBody = scrollParent === ((_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body); var win = getWindow(scrollParent); var target = isBody ? [win].concat(win.visualViewport || [], isScrollParent(scrollParent) ? scrollParent : []) : scrollParent; var updatedList = list.concat(target); return isBody ? updatedList : updatedList.concat(listScrollParents(getParentNode(target))); } // node_modules/@popperjs/core/lib/utils/rectToClientRect.js function rectToClientRect(rect) { return Object.assign({}, rect, { left: rect.x, top: rect.y, right: rect.x + rect.width, bottom: rect.y + rect.height }); } // node_modules/@popperjs/core/lib/dom-utils/getClippingRect.js function getInnerBoundingClientRect(element) { var rect = getBoundingClientRect(element); rect.top = rect.top + element.clientTop; rect.left = rect.left + element.clientLeft; rect.bottom = rect.top + element.clientHeight; rect.right = rect.left + element.clientWidth; rect.width = element.clientWidth; rect.height = element.clientHeight; rect.x = rect.left; rect.y = rect.top; return rect; } function getClientRectFromMixedType(element, clippingParent) { return clippingParent === viewport ? rectToClientRect(getViewportRect(element)) : isElement(clippingParent) ? getInnerBoundingClientRect(clippingParent) : rectToClientRect(getDocumentRect(getDocumentElement(element))); } function getClippingParents(element) { var clippingParents2 = listScrollParents(getParentNode(element)); var canEscapeClipping = ["absolute", "fixed"].indexOf(getComputedStyle(element).position) >= 0; var clipperElement = canEscapeClipping && isHTMLElement(element) ? getOffsetParent(element) : element; if (!isElement(clipperElement)) { return []; } return clippingParents2.filter(function(clippingParent) { return isElement(clippingParent) && contains(clippingParent, clipperElement) && getNodeName(clippingParent) !== "body"; }); } function getClippingRect(element, boundary, rootBoundary) { var mainClippingParents = boundary === "clippingParents" ? getClippingParents(element) : [].concat(boundary); var clippingParents2 = [].concat(mainClippingParents, [rootBoundary]); var firstClippingParent = clippingParents2[0]; var clippingRect = clippingParents2.reduce(function(accRect, clippingParent) { var rect = getClientRectFromMixedType(element, clippingParent); accRect.top = max(rect.top, accRect.top); accRect.right = min(rect.right, accRect.right); accRect.bottom = min(rect.bottom, accRect.bottom); accRect.left = max(rect.left, accRect.left); return accRect; }, getClientRectFromMixedType(element, firstClippingParent)); clippingRect.width = clippingRect.right - clippingRect.left; clippingRect.height = clippingRect.bottom - clippingRect.top; clippingRect.x = clippingRect.left; clippingRect.y = clippingRect.top; return clippingRect; } // node_modules/@popperjs/core/lib/utils/computeOffsets.js function computeOffsets(_ref) { var reference2 = _ref.reference, element = _ref.element, placement = _ref.placement; var basePlacement = placement ? getBasePlacement(placement) : null; var variation = placement ? getVariation(placement) : null; var commonX = reference2.x + reference2.width / 2 - element.width / 2; var commonY = reference2.y + reference2.height / 2 - element.height / 2; var offsets; switch (basePlacement) { case top: offsets = { x: commonX, y: reference2.y - element.height }; break; case bottom: offsets = { x: commonX, y: reference2.y + reference2.height }; break; case right: offsets = { x: reference2.x + reference2.width, y: commonY }; break; case left: offsets = { x: reference2.x - element.width, y: commonY }; break; default: offsets = { x: reference2.x, y: reference2.y }; } var mainAxis = basePlacement ? getMainAxisFromPlacement(basePlacement) : null; if (mainAxis != null) { var len = mainAxis === "y" ? "height" : "width"; switch (variation) { case start: offsets[mainAxis] = offsets[mainAxis] - (reference2[len] / 2 - element[len] / 2); break; case end: offsets[mainAxis] = offsets[mainAxis] + (reference2[len] / 2 - element[len] / 2); break; default: } } return offsets; } // node_modules/@popperjs/core/lib/utils/detectOverflow.js function detectOverflow(state, options) { if (options === void 0) { options = {}; } var _options = options, _options$placement = _options.placement, placement = _options$placement === void 0 ? state.placement : _options$placement, _options$boundary = _options.boundary, boundary = _options$boundary === void 0 ? clippingParents : _options$boundary, _options$rootBoundary = _options.rootBoundary, rootBoundary = _options$rootBoundary === void 0 ? viewport : _options$rootBoundary, _options$elementConte = _options.elementContext, elementContext = _options$elementConte === void 0 ? popper : _options$elementConte, _options$altBoundary = _options.altBoundary, altBoundary = _options$altBoundary === void 0 ? false : _options$altBoundary, _options$padding = _options.padding, padding = _options$padding === void 0 ? 0 : _options$padding; var paddingObject = mergePaddingObject(typeof padding !== "number" ? padding : expandToHashMap(padding, basePlacements)); var altContext = elementContext === popper ? reference : popper; var popperRect = state.rects.popper; var element = state.elements[altBoundary ? altContext : elementContext]; var clippingClientRect = getClippingRect(isElement(element) ? element : element.contextElement || getDocumentElement(state.elements.popper), boundary, rootBoundary); var referenceClientRect = getBoundingClientRect(state.elements.reference); var popperOffsets2 = computeOffsets({ reference: referenceClientRect, element: popperRect, strategy: "absolute", placement }); var popperClientRect = rectToClientRect(Object.assign({}, popperRect, popperOffsets2)); var elementClientRect = elementContext === popper ? popperClientRect : referenceClientRect; var overflowOffsets = { top: clippingClientRect.top - elementClientRect.top + paddingObject.top, bottom: elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom, left: clippingClientRect.left - elementClientRect.left + paddingObject.left, right: elementClientRect.right - clippingClientRect.right + paddingObject.right }; var offsetData = state.modifiersData.offset; if (elementContext === popper && offsetData) { var offset2 = offsetData[placement]; Object.keys(overflowOffsets).forEach(function(key) { var multiply = [right, bottom].indexOf(key) >= 0 ? 1 : -1; var axis = [top, bottom].indexOf(key) >= 0 ? "y" : "x"; overflowOffsets[key] += offset2[axis] * multiply; }); } return overflowOffsets; } // node_modules/@popperjs/core/lib/utils/computeAutoPlacement.js function computeAutoPlacement(state, options) { if (options === void 0) { options = {}; } var _options = options, placement = _options.placement, boundary = _options.boundary, rootBoundary = _options.rootBoundary, padding = _options.padding, flipVariations = _options.flipVariations, _options$allowedAutoP = _options.allowedAutoPlacements, allowedAutoPlacements = _options$allowedAutoP === void 0 ? placements : _options$allowedAutoP; var variation = getVariation(placement); var placements2 = variation ? flipVariations ? variationPlacements : variationPlacements.filter(function(placement2) { return getVariation(placement2) === variation; }) : basePlacements; var allowedPlacements = placements2.filter(function(placement2) { return allowedAutoPlacements.indexOf(placement2) >= 0; }); if (allowedPlacements.length === 0) { allowedPlacements = placements2; if (true) { console.error(["Popper: The `allowedAutoPlacements` option did not allow any", "placements. Ensure the `placement` option matches the variation", "of the allowed placements.", 'For example, "auto" cannot be used to allow "bottom-start".', 'Use "auto-start" instead.'].join(" ")); } } var overflows = allowedPlacements.reduce(function(acc, placement2) { acc[placement2] = detectOverflow(state, { placement: placement2, boundary, rootBoundary, padding })[getBasePlacement(placement2)]; return acc; }, {}); return Object.keys(overflows).sort(function(a, b) { return overflows[a] - overflows[b]; }); } // node_modules/@popperjs/core/lib/modifiers/flip.js function getExpandedFallbackPlacements(placement) { if (getBasePlacement(placement) === auto) { return []; } var oppositePlacement = getOppositePlacement(placement); return [getOppositeVariationPlacement(placement), oppositePlacement, getOppositeVariationPlacement(oppositePlacement)]; } function flip(_ref) { var state = _ref.state, options = _ref.options, name = _ref.name; if (state.modifiersData[name]._skip) { return; } var _options$mainAxis = options.mainAxis, checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis, _options$altAxis = options.altAxis, checkAltAxis = _options$altAxis === void 0 ? true : _options$altAxis, specifiedFallbackPlacements = options.fallbackPlacements, padding = options.padding, boundary = options.boundary, rootBoundary = options.rootBoundary, altBoundary = options.altBoundary, _options$flipVariatio = options.flipVariations, flipVariations = _options$flipVariatio === void 0 ? true : _options$flipVariatio, allowedAutoPlacements = options.allowedAutoPlacements; var preferredPlacement = state.options.placement; var basePlacement = getBasePlacement(preferredPlacement); var isBasePlacement = basePlacement === preferredPlacement; var fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipVariations ? [getOppositePlacement(preferredPlacement)] : getExpandedFallbackPlacements(preferredPlacement)); var placements2 = [preferredPlacement].concat(fallbackPlacements).reduce(function(acc, placement2) { return acc.concat(getBasePlacement(placement2) === auto ? computeAutoPlacement(state, { placement: placement2, boundary, rootBoundary, padding, flipVariations, allowedAutoPlacements }) : placement2); }, []); var referenceRect = state.rects.reference; var popperRect = state.rects.popper; var checksMap = new Map(); var makeFallbackChecks = true; var firstFittingPlacement = placements2[0]; for (var i = 0; i < placements2.length; i++) { var placement = placements2[i]; var _basePlacement = getBasePlacement(placement); var isStartVariation = getVariation(placement) === start; var isVertical = [top, bottom].indexOf(_basePlacement) >= 0; var len = isVertical ? "width" : "height"; var overflow = detectOverflow(state, { placement, boundary, rootBoundary, altBoundary, padding }); var mainVariationSide = isVertical ? isStartVariation ? right : left : isStartVariation ? bottom : top; if (referenceRect[len] > popperRect[len]) { mainVariationSide = getOppositePlacement(mainVariationSide); } var altVariationSide = getOppositePlacement(mainVariationSide); var checks = []; if (checkMainAxis) { checks.push(overflow[_basePlacement] <= 0); } if (checkAltAxis) { checks.push(overflow[mainVariationSide] <= 0, overflow[altVariationSide] <= 0); } if (checks.every(function(check) { return check; })) { firstFittingPlacement = placement; makeFallbackChecks = false; break; } checksMap.set(placement, checks); } if (makeFallbackChecks) { var numberOfChecks = flipVariations ? 3 : 1; var _loop = function _loop2(_i2) { var fittingPlacement = placements2.find(function(placement2) { var checks2 = checksMap.get(placement2); if (checks2) { return checks2.slice(0, _i2).every(function(check) { return check; }); } }); if (fittingPlacement) { firstFittingPlacement = fittingPlacement; return "break"; } }; for (var _i = numberOfChecks; _i > 0; _i--) { var _ret = _loop(_i); if (_ret === "break") break; } } if (state.placement !== firstFittingPlacement) { state.modifiersData[name]._skip = true; state.placement = firstFittingPlacement; state.reset = true; } } var flip_default = { name: "flip", enabled: true, phase: "main", fn: flip, requiresIfExists: ["offset"], data: { _skip: false } }; // node_modules/@popperjs/core/lib/modifiers/hide.js function getSideOffsets(overflow, rect, preventedOffsets) { if (preventedOffsets === void 0) { preventedOffsets = { x: 0, y: 0 }; } return { top: overflow.top - rect.height - preventedOffsets.y, right: overflow.right - rect.width + preventedOffsets.x, bottom: overflow.bottom - rect.height + preventedOffsets.y, left: overflow.left - rect.width - preventedOffsets.x }; } function isAnySideFullyClipped(overflow) { return [top, right, bottom, left].some(function(side) { return overflow[side] >= 0; }); } function hide(_ref) { var state = _ref.state, name = _ref.name; var referenceRect = state.rects.reference; var popperRect = state.rects.popper; var preventedOffsets = state.modifiersData.preventOverflow; var referenceOverflow = detectOverflow(state, { elementContext: "reference" }); var popperAltOverflow = detectOverflow(state, { altBoundary: true }); var referenceClippingOffsets = getSideOffsets(referenceOverflow, referenceRect); var popperEscapeOffsets = getSideOffsets(popperAltOverflow, popperRect, preventedOffsets); var isReferenceHidden = isAnySideFullyClipped(referenceClippingOffsets); var hasPopperEscaped = isAnySideFullyClipped(popperEscapeOffsets); state.modifiersData[name] = { referenceClippingOffsets, popperEscapeOffsets, isReferenceHidden, hasPopperEscaped }; state.attributes.popper = Object.assign({}, state.attributes.popper, { "data-popper-reference-hidden": isReferenceHidden, "data-popper-escaped": hasPopperEscaped }); } var hide_default = { name: "hide", enabled: true, phase: "main", requiresIfExists: ["preventOverflow"], fn: hide }; // node_modules/@popperjs/core/lib/modifiers/offset.js function distanceAndSkiddingToXY(placement, rects, offset2) { var basePlacement = getBasePlacement(placement); var invertDistance = [left, top].indexOf(basePlacement) >= 0 ? -1 : 1; var _ref = typeof offset2 === "function" ? offset2(Object.assign({}, rects, { placement })) : offset2, skidding = _ref[0], distance = _ref[1]; skidding = skidding || 0; distance = (distance || 0) * invertDistance; return [left, right].indexOf(basePlacement) >= 0 ? { x: distance, y: skidding } : { x: skidding, y: distance }; } function offset(_ref2) { var state = _ref2.state, options = _ref2.options, name = _ref2.name; var _options$offset = options.offset, offset2 = _options$offset === void 0 ? [0, 0] : _options$offset; var data = placements.reduce(function(acc, placement) { acc[placement] = distanceAndSkiddingToXY(placement, state.rects, offset2); return acc; }, {}); var _data$state$placement = data[state.placement], x = _data$state$placement.x, y = _data$state$placement.y; if (state.modifiersData.popperOffsets != null) { state.modifiersData.popperOffsets.x += x; state.modifiersData.popperOffsets.y += y; } state.modifiersData[name] = data; } var offset_default = { name: "offset", enabled: true, phase: "main", requires: ["popperOffsets"], fn: offset }; // node_modules/@popperjs/core/lib/modifiers/popperOffsets.js function popperOffsets(_ref) { var state = _ref.state, name = _ref.name; state.modifiersData[name] = computeOffsets({ reference: state.rects.reference, element: state.rects.popper, strategy: "absolute", placement: state.placement }); } var popperOffsets_default = { name: "popperOffsets", enabled: true, phase: "read", fn: popperOffsets, data: {} }; // node_modules/@popperjs/core/lib/utils/getAltAxis.js function getAltAxis(axis) { return axis === "x" ? "y" : "x"; } // node_modules/@popperjs/core/lib/modifiers/preventOverflow.js function preventOverflow(_ref) { var state = _ref.state, options = _ref.options, name = _ref.name; var _options$mainAxis = options.mainAxis, checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis, _options$altAxis = options.altAxis, checkAltAxis = _options$altAxis === void 0 ? false : _options$altAxis, boundary = options.boundary, rootBoundary = options.rootBoundary, altBoundary = options.altBoundary, padding = options.padding, _options$tether = options.tether, tether = _options$tether === void 0 ? true : _options$tether, _options$tetherOffset = options.tetherOffset, tetherOffset = _options$tetherOffset === void 0 ? 0 : _options$tetherOffset; var overflow = detectOverflow(state, { boundary, rootBoundary, padding, altBoundary }); var basePlacement = getBasePlacement(state.placement); var variation = getVariation(state.placement); var isBasePlacement = !variation; var mainAxis = getMainAxisFromPlacement(basePlacement); var altAxis = getAltAxis(mainAxis); var popperOffsets2 = state.modifiersData.popperOffsets; var referenceRect = state.rects.reference; var popperRect = state.rects.popper; var tetherOffsetValue = typeof tetherOffset === "function" ? tetherOffset(Object.assign({}, state.rects, { placement: state.placement })) : tetherOffset; var normalizedTetherOffsetValue = typeof tetherOffsetValue === "number" ? { mainAxis: tetherOffsetValue, altAxis: tetherOffsetValue } : Object.assign({ mainAxis: 0, altAxis: 0 }, tetherOffsetValue); var offsetModifierState = state.modifiersData.offset ? state.modifiersData.offset[state.placement] : null; var data = { x: 0, y: 0 }; if (!popperOffsets2) { return; } if (checkMainAxis) { var _offsetModifierState$; var mainSide = mainAxis === "y" ? top : left; var altSide = mainAxis === "y" ? bottom : right; var len = mainAxis === "y" ? "height" : "width"; var offset2 = popperOffsets2[mainAxis]; var min2 = offset2 + overflow[mainSide]; var max2 = offset2 - overflow[altSide]; var additive = tether ? -popperRect[len] / 2 : 0; var minLen = variation === start ? referenceRect[len] : popperRect[len]; var maxLen = variation === start ? -popperRect[len] : -referenceRect[len]; var arrowElement = state.elements.arrow; var arrowRect = tether && arrowElement ? getLayoutRect(arrowElement) : { width: 0, height: 0 }; var arrowPaddingObject = state.modifiersData["arrow#persistent"] ? state.modifiersData["arrow#persistent"].padding : getFreshSideObject(); var arrowPaddingMin = arrowPaddingObject[mainSide]; var arrowPaddingMax = arrowPaddingObject[altSide]; var arrowLen = within(0, referenceRect[len], arrowRect[len]); var minOffset = isBasePlacement ? referenceRect[len] / 2 - additive - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis : minLen - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis; var maxOffset = isBasePlacement ? -referenceRect[len] / 2 + additive + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis : maxLen + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis; var arrowOffsetParent = state.elements.arrow && getOffsetParent(state.elements.arrow); var clientOffset = arrowOffsetParent ? mainAxis === "y" ? arrowOffsetParent.clientTop || 0 : arrowOffsetParent.clientLeft || 0 : 0; var offsetModifierValue = (_offsetModifierState$ = offsetModifierState == null ? void 0 : offsetModifierState[mainAxis]) != null ? _offsetModifierState$ : 0; var tetherMin = offset2 + minOffset - offsetModifierValue - clientOffset; var tetherMax = offset2 + maxOffset - offsetModifierValue; var preventedOffset = within(tether ? min(min2, tetherMin) : min2, offset2, tether ? max(max2, tetherMax) : max2); popperOffsets2[mainAxis] = preventedOffset; data[mainAxis] = preventedOffset - offset2; } if (checkAltAxis) { var _offsetModifierState$2; var _mainSide = mainAxis === "x" ? top : left; var _altSide = mainAxis === "x" ? bottom : right; var _offset = popperOffsets2[altAxis]; var _len = altAxis === "y" ? "height" : "width"; var _min = _offset + overflow[_mainSide]; var _max = _offset - overflow[_altSide]; var isOriginSide = [top, left].indexOf(basePlacement) !== -1; var _offsetModifierValue = (_offsetModifierState$2 = offsetModifierState == null ? void 0 : offsetModifierState[altAxis]) != null ? _offsetModifierState$2 : 0; var _tetherMin = isOriginSide ? _min : _offset - referenceRect[_len] - popperRect[_len] - _offsetModifierValue + normalizedTetherOffsetValue.altAxis; var _tetherMax = isOriginSide ? _offset + referenceRect[_len] + popperRect[_len] - _offsetModifierValue - normalizedTetherOffsetValue.altAxis : _max; var _preventedOffset = tether && isOriginSide ? withinMaxClamp(_tetherMin, _offset, _tetherMax) : within(tether ? _tetherMin : _min, _offset, tether ? _tetherMax : _max); popperOffsets2[altAxis] = _preventedOffset; data[altAxis] = _preventedOffset - _offset; } state.modifiersData[name] = data; } var preventOverflow_default = { name: "preventOverflow", enabled: true, phase: "main", fn: preventOverflow, requiresIfExists: ["offset"] }; // node_modules/@popperjs/core/lib/dom-utils/getHTMLElementScroll.js function getHTMLElementScroll(element) { return { scrollLeft: element.scrollLeft, scrollTop: element.scrollTop }; } // node_modules/@popperjs/core/lib/dom-utils/getNodeScroll.js function getNodeScroll(node) { if (node === getWindow(node) || !isHTMLElement(node)) { return getWindowScroll(node); } else { return getHTMLElementScroll(node); } } // node_modules/@popperjs/core/lib/dom-utils/getCompositeRect.js function isElementScaled(element) { var rect = element.getBoundingClientRect(); var scaleX = round(rect.width) / element.offsetWidth || 1; var scaleY = round(rect.height) / element.offsetHeight || 1; return scaleX !== 1 || scaleY !== 1; } function getCompositeRect(elementOrVirtualElement, offsetParent, isFixed) { if (isFixed === void 0) { isFixed = false; } var isOffsetParentAnElement = isHTMLElement(offsetParent); var offsetParentIsScaled = isHTMLElement(offsetParent) && isElementScaled(offsetParent); var documentElement = getDocumentElement(offsetParent); var rect = getBoundingClientRect(elementOrVirtualElement, offsetParentIsScaled); var scroll = { scrollLeft: 0, scrollTop: 0 }; var offsets = { x: 0, y: 0 }; if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) { if (getNodeName(offsetParent) !== "body" || isScrollParent(documentElement)) { scroll = getNodeScroll(offsetParent); } if (isHTMLElement(offsetParent)) { offsets = getBoundingClientRect(offsetParent, true); offsets.x += offsetParent.clientLeft; offsets.y += offsetParent.clientTop; } else if (documentElement) { offsets.x = getWindowScrollBarX(documentElement); } } return { x: rect.left + scroll.scrollLeft - offsets.x, y: rect.top + scroll.scrollTop - offsets.y, width: rect.width, height: rect.height }; } // node_modules/@popperjs/core/lib/utils/orderModifiers.js function order(modifiers) { var map = new Map(); var visited = new Set(); var result = []; modifiers.forEach(function(modifier) { map.set(modifier.name, modifier); }); function sort(modifier) { visited.add(modifier.name); var requires = [].concat(modifier.requires || [], modifier.requiresIfExists || []); requires.forEach(function(dep) { if (!visited.has(dep)) { var depModifier = map.get(dep); if (depModifier) { sort(depModifier); } } }); result.push(modifier); } modifiers.forEach(function(modifier) { if (!visited.has(modifier.name)) { sort(modifier); } }); return result; } function orderModifiers(modifiers) { var orderedModifiers = order(modifiers); return modifierPhases.reduce(function(acc, phase) { return acc.concat(orderedModifiers.filter(function(modifier) { return modifier.phase === phase; })); }, []); } // node_modules/@popperjs/core/lib/utils/debounce.js function debounce(fn2) { var pending; return function() { if (!pending) { pending = new Promise(function(resolve) { Promise.resolve().then(function() { pending = void 0; resolve(fn2()); }); }); } return pending; }; } // node_modules/@popperjs/core/lib/utils/format.js function format(str) { for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { args[_key - 1] = arguments[_key]; } return [].concat(args).reduce(function(p, c) { return p.replace(/%s/, c); }, str); } // node_modules/@popperjs/core/lib/utils/validateModifiers.js var INVALID_MODIFIER_ERROR = 'Popper: modifier "%s" provided an invalid %s property, expected %s but got %s'; var MISSING_DEPENDENCY_ERROR = 'Popper: modifier "%s" requires "%s", but "%s" modifier is not available'; var VALID_PROPERTIES = ["name", "enabled", "phase", "fn", "effect", "requires", "options"]; function validateModifiers(modifiers) { modifiers.forEach(function(modifier) { [].concat(Object.keys(modifier), VALID_PROPERTIES).filter(function(value, index, self) { return self.indexOf(value) === index; }).forEach(function(key) { switch (key) { case "name": if (typeof modifier.name !== "string") { console.error(format(INVALID_MODIFIER_ERROR, String(modifier.name), '"name"', '"string"', '"' + String(modifier.name) + '"')); } break; case "enabled": if (typeof modifier.enabled !== "boolean") { console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"enabled"', '"boolean"', '"' + String(modifier.enabled) + '"')); } break; case "phase": if (modifierPhases.indexOf(modifier.phase) < 0) { console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"phase"', "either " + modifierPhases.join(", "), '"' + String(modifier.phase) + '"')); } break; case "fn": if (typeof modifier.fn !== "function") { console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"fn"', '"function"', '"' + String(modifier.fn) + '"')); } break; case "effect": if (modifier.effect != null && typeof modifier.effect !== "function") { console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"effect"', '"function"', '"' + String(modifier.fn) + '"')); } break; case "requires": if (modifier.requires != null && !Array.isArray(modifier.requires)) { console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"requires"', '"array"', '"' + String(modifier.requires) + '"')); } break; case "requiresIfExists": if (!Array.isArray(modifier.requiresIfExists)) { console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"requiresIfExists"', '"array"', '"' + String(modifier.requiresIfExists) + '"')); } break; case "options": case "data": break; default: console.error('PopperJS: an invalid property has been provided to the "' + modifier.name + '" modifier, valid properties are ' + VALID_PROPERTIES.map(function(s) { return '"' + s + '"'; }).join(", ") + '; but "' + key + '" was provided.'); } modifier.requires && modifier.requires.forEach(function(requirement) { if (modifiers.find(function(mod) { return mod.name === requirement; }) == null) { console.error(format(MISSING_DEPENDENCY_ERROR, String(modifier.name), requirement, requirement)); } }); }); }); } // node_modules/@popperjs/core/lib/utils/uniqueBy.js function uniqueBy(arr, fn2) { var identifiers = new Set(); return arr.filter(function(item) { var identifier = fn2(item); if (!identifiers.has(identifier)) { identifiers.add(identifier); return true; } }); } // node_modules/@popperjs/core/lib/utils/mergeByName.js function mergeByName(modifiers) { var merged = modifiers.reduce(function(merged2, current) { var existing = merged2[current.name]; merged2[current.name] = existing ? Object.assign({}, existing, current, { options: Object.assign({}, existing.options, current.options), data: Object.assign({}, existing.data, current.data) }) : current; return merged2; }, {}); return Object.keys(merged).map(function(key) { return merged[key]; }); } // node_modules/@popperjs/core/lib/createPopper.js var INVALID_ELEMENT_ERROR = "Popper: Invalid reference or popper argument provided. They must be either a DOM element or virtual element."; var INFINITE_LOOP_ERROR = "Popper: An infinite loop in the modifiers cycle has been detected! The cycle has been interrupted to prevent a browser crash."; var DEFAULT_OPTIONS = { placement: "bottom", modifiers: [], strategy: "absolute" }; function areValidElements() { for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } return !args.some(function(element) { return !(element && typeof element.getBoundingClientRect === "function"); }); } function popperGenerator(generatorOptions) { if (generatorOptions === void 0) { generatorOptions = {}; } var _generatorOptions = generatorOptions, _generatorOptions$def = _generatorOptions.defaultModifiers, defaultModifiers2 = _generatorOptions$def === void 0 ? [] : _generatorOptions$def, _generatorOptions$def2 = _generatorOptions.defaultOptions, defaultOptions = _generatorOptions$def2 === void 0 ? DEFAULT_OPTIONS : _generatorOptions$def2; return function createPopper2(reference2, popper2, options) { if (options === void 0) { options = defaultOptions; } var state = { placement: "bottom", orderedModifiers: [], options: Object.assign({}, DEFAULT_OPTIONS, defaultOptions), modifiersData: {}, elements: { reference: reference2, popper: popper2 }, attributes: {}, styles: {} }; var effectCleanupFns = []; var isDestroyed = false; var instance = { state, setOptions: function setOptions(setOptionsAction) { var options2 = typeof setOptionsAction === "function" ? setOptionsAction(state.options) : setOptionsAction; cleanupModifierEffects(); state.options = Object.assign({}, defaultOptions, state.options, options2); state.scrollParents = { reference: isElement(reference2) ? listScrollParents(reference2) : reference2.contextElement ? listScrollParents(reference2.contextElement) : [], popper: listScrollParents(popper2) }; var orderedModifiers = orderModifiers(mergeByName([].concat(defaultModifiers2, state.options.modifiers))); state.orderedModifiers = orderedModifiers.filter(function(m) { return m.enabled; }); if (true) { var modifiers = uniqueBy([].concat(orderedModifiers, state.options.modifiers), function(_ref) { var name = _ref.name; return name; }); validateModifiers(modifiers); if (getBasePlacement(state.options.placement) === auto) { var flipModifier = state.orderedModifiers.find(function(_ref2) { var name = _ref2.name; return name === "flip"; }); if (!flipModifier) { console.error(['Popper: "auto" placements require the "flip" modifier be', "present and enabled to work."].join(" ")); } } var _getComputedStyle = getComputedStyle(popper2), marginTop = _getComputedStyle.marginTop, marginRight = _getComputedStyle.marginRight, marginBottom = _getComputedStyle.marginBottom, marginLeft = _getComputedStyle.marginLeft; if ([marginTop, marginRight, marginBottom, marginLeft].some(function(margin) { return parseFloat(margin); })) { console.warn(['Popper: CSS "margin" styles cannot be used to apply padding', "between the popper and its reference element or boundary.", "To replicate margin, use the `offset` modifier, as well as", "the `padding` option in the `preventOverflow` and `flip`", "modifiers."].join(" ")); } } runModifierEffects(); return instance.update(); }, forceUpdate: function forceUpdate() { if (isDestroyed) { return; } var _state$elements = state.elements, reference3 = _state$elements.reference, popper3 = _state$elements.popper; if (!areValidElements(reference3, popper3)) { if (true) { console.error(INVALID_ELEMENT_ERROR); } return; } state.rects = { reference: getCompositeRect(reference3, getOffsetParent(popper3), state.options.strategy === "fixed"), popper: getLayoutRect(popper3) }; state.reset = false; state.placement = state.options.placement; state.orderedModifiers.forEach(function(modifier) { return state.modifiersData[modifier.name] = Object.assign({}, modifier.data); }); var __debug_loops__ = 0; for (var index = 0; index < state.orderedModifiers.length; index++) { if (true) { __debug_loops__ += 1; if (__debug_loops__ > 100) { console.error(INFINITE_LOOP_ERROR); break; } } if (state.reset === true) { state.reset = false; index = -1; continue; } var _state$orderedModifie = state.orderedModifiers[index], fn2 = _state$orderedModifie.fn, _state$orderedModifie2 = _state$orderedModifie.options, _options = _state$orderedModifie2 === void 0 ? {} : _state$orderedModifie2, name = _state$orderedModifie.name; if (typeof fn2 === "function") { state = fn2({ state, options: _options, name, instance }) || state; } } }, update: debounce(function() { return new Promise(function(resolve) { instance.forceUpdate(); resolve(state); }); }), destroy: function destroy() { cleanupModifierEffects(); isDestroyed = true; } }; if (!areValidElements(reference2, popper2)) { if (true) { console.error(INVALID_ELEMENT_ERROR); } return instance; } instance.setOptions(options).then(function(state2) { if (!isDestroyed && options.onFirstUpdate) { options.onFirstUpdate(state2); } }); function runModifierEffects() { state.orderedModifiers.forEach(function(_ref3) { var name = _ref3.name, _ref3$options = _ref3.options, options2 = _ref3$options === void 0 ? {} : _ref3$options, effect4 = _ref3.effect; if (typeof effect4 === "function") { var cleanupFn = effect4({ state, name, instance, options: options2 }); var noopFn = function noopFn2() { }; effectCleanupFns.push(cleanupFn || noopFn); } }); } function cleanupModifierEffects() { effectCleanupFns.forEach(function(fn2) { return fn2(); }); effectCleanupFns = []; } return instance; }; } // node_modules/@popperjs/core/lib/popper.js var defaultModifiers = [eventListeners_default, popperOffsets_default, computeStyles_default, applyStyles_default, offset_default, flip_default, preventOverflow_default, arrow_default, hide_default]; var createPopper = /* @__PURE__ */ popperGenerator({ defaultModifiers }); // src/utils/Utils.ts var pluginName = "obsidian-media-db-plugin"; var contactEmail = "m.projects.code@gmail.com"; var mediaDbTag = "mediaDB"; var mediaDbVersion = "0.2.0"; var debug = false; function wrapAround(value, size) { return (value % size + size) % size; } function debugLog(o) { if (debug) { console.log(o); } } function containsOnlyLettersAndUnderscores(str) { return /^[a-zA-Z_]+$/.test(str); } function replaceIllegalFileNameCharactersInString(string) { return string.replace(/[\\,#%&{}/*<>$"@.?]*/g, "").replace(/:+/g, " -"); } function replaceTags(template, mediaTypeModel) { const resolvedTemplate = template.replace(new RegExp("{{.*?}}", "g"), (match) => replaceTag(match, mediaTypeModel)); return resolvedTemplate; } function replaceTag(match, mediaTypeModel) { let tag = match; tag = tag.substring(2); tag = tag.substring(0, tag.length - 2); tag = tag.trim(); let parts = tag.split(":"); if (parts.length === 1) { let path = parts[0].split("."); let obj = traverseMetaData(path, mediaTypeModel); if (obj === void 0) { return "{{ INVALID TEMPLATE TAG - object undefined }}"; } return obj; } else if (parts.length === 2) { let operator = parts[0]; let path = parts[1].split("."); let obj = traverseMetaData(path, mediaTypeModel); if (obj === void 0) { return "{{ INVALID TEMPLATE TAG - object undefined }}"; } if (operator === "LIST") { if (!Array.isArray(obj)) { return "{{ INVALID TEMPLATE TAG - operator LIST is only applicable on an array }}"; } return obj.map((e) => `- ${e}`).join("\n"); } else if (operator === "ENUM") { if (!Array.isArray(obj)) { return "{{ INVALID TEMPLATE TAG - operator ENUM is only applicable on an array }}"; } return obj.join(", "); } return `{{ INVALID TEMPLATE TAG - unknown operator ${operator} }}`; } return "{{ INVALID TEMPLATE TAG }}"; } function traverseMetaData(path, mediaTypeModel) { let o = mediaTypeModel; for (let part of path) { if (o !== void 0) { o = o[part]; } } return o; } // src/settings/suggesters/Suggest.ts var Suggest = class { constructor(owner, containerEl, scope) { this.owner = owner; this.containerEl = containerEl; containerEl.on("click", ".suggestion-item", this.onSuggestionClick.bind(this)); containerEl.on("mousemove", ".suggestion-item", this.onSuggestionMouseover.bind(this)); scope.register([], "ArrowUp", (event) => { if (!event.isComposing) { this.setSelectedItem(this.selectedItem - 1, true); return false; } }); scope.register([], "ArrowDown", (event) => { if (!event.isComposing) { this.setSelectedItem(this.selectedItem + 1, true); return false; } }); scope.register([], "Enter", (event) => { if (!event.isComposing) { this.useSelectedItem(event); return false; } }); } onSuggestionClick(event, el) { event.preventDefault(); const item = this.suggestions.indexOf(el); this.setSelectedItem(item, false); this.useSelectedItem(event); } onSuggestionMouseover(_event, el) { const item = this.suggestions.indexOf(el); this.setSelectedItem(item, false); } setSuggestions(values) { this.containerEl.empty(); const suggestionEls = []; values.forEach((value) => { const suggestionEl = this.containerEl.createDiv("suggestion-item"); this.owner.renderSuggestion(value, suggestionEl); suggestionEls.push(suggestionEl); }); this.values = values; this.suggestions = suggestionEls; this.setSelectedItem(0, false); } useSelectedItem(event) { const currentValue = this.values[this.selectedItem]; if (currentValue) { this.owner.selectSuggestion(currentValue, event); } } setSelectedItem(selectedIndex, scrollIntoView) { const normalizedIndex = wrapAround(selectedIndex, this.suggestions.length); const prevSelectedSuggestion = this.suggestions[this.selectedItem]; const selectedSuggestion = this.suggestions[normalizedIndex]; prevSelectedSuggestion == null ? void 0 : prevSelectedSuggestion.removeClass("is-selected"); selectedSuggestion == null ? void 0 : selectedSuggestion.addClass("is-selected"); this.selectedItem = normalizedIndex; if (scrollIntoView) { selectedSuggestion.scrollIntoView(false); } } }; var TextInputSuggest = class { constructor(app, inputEl) { this.app = app; this.inputEl = inputEl; this.scope = new import_obsidian.Scope(); this.suggestEl = createDiv("suggestion-container"); const suggestion = this.suggestEl.createDiv("suggestion"); this.suggest = new Suggest(this, suggestion, this.scope); this.scope.register([], "Escape", this.close.bind(this)); this.inputEl.addEventListener("input", this.onInputChanged.bind(this)); this.inputEl.addEventListener("focus", this.onInputChanged.bind(this)); this.inputEl.addEventListener("blur", this.close.bind(this)); this.suggestEl.on("mousedown", ".suggestion-container", (event) => { event.preventDefault(); }); } onInputChanged() { const inputStr = this.inputEl.value; const suggestions = this.getSuggestions(inputStr); if (suggestions.length > 0) { this.suggest.setSuggestions(suggestions); this.open(this.app.dom.appContainerEl, this.inputEl); } } open(container, inputEl) { this.app.keymap.pushScope(this.scope); container.appendChild(this.suggestEl); this.popper = createPopper(inputEl, this.suggestEl, { placement: "bottom-start", modifiers: [ { name: "sameWidth", enabled: true, fn: ({ state, instance }) => { const targetWidth = `${state.rects.reference.width}px`; if (state.styles.popper.width === targetWidth) { return; } state.styles.popper.width = targetWidth; instance.update(); }, phase: "beforeWrite", requires: ["computeStyles"] } ] }); } close() { this.app.keymap.popScope(this.scope); this.suggest.setSuggestions([]); this.popper.destroy(); this.suggestEl.detach(); } }; // src/settings/suggesters/FolderSuggest.ts var FolderSuggest = class extends TextInputSuggest { getSuggestions(inputStr) { const abstractFiles = this.app.vault.getAllLoadedFiles(); const folders = []; const lowerCaseInputStr = inputStr.toLowerCase(); abstractFiles.forEach((folder) => { if (folder instanceof import_obsidian2.TFolder && folder.path.toLowerCase().contains(lowerCaseInputStr)) { folders.push(folder); } }); return folders; } renderSuggestion(file, el) { el.setText(file.path); } selectSuggestion(file) { this.inputEl.value = file.path; this.inputEl.trigger("input"); this.close(); } }; // src/settings/suggesters/FileSuggest.ts var import_obsidian3 = __toModule(require("obsidian")); var FileSuggest = class extends TextInputSuggest { getSuggestions(inputStr) { const abstractFiles = this.app.vault.getAllLoadedFiles(); const files = []; const lowerCaseInputStr = inputStr.toLowerCase(); abstractFiles.forEach((file) => { if (file instanceof import_obsidian3.TFile && file.name.toLowerCase().contains(lowerCaseInputStr)) { files.push(file); } }); return files; } renderSuggestion(file, el) { el.setText(file.name); } selectSuggestion(file) { this.inputEl.value = file.name; this.inputEl.trigger("input"); this.close(); } }; // src/settings/Settings.ts var DEFAULT_SETTINGS = { folder: "Media DB", sfwFilter: true, OMDbKey: "", movieTemplate: "", seriesTemplate: "", gameTemplate: "", wikiTemplate: "", musicReleaseTemplate: "", movieFileNameTemplate: "{{ title }} ({{ year }})", seriesFileNameTemplate: "{{ title }} ({{ year }})", gameFileNameTemplate: "{{ title }} ({{ year }})", wikiFileNameTemplate: "{{ title }}", musicReleaseFileNameTemplate: "{{ title }} (by {{ ENUM:artists }} - {{ year }})", moviePropertyConversionRules: "", seriesPropertyConversionRules: "", gamePropertyConversionRules: "", wikiPropertyConversionRules: "", musicReleasePropertyConversionRules: "", templates: true }; var MediaDbSettingTab = class extends import_obsidian4.PluginSettingTab { constructor(app, plugin) { super(app, plugin); this.plugin = plugin; } display() { const { containerEl } = this; containerEl.empty(); containerEl.createEl("h2", { text: "Media DB Plugin Settings" }); new import_obsidian4.Setting(containerEl).setName("New file location").setDesc("New media db entries will be placed here.").addSearch((cb) => { new FolderSuggest(this.app, cb.inputEl); cb.setPlaceholder("Example: folder1/folder2").setValue(this.plugin.settings.folder).onChange((data) => { this.plugin.settings.folder = data; this.plugin.saveSettings(); }); }); new import_obsidian4.Setting(containerEl).setName("OMDb API key").setDesc('API key for "www.omdbapi.com".').addText((cb) => { cb.setPlaceholder("API key").setValue(this.plugin.settings.OMDbKey).onChange((data) => { this.plugin.settings.OMDbKey = data; this.plugin.saveSettings(); }); }); new import_obsidian4.Setting(containerEl).setName("SFW filter").setDesc("Only shows SFW results for APIs that offer filtering.").addToggle((cb) => { cb.setValue(this.plugin.settings.sfwFilter).onChange((data) => { this.plugin.settings.sfwFilter = data; this.plugin.saveSettings(); }); }); new import_obsidian4.Setting(containerEl).setName("Resolve {{ tags }} in templates").setDesc("Whether to resolve {{ tags }} in templates. The spaces inside the curly braces are important.").addToggle((cb) => { cb.setValue(this.plugin.settings.templates).onChange((data) => { this.plugin.settings.templates = data; this.plugin.saveSettings(); }); }); containerEl.createEl("h3", { text: "Template Settings" }); new import_obsidian4.Setting(containerEl).setName("Movie template").setDesc("Template file to be used when creating a new note for a movie.").addSearch((cb) => { new FileSuggest(this.app, cb.inputEl); cb.setPlaceholder("Example: movieTemplate.md").setValue(this.plugin.settings.movieTemplate).onChange((data) => { this.plugin.settings.movieTemplate = data; this.plugin.saveSettings(); }); }); new import_obsidian4.Setting(containerEl).setName("Series template").setDesc("Template file to be used when creating a new note for a series.").addSearch((cb) => { new FileSuggest(this.app, cb.inputEl); cb.setPlaceholder("Example: seriesTemplate.md").setValue(this.plugin.settings.seriesTemplate).onChange((data) => { this.plugin.settings.seriesTemplate = data; this.plugin.saveSettings(); }); }); new import_obsidian4.Setting(containerEl).setName("Game template").setDesc("Template file to be used when creating a new note for a game.").addSearch((cb) => { new FileSuggest(this.app, cb.inputEl); cb.setPlaceholder("Example: gameTemplate.md").setValue(this.plugin.settings.gameTemplate).onChange((data) => { this.plugin.settings.gameTemplate = data; this.plugin.saveSettings(); }); }); new import_obsidian4.Setting(containerEl).setName("Wiki template").setDesc("Template file to be used when creating a new note for a wiki entry.").addSearch((cb) => { new FileSuggest(this.app, cb.inputEl); cb.setPlaceholder("Example: wikiTemplate.md").setValue(this.plugin.settings.wikiTemplate).onChange((data) => { this.plugin.settings.wikiTemplate = data; this.plugin.saveSettings(); }); }); new import_obsidian4.Setting(containerEl).setName("Music Release template").setDesc("Template file to be used when creating a new note for a music release.").addSearch((cb) => { new FileSuggest(this.app, cb.inputEl); cb.setPlaceholder("Example: musicReleaseTemplate.md").setValue(this.plugin.settings.musicReleaseTemplate).onChange((data) => { this.plugin.settings.musicReleaseTemplate = data; this.plugin.saveSettings(); }); }); containerEl.createEl("h3", { text: "File Name Settings" }); new import_obsidian4.Setting(containerEl).setName("Movie file name template").setDesc("Template for the file name used when creating a new note for a movie.").addText((cb) => { cb.setPlaceholder(`Example: ${DEFAULT_SETTINGS.movieFileNameTemplate}`).setValue(this.plugin.settings.movieFileNameTemplate).onChange((data) => { this.plugin.settings.movieFileNameTemplate = data; this.plugin.saveSettings(); }); }); new import_obsidian4.Setting(containerEl).setName("Series file name template").setDesc("Template for the file name used when creating a new note for a series.").addText((cb) => { cb.setPlaceholder(`Example: ${DEFAULT_SETTINGS.seriesFileNameTemplate}`).setValue(this.plugin.settings.seriesFileNameTemplate).onChange((data) => { this.plugin.settings.seriesFileNameTemplate = data; this.plugin.saveSettings(); }); }); new import_obsidian4.Setting(containerEl).setName("Game file name template").setDesc("Template for the file name used when creating a new note for a game.").addText((cb) => { cb.setPlaceholder(`Example: ${DEFAULT_SETTINGS.gameFileNameTemplate}`).setValue(this.plugin.settings.gameFileNameTemplate).onChange((data) => { this.plugin.settings.gameFileNameTemplate = data; this.plugin.saveSettings(); }); }); new import_obsidian4.Setting(containerEl).setName("Wiki file name template").setDesc("Template for the file name used when creating a new note for a wiki entry.").addText((cb) => { cb.setPlaceholder(`Example: ${DEFAULT_SETTINGS.wikiFileNameTemplate}`).setValue(this.plugin.settings.wikiFileNameTemplate).onChange((data) => { this.plugin.settings.wikiFileNameTemplate = data; this.plugin.saveSettings(); }); }); new import_obsidian4.Setting(containerEl).setName("Music Release file name template").setDesc("Template for the file name used when creating a new note for a music release.").addText((cb) => { cb.setPlaceholder(`Example: ${DEFAULT_SETTINGS.musicReleaseFileNameTemplate}`).setValue(this.plugin.settings.musicReleaseFileNameTemplate).onChange((data) => { this.plugin.settings.musicReleaseFileNameTemplate = data; this.plugin.saveSettings(); }); }); containerEl.createEl("h3", { text: "Property Mappings" }); new import_obsidian4.Setting(containerEl).setName("Movie model property mappings").setDesc("Mappings for the property names of a movie.").addTextArea((cb) => { cb.setPlaceholder(`Example: title -> name year -> releaseYear`).setValue(this.plugin.settings.moviePropertyConversionRules).onChange((data) => { this.plugin.settings.moviePropertyConversionRules = data; this.plugin.saveSettings(); }); }); new import_obsidian4.Setting(containerEl).setName("Series model property mappings").setDesc("Mappings for the property names of a series.").addTextArea((cb) => { cb.setPlaceholder(`Example: title -> name year -> releaseYear`).setValue(this.plugin.settings.seriesPropertyConversionRules).onChange((data) => { this.plugin.settings.seriesPropertyConversionRules = data; this.plugin.saveSettings(); }); }); new import_obsidian4.Setting(containerEl).setName("Game model property mappings").setDesc("Mappings for the property names of a game.").addTextArea((cb) => { cb.setPlaceholder(`Example: title -> name year -> releaseYear`).setValue(this.plugin.settings.gamePropertyConversionRules).onChange((data) => { this.plugin.settings.gamePropertyConversionRules = data; this.plugin.saveSettings(); }); }); new import_obsidian4.Setting(containerEl).setName("Wiki model property mappings").setDesc("Mappings for the property names of a wiki entry.").addTextArea((cb) => { cb.setPlaceholder(`Example: title -> name year -> releaseYear`).setValue(this.plugin.settings.wikiPropertyConversionRules).onChange((data) => { this.plugin.settings.wikiPropertyConversionRules = data; this.plugin.saveSettings(); }); }); new import_obsidian4.Setting(containerEl).setName("Music Release model property mappings").setDesc("Mappings for the property names of a music release.").addTextArea((cb) => { cb.setPlaceholder(`Example: title -> name year -> releaseYear`).setValue(this.plugin.settings.musicReleasePropertyConversionRules).onChange((data) => { this.plugin.settings.musicReleasePropertyConversionRules = data; this.plugin.saveSettings(); }); }); } }; // src/api/APIManager.ts var APIManager = class { constructor() { this.apis = []; } query(query, apisToQuery) { return __async(this, null, function* () { debugLog(`MDB | api manager queried with "${query}"`); let res = []; for (const api of this.apis) { if (Object.keys(apisToQuery).contains(api.apiName) && apisToQuery[api.apiName]) { const apiRes = yield api.searchByTitle(query); res = res.concat(apiRes); } } return res; }); } queryDetailedInfo(item) { return __async(this, null, function* () { return yield this.queryDetailedInfoById(item.id, item.dataSource); }); } queryDetailedInfoById(id, dataSource) { return __async(this, null, function* () { for (const api of this.apis) { if (api.apiName === dataSource) { return api.getById(id); } } }); } getApiByName(name) { for (const api of this.apis) { if (api.apiName === name) { return api; } } return null; } registerAPI(api) { this.apis.push(api); } }; // src/api/APIModel.ts var APIModel = class { hasType(type) { return this.types.contains(type); } hasTypeOverlap(types) { for (const type of types) { if (this.hasType(type)) { return true; } } return false; } }; // src/models/MediaTypeModel.ts var MediaTypeModel = class { toMetaDataObject() { return __spreadProps(__spreadValues(__spreadValues({}, this.getWithOutUserData()), this.userData), { tags: "#" + this.getTags().join("/") }); } getWithOutUserData() { const copy = JSON.parse(JSON.stringify(this)); delete copy.userData; return copy; } }; // src/utils/MediaType.ts var MediaType; (function(MediaType2) { MediaType2["Movie"] = "movie"; MediaType2["Series"] = "series"; MediaType2["Game"] = "game"; MediaType2["MusicRelease"] = "musicRelease"; MediaType2["Wiki"] = "wiki"; })(MediaType || (MediaType = {})); // src/models/MovieModel.ts var MovieModel = class extends MediaTypeModel { constructor(obj = {}) { super(); Object.assign(this, obj); this.type = this.getMediaType(); } getTags() { return [mediaDbTag, "tv", "movie"]; } getMediaType() { return MediaType.Movie; } }; // src/models/SeriesModel.ts var SeriesModel = class extends MediaTypeModel { constructor(obj = {}) { super(); Object.assign(this, obj); this.type = this.getMediaType(); } getTags() { return [mediaDbTag, "tv", "series"]; } getMediaType() { return MediaType.Series; } }; // src/models/GameModel.ts var GameModel = class extends MediaTypeModel { constructor(obj = {}) { super(); Object.assign(this, obj); this.type = this.getMediaType(); } getTags() { return [mediaDbTag, "game"]; } getMediaType() { return MediaType.Game; } }; // src/api/apis/OMDbAPI.ts var OMDbAPI = class extends APIModel { constructor(plugin) { super(); this.plugin = plugin; this.apiName = "OMDbAPI"; this.apiDescription = "A free API for Movies, Series and Games."; this.apiUrl = "http://www.omdbapi.com/"; this.types = ["movie", "series"]; this.typeMappings = new Map(); this.typeMappings.set("movie", "movie"); this.typeMappings.set("series", "series"); this.typeMappings.set("game", "game"); } searchByTitle(title) { return __async(this, null, function* () { console.log(`MDB | api "${this.apiName}" queried by Title`); const searchUrl = `http://www.omdbapi.com/?s=${encodeURIComponent(title)}&apikey=${this.plugin.settings.OMDbKey}`; const fetchData = yield fetch(searchUrl); if (fetchData.status === 401) { throw Error(`MDB | Authentication for ${this.apiName} failed. Check the API key.`); } if (fetchData.status !== 200) { throw Error(`MDB | Received status code ${fetchData.status} from an API.`); } const data = yield fetchData.json(); if (data.Response === "False") { throw Error(`MDB | Received error from ${this.apiName}: ${data.Error}`); } if (!data.Search) { return []; } debugLog(data.Search); let ret = []; for (const result of data.Search) { const type = this.typeMappings.get(result.Type.toLowerCase()); if (type === void 0) { continue; } if (type === "movie") { ret.push(new MovieModel({ type, title: result.Title, englishTitle: result.Title, year: result.Year, dataSource: this.apiName, id: result.imdbID })); } else if (type === "series") { ret.push(new SeriesModel({ type, title: result.Title, englishTitle: result.Title, year: result.Year, dataSource: this.apiName, id: result.imdbID })); } else if (type === "game") { ret.push(new GameModel({ type, title: result.Title, englishTitle: result.Title, year: result.Year, dataSource: this.apiName, id: result.imdbID })); } } return ret; }); } getById(id) { return __async(this, null, function* () { var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r; console.log(`MDB | api "${this.apiName}" queried by ID`); const searchUrl = `http://www.omdbapi.com/?i=${encodeURIComponent(id)}&apikey=${this.plugin.settings.OMDbKey}`; const fetchData = yield fetch(searchUrl); if (fetchData.status === 401) { throw Error(`MDB | Authentication for ${this.apiName} failed. Check the API key.`); } if (fetchData.status !== 200) { throw Error(`MDB | Received status code ${fetchData.status} from an API.`); } const result = yield fetchData.json(); debugLog(result); if (result.Response === "False") { throw Error(`MDB | Received error from ${this.apiName}: ${result.Error}`); } const type = this.typeMappings.get(result.Type.toLowerCase()); if (type === void 0) { throw Error(`${result.type.toLowerCase()} is an unsupported type.`); } if (type === "movie") { const model = new MovieModel({ type, title: result.Title, englishTitle: result.Title, year: result.Year, dataSource: this.apiName, url: `https://www.imdb.com/title/${result.imdbID}/`, id: result.imdbID, genres: (_b = (_a = result.Genre) == null ? void 0 : _a.split(", ")) != null ? _b : [], producer: (_c = result.Director) != null ? _c : "unknown", duration: (_d = result.Runtime) != null ? _d : "unknown", onlineRating: Number.parseFloat((_e = result.imdbRating) != null ? _e : 0), image: (_f = result.Poster) != null ? _f : "", released: true, premiere: (_g = new Date(result.Released).toLocaleDateString()) != null ? _g : "unknown", userData: { watched: false, lastWatched: "", personalRating: 0 } }); return model; } else if (type === "series") { const model = new SeriesModel({ type, title: result.Title, englishTitle: result.Title, year: result.Year, dataSource: this.apiName, url: `https://www.imdb.com/title/${result.imdbID}/`, id: result.imdbID, genres: (_i = (_h = result.Genre) == null ? void 0 : _h.split(", ")) != null ? _i : [], studios: [result.Director], episodes: 0, duration: (_j = result.Runtime) != null ? _j : "unknown", onlineRating: Number.parseFloat((_k = result.imdbRating) != null ? _k : 0), image: (_l = result.Poster) != null ? _l : "", released: true, airing: false, airedFrom: (_m = new Date(result.Released).toLocaleDateString()) != null ? _m : "unknown", airedTo: "unknown", userData: { watched: false, lastWatched: "", personalRating: 0 } }); return model; } else if (type === "game") { const model = new GameModel({ type, title: result.Title, englishTitle: result.Title, year: result.Year, dataSource: this.apiName, url: `https://www.imdb.com/title/${result.imdbID}/`, id: result.imdbID, genres: (_o = (_n = result.Genre) == null ? void 0 : _n.split(", ")) != null ? _o : [], onlineRating: Number.parseFloat((_p = result.imdbRating) != null ? _p : 0), image: (_q = result.Poster) != null ? _q : "", released: true, releaseDate: (_r = new Date(result.Released).toLocaleDateString()) != null ? _r : "unknown", userData: { played: false, personalRating: 0 } }); return model; } return; }); } }; // src/modals/MediaDbAdvancedSearchModal.ts var import_obsidian5 = __toModule(require("obsidian")); var MediaDbAdvancedSearchModal = class extends import_obsidian5.Modal { constructor(app, plugin, onSubmit) { super(app); this.plugin = plugin; this.onSubmit = onSubmit; this.selectedApis = []; for (const api of this.plugin.apiManager.apis) { this.selectedApis[api.apiName] = false; } } submitCallback(event) { if (event.key === "Enter") { this.search(); } } search() { return __async(this, null, function* () { debugLog(this.selectedApis); if (!this.query || this.query.length < 3) { new import_obsidian5.Notice("MDB | Query to short"); return; } let selectedAPICount = 0; for (const api in this.selectedApis) { if (this.selectedApis[api]) { selectedAPICount += 1; } } if (selectedAPICount === 0) { new import_obsidian5.Notice("MDB | No API selected"); return; } if (!this.isBusy) { try { this.isBusy = true; this.searchBtn.setDisabled(false); this.searchBtn.setButtonText("Searching..."); console.log(`MDB | query started with title ${this.query}`); const res = yield this.plugin.apiManager.query(this.query, this.selectedApis); this.onSubmit(null, res); } catch (e) { this.onSubmit(e); } finally { this.close(); } } }); } onOpen() { const { contentEl } = this; contentEl.createEl("h2", { text: "Search media db" }); const placeholder = "Search by title"; const searchComponent = new import_obsidian5.TextComponent(contentEl); searchComponent.inputEl.style.width = "100%"; searchComponent.setPlaceholder(placeholder); searchComponent.onChange((value) => this.query = value); searchComponent.inputEl.addEventListener("keydown", this.submitCallback.bind(this)); contentEl.appendChild(searchComponent.inputEl); searchComponent.inputEl.focus(); contentEl.createEl("h3", { text: "APIs to search" }); const apiToggleComponents = []; for (const api of this.plugin.apiManager.apis) { const apiToggleListElementWrapper = contentEl.createEl("div", { cls: "media-db-plugin-list-wrapper" }); const apiToggleTextWrapper = apiToggleListElementWrapper.createEl("div", { cls: "media-db-plugin-list-text-wrapper" }); apiToggleTextWrapper.createEl("span", { text: api.apiName, cls: "media-db-plugin-list-text" }); apiToggleTextWrapper.createEl("small", { text: api.apiDescription, cls: "media-db-plugin-list-text" }); const apiToggleComponentWrapper = apiToggleListElementWrapper.createEl("div", { cls: "media-db-plugin-list-toggle" }); const apiToggleComponent = new import_obsidian5.ToggleComponent(apiToggleComponentWrapper); apiToggleComponent.setTooltip(api.apiName); apiToggleComponent.setValue(this.selectedApis[api.apiName]); apiToggleComponent.onChange((value) => { this.selectedApis[api.apiName] = value; }); apiToggleComponentWrapper.appendChild(apiToggleComponent.toggleEl); } new import_obsidian5.Setting(contentEl).addButton((btn) => btn.setButtonText("Cancel").onClick(() => this.close())).addButton((btn) => { return this.searchBtn = btn.setButtonText("Ok").setCta().onClick(() => { this.search(); }); }); } onClose() { const { contentEl } = this; contentEl.empty(); } }; // src/modals/MediaDbSearchResultModal.ts var import_obsidian6 = __toModule(require("obsidian")); var MediaDbSearchResultModal = class extends import_obsidian6.SuggestModal { constructor(app, plugin, suggestion, onChoose) { super(app); this.plugin = plugin; this.suggestion = suggestion; this.onChoose = onChoose; } getSuggestions(query) { return this.suggestion.filter((item) => { const searchQuery = query.toLowerCase(); return item.title.toLowerCase().includes(searchQuery); }); } renderSuggestion(item, el) { el.createEl("div", { text: this.plugin.mediaTypeManager.getFileName(item) }); el.createEl("small", { text: `${item.englishTitle} ` }); el.createEl("small", { text: `${item.type.toUpperCase() + (item.subType ? ` (${item.subType})` : "")} from ${item.dataSource}` }); } onChooseSuggestion(item, evt) { this.onChoose(null, item); } }; // src/api/apis/MALAPI.ts var MALAPI = class extends APIModel { constructor(plugin) { super(); this.plugin = plugin; this.apiName = "MALAPI"; this.apiDescription = "A free API for Anime. Some results may take a long time to load."; this.apiUrl = "https://jikan.moe/"; this.types = ["movie", "series", "anime"]; this.typeMappings = new Map(); this.typeMappings.set("movie", "movie"); this.typeMappings.set("special", "special"); this.typeMappings.set("tv", "series"); this.typeMappings.set("ova", "ova"); } searchByTitle(title) { return __async(this, null, function* () { var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l; console.log(`MDB | api "${this.apiName}" queried by Title`); const searchUrl = `https://api.jikan.moe/v4/anime?q=${encodeURIComponent(title)}&limit=20${this.plugin.settings.sfwFilter ? "&sfw" : ""}`; const fetchData = yield fetch(searchUrl); debugLog(fetchData); if (fetchData.status !== 200) { throw Error(`MDB | Received status code ${fetchData.status} from an API.`); } const data = yield fetchData.json(); debugLog(data); let ret = []; for (const result of data.data) { const type = this.typeMappings.get(result.type.toLowerCase()); if (type === void 0) { continue; } if (type === "movie" || type === "special") { ret.push(new MovieModel({ type, title: result.title, englishTitle: (_a = result.title_english) != null ? _a : result.title, year: (_f = (_e = result.year) != null ? _e : (_d = (_c = (_b = result.aired) == null ? void 0 : _b.prop) == null ? void 0 : _c.from) == null ? void 0 : _d.year) != null ? _f : "", dataSource: this.apiName, id: result.mal_id })); } else if (type === "series" || type === "ova") { ret.push(new SeriesModel({ type, title: result.title, englishTitle: (_g = result.title_english) != null ? _g : result.title, year: (_l = (_k = result.year) != null ? _k : (_j = (_i = (_h = result.aired) == null ? void 0 : _h.prop) == null ? void 0 : _i.from) == null ? void 0 : _j.year) != null ? _l : "", dataSource: this.apiName, id: result.mal_id })); } } return ret; }); } getById(id) { return __async(this, null, function* () { var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J; console.log(`MDB | api "${this.apiName}" queried by ID`); const searchUrl = `https://api.jikan.moe/v4/anime/${encodeURIComponent(id)}`; const fetchData = yield fetch(searchUrl); if (fetchData.status !== 200) { throw Error(`MDB | Received status code ${fetchData.status} from an API.`); } const data = yield fetchData.json(); debugLog(data); const result = data.data; const type = this.typeMappings.get(result.type.toLowerCase()); if (type === void 0) { throw Error(`${result.type.toLowerCase()} is an unsupported type.`); } if (type === "movie" || type === "special") { const model = new MovieModel({ type, title: result.title, englishTitle: (_a = result.title_english) != null ? _a : result.title, year: (_f = (_e = result.year) != null ? _e : (_d = (_c = (_b = result.aired) == null ? void 0 : _b.prop) == null ? void 0 : _c.from) == null ? void 0 : _d.year) != null ? _f : "", dataSource: this.apiName, url: result.url, id: result.mal_id, genres: (_h = (_g = result.genres) == null ? void 0 : _g.map((x) => x.name)) != null ? _h : [], producer: (_j = (_i = result.studios) == null ? void 0 : _i.map((x) => x.name).join(", ")) != null ? _j : "unknown", duration: (_k = result.duration) != null ? _k : "unknown", onlineRating: (_l = result.score) != null ? _l : 0, image: (_o = (_n = (_m = result.images) == null ? void 0 : _m.jpg) == null ? void 0 : _n.image_url) != null ? _o : "", released: true, premiere: (_q = new Date((_p = result.aired) == null ? void 0 : _p.from).toLocaleDateString()) != null ? _q : "unknown", userData: { watched: false, lastWatched: "", personalRating: 0 } }); return model; } else if (type === "series" || type === "ova") { const model = new SeriesModel({ type, title: result.title, englishTitle: (_r = result.title_english) != null ? _r : result.title, year: (_w = (_v = result.year) != null ? _v : (_u = (_t = (_s = result.aired) == null ? void 0 : _s.prop) == null ? void 0 : _t.from) == null ? void 0 : _u.year) != null ? _w : "", dataSource: this.apiName, url: result.url, id: result.mal_id, genres: (_y = (_x = result.genres) == null ? void 0 : _x.map((x) => x.name)) != null ? _y : [], studios: (_A = (_z = result.studios) == null ? void 0 : _z.map((x) => x.name)) != null ? _A : [], episodes: result.episodes, duration: (_B = result.duration) != null ? _B : "unknown", onlineRating: (_C = result.score) != null ? _C : 0, image: (_F = (_E = (_D = result.images) == null ? void 0 : _D.jpg) == null ? void 0 : _E.image_url) != null ? _F : "", released: true, airedFrom: (_H = new Date((_G = result.aired) == null ? void 0 : _G.from).toLocaleDateString()) != null ? _H : "unknown", airedTo: (_J = new Date((_I = result.aired) == null ? void 0 : _I.to).toLocaleDateString()) != null ? _J : "unknown", airing: result.airing, userData: { watched: false, lastWatched: "", personalRating: 0 } }); return model; } return; }); } }; // src/modals/MediaDbIdSearchModal.ts var import_obsidian7 = __toModule(require("obsidian")); var MediaDbIdSearchModal = class extends import_obsidian7.Modal { constructor(app, plugin, onSubmit) { super(app); this.plugin = plugin; this.onSubmit = onSubmit; this.selectedApi = ""; } submitCallback(event) { if (event.key === "Enter") { this.search(); } } search() { return __async(this, null, function* () { debugLog(this.selectedApi); if (!this.query) { new import_obsidian7.Notice("MDB | no Id entered"); return; } if (!this.selectedApi) { new import_obsidian7.Notice("MDB | No API selected"); return; } if (!this.isBusy) { try { this.isBusy = true; this.searchBtn.setDisabled(false); this.searchBtn.setButtonText("Searching..."); console.log(`MDB | query started with id ${this.query}`); const api = this.plugin.apiManager.getApiByName(this.selectedApi); if (!api) { this.onSubmit(new Error("the selected api does not exist")); } const res = yield api.getById(this.query); this.onSubmit(null, res); } catch (e) { this.onSubmit(e); } finally { this.close(); } } }); } onOpen() { const { contentEl } = this; contentEl.createEl("h2", { text: "Search media db by id" }); const placeholder = "Search by id"; const searchComponent = new import_obsidian7.TextComponent(contentEl); searchComponent.inputEl.style.width = "100%"; searchComponent.setPlaceholder(placeholder); searchComponent.onChange((value) => this.query = value); searchComponent.inputEl.addEventListener("keydown", this.submitCallback.bind(this)); contentEl.appendChild(searchComponent.inputEl); searchComponent.inputEl.focus(); const apiSelectorWrapper = contentEl.createEl("div", { cls: "media-db-plugin-list-wrapper" }); const apiSelectorTExtWrapper = apiSelectorWrapper.createEl("div", { cls: "media-db-plugin-list-text-wrapper" }); apiSelectorTExtWrapper.createEl("span", { text: "API to search", cls: "media-db-plugin-list-text" }); const apiSelectorComponent = new import_obsidian7.DropdownComponent(apiSelectorWrapper); apiSelectorComponent.onChange((value) => { this.selectedApi = value; }); for (const api of this.plugin.apiManager.apis) { apiSelectorComponent.addOption(api.apiName, api.apiName); } apiSelectorWrapper.appendChild(apiSelectorComponent.selectEl); new import_obsidian7.Setting(contentEl).addButton((btn) => btn.setButtonText("Cancel").onClick(() => this.close())).addButton((btn) => { return this.searchBtn = btn.setButtonText("Ok").setCta().onClick(() => { this.search(); }); }); } onClose() { const { contentEl } = this; contentEl.empty(); } }; // src/models/WikiModel.ts var WikiModel = class extends MediaTypeModel { constructor(obj = {}) { super(); Object.assign(this, obj); this.type = this.getMediaType(); } getTags() { return [mediaDbTag, "wiki"]; } getMediaType() { return MediaType.Wiki; } getWithOutUserData() { const copy = JSON.parse(JSON.stringify(this)); delete copy.userData; delete copy.article; return copy; } }; // src/api/apis/WikipediaAPI.ts var WikipediaAPI = class extends APIModel { constructor(plugin) { super(); this.plugin = plugin; this.apiName = "Wikipedia API"; this.apiDescription = "The API behind Wikipedia"; this.apiUrl = "https://www.wikipedia.com"; this.types = ["wiki"]; } searchByTitle(title) { return __async(this, null, function* () { console.log(`MDB | api "${this.apiName}" queried by Title`); const searchUrl = `https://en.wikipedia.org/w/api.php?action=query&list=search&srsearch=${encodeURIComponent(title)}&srlimit=20&utf8=&format=json&origin=*`; const fetchData = yield fetch(searchUrl); debugLog(fetchData); if (fetchData.status !== 200) { throw Error(`MDB | Received status code ${fetchData.status} from an API.`); } const data = yield fetchData.json(); debugLog(data); let ret = []; for (const result of data.query.search) { ret.push(new WikiModel({ type: "wiki", title: result.title, englishTitle: result.title, year: "", dataSource: this.apiName, id: result.pageid })); } return ret; }); } getById(id) { return __async(this, null, function* () { var _a, _b; console.log(`MDB | api "${this.apiName}" queried by ID`); const searchUrl = `https://en.wikipedia.org/w/api.php?action=query&prop=info&pageids=${encodeURIComponent(id)}&inprop=url&format=json&origin=*`; const fetchData = yield fetch(searchUrl); if (fetchData.status !== 200) { throw Error(`MDB | Received status code ${fetchData.status} from an API.`); } const data = yield fetchData.json(); debugLog(data); const result = Object.entries((_a = data == null ? void 0 : data.query) == null ? void 0 : _a.pages)[0][1]; const model = new WikiModel({ type: "wiki", title: result.title, englishTitle: result.title, year: "", dataSource: this.apiName, id: result.pageid, wikiUrl: result.fullurl, lastUpdated: (_b = new Date(result.touched).toLocaleDateString()) != null ? _b : "unknown", length: result.length, userData: {} }); return model; }); } }; // src/api/apis/MusicBrainzAPI.ts var import_obsidian8 = __toModule(require("obsidian")); // src/models/MusicReleaseModel.ts var MusicReleaseModel = class extends MediaTypeModel { constructor(obj = {}) { super(); Object.assign(this, obj); this.type = this.getMediaType(); } getTags() { return [mediaDbTag, "music", this.subType]; } getMediaType() { return MediaType.MusicRelease; } }; // src/api/apis/MusicBrainzAPI.ts var MusicBrainzAPI = class extends APIModel { constructor(plugin) { super(); this.plugin = plugin; this.apiName = "MusicBrainz API"; this.apiDescription = "Free API for music albums."; this.apiUrl = "https://musicbrainz.org/"; this.types = ["music"]; } searchByTitle(title) { return __async(this, null, function* () { console.log(`MDB | api "${this.apiName}" queried by Title`); const searchUrl = `https://musicbrainz.org/ws/2/release-group?query=${encodeURIComponent(title)}&limit=20&fmt=json`; const fetchData = yield (0, import_obsidian8.requestUrl)({ url: searchUrl, headers: { "User-Agent": `${pluginName}/${mediaDbVersion} (${contactEmail})` } }); debugLog(fetchData); if (fetchData.status !== 200) { throw Error(`MDB | Received status code ${fetchData.status} from an API.`); } const data = yield fetchData.json; debugLog(data); let ret = []; for (const result of data["release-groups"]) { ret.push(new MusicReleaseModel({ type: "musicRelease", title: result.title, englishTitle: result.title, year: new Date(result["first-release-date"]).getFullYear().toString(), dataSource: this.apiName, url: "", id: result.id, artists: result["artist-credit"].map((a) => a.name), subType: result["primary-type"] })); } return ret; }); } getById(id) { return __async(this, null, function* () { console.log(`MDB | api "${this.apiName}" queried by ID`); const searchUrl = `https://musicbrainz.org/ws/2/release-group/${encodeURIComponent(id)}?inc=releases+artists+tags+ratings+genres&fmt=json`; const fetchData = yield (0, import_obsidian8.requestUrl)({ url: searchUrl, headers: { "User-Agent": `${pluginName}/${mediaDbVersion} (${contactEmail})` } }); if (fetchData.status !== 200) { throw Error(`MDB | Received status code ${fetchData.status} from an API.`); } const data = yield fetchData.json; debugLog(data); const result = data; const model = new MusicReleaseModel({ type: "musicRelease", title: result.title, englishTitle: result.title, year: new Date(result["first-release-date"]).getFullYear().toString(), dataSource: this.apiName, url: "", id: result.id, artists: result["artist-credit"].map((a) => a.name), genres: result.genres.map((g) => g.name), subType: result["primary-type"], rating: result.rating.value * 2, userData: { personalRating: 0 } }); return model; }); } }; // src/utils/MediaTypeManager.ts var MediaTypeManager = class { constructor(settings) { this.updateTemplates(settings); } updateTemplates(settings) { this.mediaFileNameTemplateMap = new Map(); this.mediaFileNameTemplateMap.set(MediaType.Movie, settings.movieFileNameTemplate); this.mediaFileNameTemplateMap.set(MediaType.Series, settings.seriesFileNameTemplate); this.mediaFileNameTemplateMap.set(MediaType.Game, settings.gameFileNameTemplate); this.mediaFileNameTemplateMap.set(MediaType.Wiki, settings.wikiFileNameTemplate); this.mediaFileNameTemplateMap.set(MediaType.MusicRelease, settings.musicReleaseFileNameTemplate); this.mediaTemplateMap = new Map(); this.mediaTemplateMap.set(MediaType.Movie, settings.movieTemplate); this.mediaTemplateMap.set(MediaType.Series, settings.seriesTemplate); this.mediaTemplateMap.set(MediaType.Game, settings.gameTemplate); this.mediaTemplateMap.set(MediaType.Wiki, settings.wikiTemplate); this.mediaTemplateMap.set(MediaType.MusicRelease, settings.musicReleaseTemplate); } getFileName(mediaTypeModel) { return replaceTags(this.mediaFileNameTemplateMap.get(mediaTypeModel.getMediaType()), mediaTypeModel); } getContent(mediaTypeModel, app) { return __async(this, null, function* () { const templateFileName = this.mediaTemplateMap.get(mediaTypeModel.getMediaType()); if (!templateFileName) { return ""; } const templateFile = app.vault.getFiles().filter((f) => f.name === templateFileName).first(); if (!templateFile) { return ""; } const template = yield app.vault.cachedRead(templateFile); return replaceTags(template, mediaTypeModel); }); } createMediaTypeModelFromMediaType(obj, mediaType) { if (mediaType === MediaType.Movie) { return new MovieModel(obj); } else if (mediaType === MediaType.Series) { return new SeriesModel(obj); } else if (mediaType === MediaType.Game) { return new GameModel(obj); } else if (mediaType === MediaType.Wiki) { return new WikiModel(obj); } else if (mediaType === MediaType.MusicRelease) { return new MusicReleaseModel(obj); } return void 0; } }; // src/api/apis/SteamAPI.ts var import_obsidian9 = __toModule(require("obsidian")); var SteamAPI = class extends APIModel { constructor(plugin) { super(); this.plugin = plugin; this.apiName = "SteamAPI"; this.apiDescription = "A free API for all Steam games."; this.apiUrl = "http://www.steampowered.com/"; this.types = ["games"]; this.typeMappings = new Map(); this.typeMappings.set("game", "game"); } searchByTitle(title) { return __async(this, null, function* () { console.log(`MDB | api "${this.apiName}" queried by Title`); const searchUrl = `http://api.steampowered.com/ISteamApps/GetAppList/v0002/?format=json`; const fetchData = yield (0, import_obsidian9.requestUrl)({ url: searchUrl }); if (fetchData.status !== 200) { throw Error(`MDB | Received status code ${fetchData.status} from an API.`); } const data = yield fetchData.json; debugLog(data); let filteredData = []; for (const app of data.applist.apps) { if (app.name.toLowerCase().includes(title.toLowerCase())) { filteredData.push(app); } if (filteredData.length > 20) { break; } } let ret = []; for (const result of filteredData) { ret.push(new GameModel({ type: MediaType.Game, title: result.name, englishTitle: result.name, year: "", dataSource: this.apiName, id: result.appid })); } return ret; }); } getById(id) { return __async(this, null, function* () { var _a, _b, _c, _d, _e, _f, _g, _h; console.log(`MDB | api "${this.apiName}" queried by ID`); const searchUrl = `http://store.steampowered.com/api/appdetails?appids=${encodeURIComponent(id)}`; const fetchData = yield (0, import_obsidian9.requestUrl)({ url: searchUrl }); if (fetchData.status !== 200) { throw Error(`MDB | Received status code ${fetchData.status} from an API.`); } debugLog(yield fetchData.json); let result; for (const [key, value] of Object.entries(yield fetchData.json)) { if (key === String(id)) { result = value.data; } } if (!result) { throw Error(`MDB | API returned invalid data.`); } debugLog(result); const model = new GameModel({ type: MediaType.Game, title: result.name, englishTitle: result.name, year: new Date(result.release_date.date).getFullYear().toString(), dataSource: this.apiName, url: `https://store.steampowered.com/app/${result.id}`, id: result.steam_appid, genres: (_b = (_a = result.genres) == null ? void 0 : _a.map((x) => x.description)) != null ? _b : [], onlineRating: Number.parseFloat((_d = (_c = result.metacritic) == null ? void 0 : _c.score) != null ? _d : 0), image: (_e = result.header_image) != null ? _e : "", released: !((_f = result.release_date) == null ? void 0 : _f.comming_soon), releaseDate: (_h = new Date((_g = result.release_date) == null ? void 0 : _g.date).toLocaleDateString()) != null ? _h : "unknown", userData: { played: false, personalRating: 0 } }); return model; }); } }; // src/settings/ModelPropertyConversionRule.ts var ModelPropertyConversionRule = class { constructor(conversionRule) { const conversionRuleParts = conversionRule.split("->"); if (conversionRuleParts.length !== 2) { throw Error(`Conversion rule "${conversionRule}" may only have exactly one "->"`); } let property = conversionRuleParts[0].trim(); let newProperty = conversionRuleParts[1].trim(); if (!property || !containsOnlyLettersAndUnderscores(property)) { throw Error(`Error in conversion rule "${conversionRule}": property may not be empty and only contain letters and underscores.`); } if (!newProperty || !containsOnlyLettersAndUnderscores(newProperty)) { throw Error(`Error in conversion rule "${conversionRule}": new property may not be empty and only contain letters and underscores.`); } this.property = property; this.newProperty = newProperty; } }; // src/settings/ModelPropertyMapper.ts var ModelPropertyMapper = class { constructor(settings) { this.updateConversionRules(settings); } updateConversionRules(settings) { this.conversionRulesMap = new Map(); this.conversionRulesMap.set(MediaType.Movie, settings.moviePropertyConversionRules); this.conversionRulesMap.set(MediaType.Series, settings.seriesPropertyConversionRules); this.conversionRulesMap.set(MediaType.Game, settings.gamePropertyConversionRules); this.conversionRulesMap.set(MediaType.Wiki, settings.wikiPropertyConversionRules); this.conversionRulesMap.set(MediaType.MusicRelease, settings.musicReleasePropertyConversionRules); } convertObject(obj) { if (!obj.hasOwnProperty("type")) { return obj; } const conversionRulesString = this.conversionRulesMap.get(obj["type"]); if (!conversionRulesString) { return obj; } const conversionRules = []; for (const conversionRuleString of conversionRulesString.split("\n")) { if (conversionRuleString) { conversionRules.push(new ModelPropertyConversionRule(conversionRuleString)); } } const newObj = {}; for (const [key, value] of Object.entries(obj)) { if (key === "type") { newObj[key] = value; continue; } let hasConversionRule = false; for (const conversionRule of conversionRules) { if (conversionRule.property === key) { hasConversionRule = true; newObj[conversionRule.newProperty] = value; } } if (!hasConversionRule) { newObj[key] = value; } } return newObj; } convertObjectBack(obj) { if (!obj.hasOwnProperty("type")) { return obj; } const conversionRulesString = this.conversionRulesMap.get(obj["type"]); if (!conversionRulesString) { return obj; } const conversionRules = []; for (const conversionRuleString of conversionRulesString.split("\n")) { if (conversionRuleString) { conversionRules.push(new ModelPropertyConversionRule(conversionRuleString)); } } const originalObj = {}; for (const [key, value] of Object.entries(obj)) { if (key === "type") { originalObj[key] = value; continue; } let hasConversionRule = false; for (const conversionRule of conversionRules) { if (conversionRule.newProperty === key) { hasConversionRule = true; originalObj[conversionRule.property] = value; } } if (!hasConversionRule) { originalObj[key] = value; } } return originalObj; } }; // src/utils/YAMLConverter.ts var YAMLConverter = class { static toYaml(obj) { let output = ""; for (const [key, value] of Object.entries(obj)) { output += `${key}: ${YAMLConverter.toYamlString(value, 0)} `; } return output; } static toYamlString(value, indentation) { if (typeof value === "boolean") { return value ? "true" : "false"; } else if (typeof value === "number") { return value.toString(); } else if (typeof value === "string") { return '"' + value + '"'; } else if (typeof value === "object") { let output = ""; if (Array.isArray(value)) { for (const valueElement of value) { output += ` ${YAMLConverter.calculateSpacing(indentation)} - ${YAMLConverter.toYamlString(valueElement, indentation + 1)}`; } } else { for (const [objKey, objValue] of Object.entries(value)) { output += ` ${YAMLConverter.calculateSpacing(indentation)} ${objKey}: ${YAMLConverter.toYamlString(objValue, indentation + 1)}`; } } return output; } } static calculateSpacing(indentation) { return " ".repeat(indentation * 4); } }; // src/main.ts var MediaDbPlugin = class extends import_obsidian10.Plugin { onload() { return __async(this, null, function* () { yield this.loadSettings(); const ribbonIconEl = this.addRibbonIcon("database", "Add new Media DB entry", (evt) => this.createMediaDbNote(this.openMediaDbAdvancedSearchModal.bind(this))); ribbonIconEl.addClass("obsidian-media-db-plugin-ribbon-class"); this.addCommand({ id: "open-media-db-search-modal", name: "Add new Media DB entry", callback: () => this.createMediaDbNote(this.openMediaDbAdvancedSearchModal.bind(this)) }); this.addCommand({ id: "open-media-db-id-search-modal", name: "Add new Media DB entry by id", callback: () => this.createMediaDbNote(this.openMediaDbIdSearchModal.bind(this)) }); this.addCommand({ id: "update-media-db-note", name: "Update the open note, if it is a Media DB entry.", checkCallback: (checking) => { if (!this.app.workspace.getActiveFile()) { return false; } if (!checking) { this.updateActiveNote(); } return true; } }); this.addSettingTab(new MediaDbSettingTab(this.app, this)); this.apiManager = new APIManager(); this.apiManager.registerAPI(new OMDbAPI(this)); this.apiManager.registerAPI(new MALAPI(this)); this.apiManager.registerAPI(new WikipediaAPI(this)); this.apiManager.registerAPI(new MusicBrainzAPI(this)); this.apiManager.registerAPI(new SteamAPI(this)); this.mediaTypeManager = new MediaTypeManager(this.settings); this.modelPropertyMapper = new ModelPropertyMapper(this.settings); }); } createMediaDbNote(modal) { return __async(this, null, function* () { try { let data = yield modal(); data = yield this.apiManager.queryDetailedInfo(data); yield this.createMediaDbNoteFromModel(data); } catch (e) { console.warn(e); new import_obsidian10.Notice(e.toString()); } }); } createMediaDbNoteFromModel(mediaTypeModel) { return __async(this, null, function* () { try { console.log("MDB | Creating new note..."); let fileContent = `--- ${YAMLConverter.toYaml(this.modelPropertyMapper.convertObject(mediaTypeModel.toMetaDataObject()))}--- `; if (this.settings.templates) { fileContent += yield this.mediaTypeManager.getContent(mediaTypeModel, this.app); } const fileName = replaceIllegalFileNameCharactersInString(this.mediaTypeManager.getFileName(mediaTypeModel)); const filePath = `${this.settings.folder.replace(/\/$/, "")}/${fileName}.md`; const folder = this.app.vault.getAbstractFileByPath(this.settings.folder); if (!folder) { yield this.app.vault.createFolder(this.settings.folder.replace(/\/$/, "")); } const file = this.app.vault.getAbstractFileByPath(filePath); if (file) { yield this.app.vault.delete(file); } const targetFile = yield this.app.vault.create(filePath, fileContent); const activeLeaf = this.app.workspace.getUnpinnedLeaf(); if (!activeLeaf) { console.warn("MDB | no active leaf, not opening media db note"); return; } yield activeLeaf.openFile(targetFile, { state: { mode: "source" } }); } catch (e) { console.warn(e); new import_obsidian10.Notice(e.toString()); } }); } openMediaDbAdvancedSearchModal() { return __async(this, null, function* () { return new Promise((resolve, reject) => { new MediaDbAdvancedSearchModal(this.app, this, (err, results) => { if (err) return reject(err); new MediaDbSearchResultModal(this.app, this, results, (err2, res) => { if (err2) return reject(err2); resolve(res); }).open(); }).open(); }); }); } openMediaDbIdSearchModal() { return __async(this, null, function* () { return new Promise((resolve, reject) => { new MediaDbIdSearchModal(this.app, this, (err, res) => { if (err) return reject(err); resolve(res); }).open(); }); }); } updateActiveNote() { return __async(this, null, function* () { const activeFile = this.app.workspace.getActiveFile(); if (!activeFile) { throw new Error("MDB | there is no active note"); } let metadata = this.app.metadataCache.getFileCache(activeFile).frontmatter; delete metadata.position; metadata = this.modelPropertyMapper.convertObjectBack(metadata); console.log(metadata); if (!(metadata == null ? void 0 : metadata.type) || !(metadata == null ? void 0 : metadata.dataSource) || !(metadata == null ? void 0 : metadata.id)) { throw new Error("MDB | active note is not a Media DB entry or is missing metadata"); } let oldMediaTypeModel = this.mediaTypeManager.createMediaTypeModelFromMediaType(metadata, metadata.type); let newMediaTypeModel = yield this.apiManager.queryDetailedInfoById(metadata.id, metadata.dataSource); if (!newMediaTypeModel) { return; } newMediaTypeModel = Object.assign(oldMediaTypeModel, newMediaTypeModel.getWithOutUserData()); console.log("MDB | deleting old entry"); yield this.app.vault.delete(activeFile); yield this.createMediaDbNoteFromModel(newMediaTypeModel); }); } loadSettings() { return __async(this, null, function* () { this.settings = Object.assign({}, DEFAULT_SETTINGS, yield this.loadData()); }); } saveSettings() { return __async(this, null, function* () { this.mediaTypeManager.updateTemplates(this.settings); this.modelPropertyMapper.updateConversionRules(this.settings); yield this.saveData(this.settings); }); } };