mirror of
https://github.com/stashapp/CommunityScripts.git
synced 2026-02-04 20:04:27 -06:00
* replace SUL in VideoScrollWheel * rewrite stats to use cs-ui-lib - reused and simplified GQL queries * rewrite sceneCoverCropper to use cs-ui-lib * update discordPrescence to use cs-ui-lib - add websocket liveliness check - add video playback hooks * make stash-realbooru use cs-ui-lib * deprecated by https://github.com/7dJx1qP/stash-plugins/tree/main/plugins/stashBatchResultToggle * add cs-ui-lib to stashAI, applied some fixes to realbooru * update Visage to use cs-ui-lib * update themeSwitch to use cs-ui-lib * remove userscript lib --------- Co-authored-by: feederbox826 <feederbox826@users.noreply.github.com>
4135 lines
117 KiB
JavaScript
4135 lines
117 KiB
JavaScript
(function () {
|
|
"use strict";
|
|
|
|
let STASHMARKER_API_URL = "https://cc1234-stashtag.hf.space/api/predict";
|
|
|
|
var OPTIONS = [
|
|
"Anal",
|
|
"Vaginal Penetration",
|
|
"Blow Job",
|
|
"Doggy Style",
|
|
"Cowgirl",
|
|
"Reverse Cowgirl",
|
|
"Side Fuck",
|
|
"Seashell",
|
|
"Gape",
|
|
"Face Fuck",
|
|
"Fingering",
|
|
"Kneeling",
|
|
"Butter Churner",
|
|
"Table Top",
|
|
"Double Penetration",
|
|
"Missionary",
|
|
"Scissoring",
|
|
"Flatiron",
|
|
"Pussy Licking",
|
|
"Ass Licking",
|
|
"Ball Licking",
|
|
"Face Sitting",
|
|
"Hand Job",
|
|
"Tit Job",
|
|
"69",
|
|
"Kissing",
|
|
"Dildo",
|
|
"Cumshot",
|
|
];
|
|
|
|
/**
|
|
* Retrieves the tags associated with a given scene ID.
|
|
*
|
|
* @param {string} scene_id - The ID of the scene to retrieve tags for.
|
|
* @returns {Promise<string[]>} - A promise that resolves with an array of tag IDs.
|
|
*/
|
|
async function getTagsForScene(scene_id) {
|
|
const query = `query { findScene(id: "${scene_id}") { tags { id }}}`;
|
|
return csLib
|
|
.callGQL({ query })
|
|
.then((data) => data.findScene.tags.map((p) => p.id));
|
|
}
|
|
|
|
/**
|
|
* Updates a scene with the given scene_id and tag_ids.
|
|
* @param {string} scene_id - The ID of the scene to update.
|
|
* @param {Array<string>} tag_ids - An array of tag IDs to associate with the scene.
|
|
* @returns {Promise<Object>} - A promise that resolves with the updated scene object.
|
|
*/
|
|
async function updateScene(scene_id, tag_ids) {
|
|
const variables = { input: { id: scene_id, tag_ids: tag_ids } };
|
|
const query = `mutation sceneUpdate($input: SceneUpdateInput!){
|
|
sceneUpdate(input: $input) { id }}`;
|
|
return csLib.callGQL({ query, variables });
|
|
}
|
|
|
|
/**
|
|
* Returns an array with the scenario and scenario ID parsed from the current URL.
|
|
* @returns {Array<string>} An array with the scenario and scenario ID.
|
|
*/
|
|
function getScenarioAndID() {
|
|
var result = document.URL.match(/(scenes|images)\/(\d+)/);
|
|
var scenario = result[1];
|
|
var scenario_id = result[2];
|
|
return [scenario, scenario_id];
|
|
}
|
|
|
|
/**
|
|
* Creates a new tag with the given name.
|
|
* @param {string} tag_name - The name of the tag to create.
|
|
* @returns {Promise<string>} - A Promise that resolves with the ID of the newly created tag.
|
|
*/
|
|
async function createTag(tag_name) {
|
|
const variables = { input: { name: tag_name } };
|
|
const query = `mutation ($input: TagCreateInput!) { tagCreate(input: $input){ id }}`;
|
|
return await csLib
|
|
.callGQL({ query, variables })
|
|
.then((data) => data.tagCreate.id);
|
|
}
|
|
|
|
/**
|
|
* Creates a marker for a scene with the given parameters.
|
|
* @param {string} scene_id - The ID of the scene.
|
|
* @param {string} primary_tag_id - The ID of the primary tag.
|
|
* @param {number} seconds - The number of seconds for the marker.
|
|
* @returns {Promise<string>} - The ID of the created marker.
|
|
*/
|
|
async function createMarker(scene_id, primary_tag_id, seconds) {
|
|
const variables = {
|
|
scene_id: scene_id,
|
|
primary_tag_id: primary_tag_id,
|
|
seconds: seconds,
|
|
};
|
|
const query = `mutation SceneMarkerCreate($seconds: Float!, $scene_id: ID!, $primary_tag_id: ID!) {
|
|
sceneMarkerCreate(input: {title:"", seconds: $seconds, scene_id: $scene_id, primary_tag_id: $primary_tag_id}) {
|
|
id
|
|
}}`;
|
|
return csLib
|
|
.callGQL({ query, variables })
|
|
.then((data) => data.sceneMarkerCreate.id);
|
|
}
|
|
|
|
/**
|
|
* Retrieves all tags from the server and returns them as an object with tag names as keys and tag IDs as values.
|
|
* @returns {Promise<Object>} An object with tag names as keys and tag IDs as values.
|
|
*/
|
|
async function getAllTags() {
|
|
const query = `{
|
|
allTags{
|
|
id
|
|
name
|
|
aliases
|
|
}
|
|
}`;
|
|
var result = await csLib.callGQL({ query });
|
|
return result.allTags.reduce((map, obj) => {
|
|
map[obj.name.toLowerCase()] = obj.id;
|
|
obj.aliases.forEach((alias) => {
|
|
map[alias.toLowerCase()] = obj.id;
|
|
});
|
|
return map;
|
|
}, {});
|
|
}
|
|
|
|
/**
|
|
* Retrieves the URL of the sprite for a given scene ID.
|
|
* @param {number} scene_id - The ID of the scene to retrieve the sprite URL for.
|
|
* @returns {Promise<string|null>} - A Promise that resolves with the sprite URL if it exists, or null if it does not.
|
|
*/
|
|
async function getUrlSprite(scene_id) {
|
|
const query = `query { findScene(id: ${scene_id}){ paths{ sprite }} }`;
|
|
const url = await csLib
|
|
.callGQL({ query })
|
|
.then((data) => data.findScene.paths.sprite);
|
|
const response = await fetch(url);
|
|
return response.ok ? url : null;
|
|
}
|
|
|
|
function noop() {}
|
|
const identity = (x) => x;
|
|
function add_location(element, file, line, column, char) {
|
|
element.__svelte_meta = {
|
|
loc: { file, line, column, char },
|
|
};
|
|
}
|
|
function run(fn) {
|
|
return fn();
|
|
}
|
|
function blank_object() {
|
|
return Object.create(null);
|
|
}
|
|
function run_all(fns) {
|
|
fns.forEach(run);
|
|
}
|
|
function is_function(thing) {
|
|
return typeof thing === "function";
|
|
}
|
|
function safe_not_equal(a, b) {
|
|
return a != a
|
|
? b == b
|
|
: a !== b || (a && typeof a === "object") || typeof a === "function";
|
|
}
|
|
function is_empty(obj) {
|
|
return Object.keys(obj).length === 0;
|
|
}
|
|
function split_css_unit(value) {
|
|
const split =
|
|
typeof value === "string" && value.match(/^\s*(-?[\d.]+)([^\s]*)\s*$/);
|
|
return split ? [parseFloat(split[1]), split[2] || "px"] : [value, "px"];
|
|
}
|
|
|
|
const is_client = typeof window !== "undefined";
|
|
let now = is_client ? () => window.performance.now() : () => Date.now();
|
|
let raf = is_client ? (cb) => requestAnimationFrame(cb) : noop;
|
|
|
|
const tasks = new Set();
|
|
function run_tasks(now) {
|
|
tasks.forEach((task) => {
|
|
if (!task.c(now)) {
|
|
tasks.delete(task);
|
|
task.f();
|
|
}
|
|
});
|
|
if (tasks.size !== 0) raf(run_tasks);
|
|
}
|
|
/**
|
|
* Creates a new task that runs on each raf frame
|
|
* until it returns a falsy value or is aborted
|
|
*/
|
|
function loop(callback) {
|
|
let task;
|
|
if (tasks.size === 0) raf(run_tasks);
|
|
return {
|
|
promise: new Promise((fulfill) => {
|
|
tasks.add((task = { c: callback, f: fulfill }));
|
|
}),
|
|
abort() {
|
|
tasks.delete(task);
|
|
},
|
|
};
|
|
}
|
|
|
|
const globals =
|
|
typeof window !== "undefined"
|
|
? window
|
|
: typeof globalThis !== "undefined"
|
|
? globalThis
|
|
: global;
|
|
function append(target, node) {
|
|
target.appendChild(node);
|
|
}
|
|
function get_root_for_style(node) {
|
|
if (!node) return document;
|
|
const root = node.getRootNode ? node.getRootNode() : node.ownerDocument;
|
|
if (root && root.host) {
|
|
return root;
|
|
}
|
|
return node.ownerDocument;
|
|
}
|
|
function append_empty_stylesheet(node) {
|
|
const style_element = element("style");
|
|
append_stylesheet(get_root_for_style(node), style_element);
|
|
return style_element.sheet;
|
|
}
|
|
function append_stylesheet(node, style) {
|
|
append(node.head || node, style);
|
|
return style.sheet;
|
|
}
|
|
function insert(target, node, anchor) {
|
|
target.insertBefore(node, anchor || null);
|
|
}
|
|
function detach(node) {
|
|
if (node.parentNode) {
|
|
node.parentNode.removeChild(node);
|
|
}
|
|
}
|
|
function destroy_each(iterations, detaching) {
|
|
for (let i = 0; i < iterations.length; i += 1) {
|
|
if (iterations[i]) iterations[i].d(detaching);
|
|
}
|
|
}
|
|
function element(name) {
|
|
return document.createElement(name);
|
|
}
|
|
function svg_element(name) {
|
|
return document.createElementNS("http://www.w3.org/2000/svg", name);
|
|
}
|
|
function text(data) {
|
|
return document.createTextNode(data);
|
|
}
|
|
function space() {
|
|
return text(" ");
|
|
}
|
|
function empty() {
|
|
return text("");
|
|
}
|
|
function listen(node, event, handler, options) {
|
|
node.addEventListener(event, handler, options);
|
|
return () => node.removeEventListener(event, handler, options);
|
|
}
|
|
function attr(node, attribute, value) {
|
|
if (value == null) node.removeAttribute(attribute);
|
|
else if (node.getAttribute(attribute) !== value)
|
|
node.setAttribute(attribute, value);
|
|
}
|
|
function to_number(value) {
|
|
return value === "" ? null : +value;
|
|
}
|
|
function children(element) {
|
|
return Array.from(element.childNodes);
|
|
}
|
|
function set_input_value(input, value) {
|
|
input.value = value == null ? "" : value;
|
|
}
|
|
function set_style(node, key, value, important) {
|
|
if (value == null) {
|
|
node.style.removeProperty(key);
|
|
} else {
|
|
node.style.setProperty(key, value, important ? "important" : "");
|
|
}
|
|
}
|
|
function select_option(select, value, mounting) {
|
|
for (let i = 0; i < select.options.length; i += 1) {
|
|
const option = select.options[i];
|
|
if (option.__value === value) {
|
|
option.selected = true;
|
|
return;
|
|
}
|
|
}
|
|
if (!mounting || value !== undefined) {
|
|
select.selectedIndex = -1; // no option should be selected
|
|
}
|
|
}
|
|
function select_value(select) {
|
|
const selected_option = select.querySelector(":checked");
|
|
return selected_option && selected_option.__value;
|
|
}
|
|
function toggle_class(element, name, toggle) {
|
|
element.classList[toggle ? "add" : "remove"](name);
|
|
}
|
|
function custom_event(
|
|
type,
|
|
detail,
|
|
{ bubbles = false, cancelable = false } = {}
|
|
) {
|
|
const e = document.createEvent("CustomEvent");
|
|
e.initCustomEvent(type, bubbles, cancelable, detail);
|
|
return e;
|
|
}
|
|
|
|
// we need to store the information for multiple documents because a Svelte application could also contain iframes
|
|
// https://github.com/sveltejs/svelte/issues/3624
|
|
const managed_styles = new Map();
|
|
let active = 0;
|
|
// https://github.com/darkskyapp/string-hash/blob/master/index.js
|
|
function hash(str) {
|
|
let hash = 5381;
|
|
let i = str.length;
|
|
while (i--) hash = ((hash << 5) - hash) ^ str.charCodeAt(i);
|
|
return hash >>> 0;
|
|
}
|
|
function create_style_information(doc, node) {
|
|
const info = { stylesheet: append_empty_stylesheet(node), rules: {} };
|
|
managed_styles.set(doc, info);
|
|
return info;
|
|
}
|
|
function create_rule(node, a, b, duration, delay, ease, fn, uid = 0) {
|
|
const step = 16.666 / duration;
|
|
let keyframes = "{\n";
|
|
for (let p = 0; p <= 1; p += step) {
|
|
const t = a + (b - a) * ease(p);
|
|
keyframes += p * 100 + `%{${fn(t, 1 - t)}}\n`;
|
|
}
|
|
const rule = keyframes + `100% {${fn(b, 1 - b)}}\n}`;
|
|
const name = `__svelte_${hash(rule)}_${uid}`;
|
|
const doc = get_root_for_style(node);
|
|
const { stylesheet, rules } =
|
|
managed_styles.get(doc) || create_style_information(doc, node);
|
|
if (!rules[name]) {
|
|
rules[name] = true;
|
|
stylesheet.insertRule(
|
|
`@keyframes ${name} ${rule}`,
|
|
stylesheet.cssRules.length
|
|
);
|
|
}
|
|
const animation = node.style.animation || "";
|
|
node.style.animation = `${animation ? `${animation}, ` : ""}${name} ${duration}ms linear ${delay}ms 1 both`;
|
|
active += 1;
|
|
return name;
|
|
}
|
|
function delete_rule(node, name) {
|
|
const previous = (node.style.animation || "").split(", ");
|
|
const next = previous.filter(
|
|
name
|
|
? (anim) => anim.indexOf(name) < 0 // remove specific animation
|
|
: (anim) => anim.indexOf("__svelte") === -1 // remove all Svelte animations
|
|
);
|
|
const deleted = previous.length - next.length;
|
|
if (deleted) {
|
|
node.style.animation = next.join(", ");
|
|
active -= deleted;
|
|
if (!active) clear_rules();
|
|
}
|
|
}
|
|
function clear_rules() {
|
|
raf(() => {
|
|
if (active) return;
|
|
managed_styles.forEach((info) => {
|
|
const { ownerNode } = info.stylesheet;
|
|
// there is no ownerNode if it runs on jsdom.
|
|
if (ownerNode) detach(ownerNode);
|
|
});
|
|
managed_styles.clear();
|
|
});
|
|
}
|
|
|
|
function create_animation(node, from, fn, params) {
|
|
if (!from) return noop;
|
|
const to = node.getBoundingClientRect();
|
|
if (
|
|
from.left === to.left &&
|
|
from.right === to.right &&
|
|
from.top === to.top &&
|
|
from.bottom === to.bottom
|
|
)
|
|
return noop;
|
|
const {
|
|
delay = 0,
|
|
duration = 300,
|
|
easing = identity,
|
|
// @ts-ignore todo: should this be separated from destructuring? Or start/end added to public api and documentation?
|
|
start: start_time = now() + delay,
|
|
// @ts-ignore todo:
|
|
end = start_time + duration,
|
|
tick = noop,
|
|
css,
|
|
} = fn(node, { from, to }, params);
|
|
let running = true;
|
|
let started = false;
|
|
let name;
|
|
function start() {
|
|
if (css) {
|
|
name = create_rule(node, 0, 1, duration, delay, easing, css);
|
|
}
|
|
if (!delay) {
|
|
started = true;
|
|
}
|
|
}
|
|
function stop() {
|
|
if (css) delete_rule(node, name);
|
|
running = false;
|
|
}
|
|
loop((now) => {
|
|
if (!started && now >= start_time) {
|
|
started = true;
|
|
}
|
|
if (started && now >= end) {
|
|
tick(1, 0);
|
|
stop();
|
|
}
|
|
if (!running) {
|
|
return false;
|
|
}
|
|
if (started) {
|
|
const p = now - start_time;
|
|
const t = 0 + 1 * easing(p / duration);
|
|
tick(t, 1 - t);
|
|
}
|
|
return true;
|
|
});
|
|
start();
|
|
tick(0, 1);
|
|
return stop;
|
|
}
|
|
function fix_position(node) {
|
|
const style = getComputedStyle(node);
|
|
if (style.position !== "absolute" && style.position !== "fixed") {
|
|
const { width, height } = style;
|
|
const a = node.getBoundingClientRect();
|
|
node.style.position = "absolute";
|
|
node.style.width = width;
|
|
node.style.height = height;
|
|
add_transform(node, a);
|
|
}
|
|
}
|
|
function add_transform(node, a) {
|
|
const b = node.getBoundingClientRect();
|
|
if (a.left !== b.left || a.top !== b.top) {
|
|
const style = getComputedStyle(node);
|
|
const transform = style.transform === "none" ? "" : style.transform;
|
|
node.style.transform = `${transform} translate(${a.left - b.left}px, ${a.top - b.top}px)`;
|
|
}
|
|
}
|
|
|
|
let current_component;
|
|
function set_current_component(component) {
|
|
current_component = component;
|
|
}
|
|
function get_current_component() {
|
|
if (!current_component)
|
|
throw new Error("Function called outside component initialization");
|
|
return current_component;
|
|
}
|
|
/**
|
|
* The `onMount` function schedules a callback to run as soon as the component has been mounted to the DOM.
|
|
* It must be called during the component's initialisation (but doesn't need to live *inside* the component;
|
|
* it can be called from an external module).
|
|
*
|
|
* `onMount` does not run inside a [server-side component](/docs#run-time-server-side-component-api).
|
|
*
|
|
* https://svelte.dev/docs#run-time-svelte-onmount
|
|
*/
|
|
function onMount(fn) {
|
|
get_current_component().$$.on_mount.push(fn);
|
|
}
|
|
/**
|
|
* Creates an event dispatcher that can be used to dispatch [component events](/docs#template-syntax-component-directives-on-eventname).
|
|
* Event dispatchers are functions that can take two arguments: `name` and `detail`.
|
|
*
|
|
* Component events created with `createEventDispatcher` create a
|
|
* [CustomEvent](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent).
|
|
* These events do not [bubble](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events#Event_bubbling_and_capture).
|
|
* The `detail` argument corresponds to the [CustomEvent.detail](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/detail)
|
|
* property and can contain any type of data.
|
|
*
|
|
* https://svelte.dev/docs#run-time-svelte-createeventdispatcher
|
|
*/
|
|
function createEventDispatcher() {
|
|
const component = get_current_component();
|
|
return (type, detail, { cancelable = false } = {}) => {
|
|
const callbacks = component.$$.callbacks[type];
|
|
if (callbacks) {
|
|
// TODO are there situations where events could be dispatched
|
|
// in a server (non-DOM) environment?
|
|
const event = custom_event(type, detail, { cancelable });
|
|
callbacks.slice().forEach((fn) => {
|
|
fn.call(component, event);
|
|
});
|
|
return !event.defaultPrevented;
|
|
}
|
|
return true;
|
|
};
|
|
}
|
|
|
|
const dirty_components = [];
|
|
const binding_callbacks = [];
|
|
let render_callbacks = [];
|
|
const flush_callbacks = [];
|
|
const resolved_promise = /* @__PURE__ */ Promise.resolve();
|
|
let update_scheduled = false;
|
|
function schedule_update() {
|
|
if (!update_scheduled) {
|
|
update_scheduled = true;
|
|
resolved_promise.then(flush);
|
|
}
|
|
}
|
|
function add_render_callback(fn) {
|
|
render_callbacks.push(fn);
|
|
}
|
|
function add_flush_callback(fn) {
|
|
flush_callbacks.push(fn);
|
|
}
|
|
// flush() calls callbacks in this order:
|
|
// 1. All beforeUpdate callbacks, in order: parents before children
|
|
// 2. All bind:this callbacks, in reverse order: children before parents.
|
|
// 3. All afterUpdate callbacks, in order: parents before children. EXCEPT
|
|
// for afterUpdates called during the initial onMount, which are called in
|
|
// reverse order: children before parents.
|
|
// Since callbacks might update component values, which could trigger another
|
|
// call to flush(), the following steps guard against this:
|
|
// 1. During beforeUpdate, any updated components will be added to the
|
|
// dirty_components array and will cause a reentrant call to flush(). Because
|
|
// the flush index is kept outside the function, the reentrant call will pick
|
|
// up where the earlier call left off and go through all dirty components. The
|
|
// current_component value is saved and restored so that the reentrant call will
|
|
// not interfere with the "parent" flush() call.
|
|
// 2. bind:this callbacks cannot trigger new flush() calls.
|
|
// 3. During afterUpdate, any updated components will NOT have their afterUpdate
|
|
// callback called a second time; the seen_callbacks set, outside the flush()
|
|
// function, guarantees this behavior.
|
|
const seen_callbacks = new Set();
|
|
let flushidx = 0; // Do *not* move this inside the flush() function
|
|
function flush() {
|
|
// Do not reenter flush while dirty components are updated, as this can
|
|
// result in an infinite loop. Instead, let the inner flush handle it.
|
|
// Reentrancy is ok afterwards for bindings etc.
|
|
if (flushidx !== 0) {
|
|
return;
|
|
}
|
|
const saved_component = current_component;
|
|
do {
|
|
// first, call beforeUpdate functions
|
|
// and update components
|
|
try {
|
|
while (flushidx < dirty_components.length) {
|
|
const component = dirty_components[flushidx];
|
|
flushidx++;
|
|
set_current_component(component);
|
|
update(component.$$);
|
|
}
|
|
} catch (e) {
|
|
// reset dirty state to not end up in a deadlocked state and then rethrow
|
|
dirty_components.length = 0;
|
|
flushidx = 0;
|
|
throw e;
|
|
}
|
|
set_current_component(null);
|
|
dirty_components.length = 0;
|
|
flushidx = 0;
|
|
while (binding_callbacks.length) binding_callbacks.pop()();
|
|
// then, once components are updated, call
|
|
// afterUpdate functions. This may cause
|
|
// subsequent updates...
|
|
for (let i = 0; i < render_callbacks.length; i += 1) {
|
|
const callback = render_callbacks[i];
|
|
if (!seen_callbacks.has(callback)) {
|
|
// ...so guard against infinite loops
|
|
seen_callbacks.add(callback);
|
|
callback();
|
|
}
|
|
}
|
|
render_callbacks.length = 0;
|
|
} while (dirty_components.length);
|
|
while (flush_callbacks.length) {
|
|
flush_callbacks.pop()();
|
|
}
|
|
update_scheduled = false;
|
|
seen_callbacks.clear();
|
|
set_current_component(saved_component);
|
|
}
|
|
function update($$) {
|
|
if ($$.fragment !== null) {
|
|
$$.update();
|
|
run_all($$.before_update);
|
|
const dirty = $$.dirty;
|
|
$$.dirty = [-1];
|
|
$$.fragment && $$.fragment.p($$.ctx, dirty);
|
|
$$.after_update.forEach(add_render_callback);
|
|
}
|
|
}
|
|
/**
|
|
* Useful for example to execute remaining `afterUpdate` callbacks before executing `destroy`.
|
|
*/
|
|
function flush_render_callbacks(fns) {
|
|
const filtered = [];
|
|
const targets = [];
|
|
render_callbacks.forEach((c) =>
|
|
fns.indexOf(c) === -1 ? filtered.push(c) : targets.push(c)
|
|
);
|
|
targets.forEach((c) => c());
|
|
render_callbacks = filtered;
|
|
}
|
|
|
|
let promise;
|
|
function wait() {
|
|
if (!promise) {
|
|
promise = Promise.resolve();
|
|
promise.then(() => {
|
|
promise = null;
|
|
});
|
|
}
|
|
return promise;
|
|
}
|
|
function dispatch(node, direction, kind) {
|
|
node.dispatchEvent(custom_event(`${direction ? "intro" : "outro"}${kind}`));
|
|
}
|
|
const outroing = new Set();
|
|
let outros;
|
|
function group_outros() {
|
|
outros = {
|
|
r: 0,
|
|
c: [],
|
|
p: outros, // parent group
|
|
};
|
|
}
|
|
function check_outros() {
|
|
if (!outros.r) {
|
|
run_all(outros.c);
|
|
}
|
|
outros = outros.p;
|
|
}
|
|
function transition_in(block, local) {
|
|
if (block && block.i) {
|
|
outroing.delete(block);
|
|
block.i(local);
|
|
}
|
|
}
|
|
function transition_out(block, local, detach, callback) {
|
|
if (block && block.o) {
|
|
if (outroing.has(block)) return;
|
|
outroing.add(block);
|
|
outros.c.push(() => {
|
|
outroing.delete(block);
|
|
if (callback) {
|
|
if (detach) block.d(1);
|
|
callback();
|
|
}
|
|
});
|
|
block.o(local);
|
|
} else if (callback) {
|
|
callback();
|
|
}
|
|
}
|
|
const null_transition = { duration: 0 };
|
|
function create_in_transition(node, fn, params) {
|
|
const options = { direction: "in" };
|
|
let config = fn(node, params, options);
|
|
let running = false;
|
|
let animation_name;
|
|
let task;
|
|
let uid = 0;
|
|
function cleanup() {
|
|
if (animation_name) delete_rule(node, animation_name);
|
|
}
|
|
function go() {
|
|
const {
|
|
delay = 0,
|
|
duration = 300,
|
|
easing = identity,
|
|
tick = noop,
|
|
css,
|
|
} = config || null_transition;
|
|
if (css)
|
|
animation_name = create_rule(
|
|
node,
|
|
0,
|
|
1,
|
|
duration,
|
|
delay,
|
|
easing,
|
|
css,
|
|
uid++
|
|
);
|
|
tick(0, 1);
|
|
const start_time = now() + delay;
|
|
const end_time = start_time + duration;
|
|
if (task) task.abort();
|
|
running = true;
|
|
add_render_callback(() => dispatch(node, true, "start"));
|
|
task = loop((now) => {
|
|
if (running) {
|
|
if (now >= end_time) {
|
|
tick(1, 0);
|
|
dispatch(node, true, "end");
|
|
cleanup();
|
|
return (running = false);
|
|
}
|
|
if (now >= start_time) {
|
|
const t = easing((now - start_time) / duration);
|
|
tick(t, 1 - t);
|
|
}
|
|
}
|
|
return running;
|
|
});
|
|
}
|
|
let started = false;
|
|
return {
|
|
start() {
|
|
if (started) return;
|
|
started = true;
|
|
delete_rule(node);
|
|
if (is_function(config)) {
|
|
config = config(options);
|
|
wait().then(go);
|
|
} else {
|
|
go();
|
|
}
|
|
},
|
|
invalidate() {
|
|
started = false;
|
|
},
|
|
end() {
|
|
if (running) {
|
|
cleanup();
|
|
running = false;
|
|
}
|
|
},
|
|
};
|
|
}
|
|
function create_out_transition(node, fn, params) {
|
|
const options = { direction: "out" };
|
|
let config = fn(node, params, options);
|
|
let running = true;
|
|
let animation_name;
|
|
const group = outros;
|
|
group.r += 1;
|
|
function go() {
|
|
const {
|
|
delay = 0,
|
|
duration = 300,
|
|
easing = identity,
|
|
tick = noop,
|
|
css,
|
|
} = config || null_transition;
|
|
if (css)
|
|
animation_name = create_rule(node, 1, 0, duration, delay, easing, css);
|
|
const start_time = now() + delay;
|
|
const end_time = start_time + duration;
|
|
add_render_callback(() => dispatch(node, false, "start"));
|
|
loop((now) => {
|
|
if (running) {
|
|
if (now >= end_time) {
|
|
tick(0, 1);
|
|
dispatch(node, false, "end");
|
|
if (!--group.r) {
|
|
// this will result in `end()` being called,
|
|
// so we don't need to clean up here
|
|
run_all(group.c);
|
|
}
|
|
return false;
|
|
}
|
|
if (now >= start_time) {
|
|
const t = easing((now - start_time) / duration);
|
|
tick(1 - t, t);
|
|
}
|
|
}
|
|
return running;
|
|
});
|
|
}
|
|
if (is_function(config)) {
|
|
wait().then(() => {
|
|
// @ts-ignore
|
|
config = config(options);
|
|
go();
|
|
});
|
|
} else {
|
|
go();
|
|
}
|
|
return {
|
|
end(reset) {
|
|
if (reset && config.tick) {
|
|
config.tick(1, 0);
|
|
}
|
|
if (running) {
|
|
if (animation_name) delete_rule(node, animation_name);
|
|
running = false;
|
|
}
|
|
},
|
|
};
|
|
}
|
|
function outro_and_destroy_block(block, lookup) {
|
|
transition_out(block, 1, 1, () => {
|
|
lookup.delete(block.key);
|
|
});
|
|
}
|
|
function fix_and_outro_and_destroy_block(block, lookup) {
|
|
block.f();
|
|
outro_and_destroy_block(block, lookup);
|
|
}
|
|
function update_keyed_each(
|
|
old_blocks,
|
|
dirty,
|
|
get_key,
|
|
dynamic,
|
|
ctx,
|
|
list,
|
|
lookup,
|
|
node,
|
|
destroy,
|
|
create_each_block,
|
|
next,
|
|
get_context
|
|
) {
|
|
let o = old_blocks.length;
|
|
let n = list.length;
|
|
let i = o;
|
|
const old_indexes = {};
|
|
while (i--) old_indexes[old_blocks[i].key] = i;
|
|
const new_blocks = [];
|
|
const new_lookup = new Map();
|
|
const deltas = new Map();
|
|
const updates = [];
|
|
i = n;
|
|
while (i--) {
|
|
const child_ctx = get_context(ctx, list, i);
|
|
const key = get_key(child_ctx);
|
|
let block = lookup.get(key);
|
|
if (!block) {
|
|
block = create_each_block(key, child_ctx);
|
|
block.c();
|
|
} else if (dynamic) {
|
|
// defer updates until all the DOM shuffling is done
|
|
updates.push(() => block.p(child_ctx, dirty));
|
|
}
|
|
new_lookup.set(key, (new_blocks[i] = block));
|
|
if (key in old_indexes) deltas.set(key, Math.abs(i - old_indexes[key]));
|
|
}
|
|
const will_move = new Set();
|
|
const did_move = new Set();
|
|
function insert(block) {
|
|
transition_in(block, 1);
|
|
block.m(node, next);
|
|
lookup.set(block.key, block);
|
|
next = block.first;
|
|
n--;
|
|
}
|
|
while (o && n) {
|
|
const new_block = new_blocks[n - 1];
|
|
const old_block = old_blocks[o - 1];
|
|
const new_key = new_block.key;
|
|
const old_key = old_block.key;
|
|
if (new_block === old_block) {
|
|
// do nothing
|
|
next = new_block.first;
|
|
o--;
|
|
n--;
|
|
} else if (!new_lookup.has(old_key)) {
|
|
// remove old block
|
|
destroy(old_block, lookup);
|
|
o--;
|
|
} else if (!lookup.has(new_key) || will_move.has(new_key)) {
|
|
insert(new_block);
|
|
} else if (did_move.has(old_key)) {
|
|
o--;
|
|
} else if (deltas.get(new_key) > deltas.get(old_key)) {
|
|
did_move.add(new_key);
|
|
insert(new_block);
|
|
} else {
|
|
will_move.add(old_key);
|
|
o--;
|
|
}
|
|
}
|
|
while (o--) {
|
|
const old_block = old_blocks[o];
|
|
if (!new_lookup.has(old_block.key)) destroy(old_block, lookup);
|
|
}
|
|
while (n) insert(new_blocks[n - 1]);
|
|
run_all(updates);
|
|
return new_blocks;
|
|
}
|
|
function validate_each_keys(ctx, list, get_context, get_key) {
|
|
const keys = new Set();
|
|
for (let i = 0; i < list.length; i++) {
|
|
const key = get_key(get_context(ctx, list, i));
|
|
if (keys.has(key)) {
|
|
throw new Error("Cannot have duplicate keys in a keyed each");
|
|
}
|
|
keys.add(key);
|
|
}
|
|
}
|
|
|
|
function bind(component, name, callback) {
|
|
const index = component.$$.props[name];
|
|
if (index !== undefined) {
|
|
component.$$.bound[index] = callback;
|
|
callback(component.$$.ctx[index]);
|
|
}
|
|
}
|
|
function create_component(block) {
|
|
block && block.c();
|
|
}
|
|
function mount_component(component, target, anchor, customElement) {
|
|
const { fragment, after_update } = component.$$;
|
|
fragment && fragment.m(target, anchor);
|
|
if (!customElement) {
|
|
// onMount happens before the initial afterUpdate
|
|
add_render_callback(() => {
|
|
const new_on_destroy = component.$$.on_mount
|
|
.map(run)
|
|
.filter(is_function);
|
|
// if the component was destroyed immediately
|
|
// it will update the `$$.on_destroy` reference to `null`.
|
|
// the destructured on_destroy may still reference to the old array
|
|
if (component.$$.on_destroy) {
|
|
component.$$.on_destroy.push(...new_on_destroy);
|
|
} else {
|
|
// Edge case - component was destroyed immediately,
|
|
// most likely as a result of a binding initialising
|
|
run_all(new_on_destroy);
|
|
}
|
|
component.$$.on_mount = [];
|
|
});
|
|
}
|
|
after_update.forEach(add_render_callback);
|
|
}
|
|
function destroy_component(component, detaching) {
|
|
const $$ = component.$$;
|
|
if ($$.fragment !== null) {
|
|
flush_render_callbacks($$.after_update);
|
|
run_all($$.on_destroy);
|
|
$$.fragment && $$.fragment.d(detaching);
|
|
// TODO null out other refs, including component.$$ (but need to
|
|
// preserve final state?)
|
|
$$.on_destroy = $$.fragment = null;
|
|
$$.ctx = [];
|
|
}
|
|
}
|
|
function make_dirty(component, i) {
|
|
if (component.$$.dirty[0] === -1) {
|
|
dirty_components.push(component);
|
|
schedule_update();
|
|
component.$$.dirty.fill(0);
|
|
}
|
|
component.$$.dirty[(i / 31) | 0] |= 1 << i % 31;
|
|
}
|
|
function init(
|
|
component,
|
|
options,
|
|
instance,
|
|
create_fragment,
|
|
not_equal,
|
|
props,
|
|
append_styles,
|
|
dirty = [-1]
|
|
) {
|
|
const parent_component = current_component;
|
|
set_current_component(component);
|
|
const $$ = (component.$$ = {
|
|
fragment: null,
|
|
ctx: [],
|
|
// state
|
|
props,
|
|
update: noop,
|
|
not_equal,
|
|
bound: blank_object(),
|
|
// lifecycle
|
|
on_mount: [],
|
|
on_destroy: [],
|
|
on_disconnect: [],
|
|
before_update: [],
|
|
after_update: [],
|
|
context: new Map(
|
|
options.context || (parent_component ? parent_component.$$.context : [])
|
|
),
|
|
// everything else
|
|
callbacks: blank_object(),
|
|
dirty,
|
|
skip_bound: false,
|
|
root: options.target || parent_component.$$.root,
|
|
});
|
|
append_styles && append_styles($$.root);
|
|
let ready = false;
|
|
$$.ctx = instance
|
|
? instance(component, options.props || {}, (i, ret, ...rest) => {
|
|
const value = rest.length ? rest[0] : ret;
|
|
if ($$.ctx && not_equal($$.ctx[i], ($$.ctx[i] = value))) {
|
|
if (!$$.skip_bound && $$.bound[i]) $$.bound[i](value);
|
|
if (ready) make_dirty(component, i);
|
|
}
|
|
return ret;
|
|
})
|
|
: [];
|
|
$$.update();
|
|
ready = true;
|
|
run_all($$.before_update);
|
|
// `false` as a special case of no DOM component
|
|
$$.fragment = create_fragment ? create_fragment($$.ctx) : false;
|
|
if (options.target) {
|
|
if (options.hydrate) {
|
|
const nodes = children(options.target);
|
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
$$.fragment && $$.fragment.l(nodes);
|
|
nodes.forEach(detach);
|
|
} else {
|
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
$$.fragment && $$.fragment.c();
|
|
}
|
|
if (options.intro) transition_in(component.$$.fragment);
|
|
mount_component(
|
|
component,
|
|
options.target,
|
|
options.anchor,
|
|
options.customElement
|
|
);
|
|
flush();
|
|
}
|
|
set_current_component(parent_component);
|
|
}
|
|
/**
|
|
* Base class for Svelte components. Used when dev=false.
|
|
*/
|
|
class SvelteComponent {
|
|
$destroy() {
|
|
destroy_component(this, 1);
|
|
this.$destroy = noop;
|
|
}
|
|
$on(type, callback) {
|
|
if (!is_function(callback)) {
|
|
return noop;
|
|
}
|
|
const callbacks =
|
|
this.$$.callbacks[type] || (this.$$.callbacks[type] = []);
|
|
callbacks.push(callback);
|
|
return () => {
|
|
const index = callbacks.indexOf(callback);
|
|
if (index !== -1) callbacks.splice(index, 1);
|
|
};
|
|
}
|
|
$set($$props) {
|
|
if (this.$$set && !is_empty($$props)) {
|
|
this.$$.skip_bound = true;
|
|
this.$$set($$props);
|
|
this.$$.skip_bound = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
function dispatch_dev(type, detail) {
|
|
document.dispatchEvent(
|
|
custom_event(type, Object.assign({ version: "3.59.2" }, detail), {
|
|
bubbles: true,
|
|
})
|
|
);
|
|
}
|
|
function append_dev(target, node) {
|
|
dispatch_dev("SvelteDOMInsert", { target, node });
|
|
append(target, node);
|
|
}
|
|
function insert_dev(target, node, anchor) {
|
|
dispatch_dev("SvelteDOMInsert", { target, node, anchor });
|
|
insert(target, node, anchor);
|
|
}
|
|
function detach_dev(node) {
|
|
dispatch_dev("SvelteDOMRemove", { node });
|
|
detach(node);
|
|
}
|
|
function listen_dev(
|
|
node,
|
|
event,
|
|
handler,
|
|
options,
|
|
has_prevent_default,
|
|
has_stop_propagation,
|
|
has_stop_immediate_propagation
|
|
) {
|
|
const modifiers =
|
|
options === true
|
|
? ["capture"]
|
|
: options
|
|
? Array.from(Object.keys(options))
|
|
: [];
|
|
if (has_prevent_default) modifiers.push("preventDefault");
|
|
if (has_stop_propagation) modifiers.push("stopPropagation");
|
|
if (has_stop_immediate_propagation)
|
|
modifiers.push("stopImmediatePropagation");
|
|
dispatch_dev("SvelteDOMAddEventListener", {
|
|
node,
|
|
event,
|
|
handler,
|
|
modifiers,
|
|
});
|
|
const dispose = listen(node, event, handler, options);
|
|
return () => {
|
|
dispatch_dev("SvelteDOMRemoveEventListener", {
|
|
node,
|
|
event,
|
|
handler,
|
|
modifiers,
|
|
});
|
|
dispose();
|
|
};
|
|
}
|
|
function attr_dev(node, attribute, value) {
|
|
attr(node, attribute, value);
|
|
if (value == null)
|
|
dispatch_dev("SvelteDOMRemoveAttribute", { node, attribute });
|
|
else dispatch_dev("SvelteDOMSetAttribute", { node, attribute, value });
|
|
}
|
|
function set_data_dev(text, data) {
|
|
data = "" + data;
|
|
if (text.data === data) return;
|
|
dispatch_dev("SvelteDOMSetData", { node: text, data });
|
|
text.data = data;
|
|
}
|
|
function validate_each_argument(arg) {
|
|
if (
|
|
typeof arg !== "string" &&
|
|
!(arg && typeof arg === "object" && "length" in arg)
|
|
) {
|
|
let msg = "{#each} only iterates over array-like objects.";
|
|
if (typeof Symbol === "function" && arg && Symbol.iterator in arg) {
|
|
msg += " You can use a spread to convert this iterable into an array.";
|
|
}
|
|
throw new Error(msg);
|
|
}
|
|
}
|
|
function validate_slots(name, slot, keys) {
|
|
for (const slot_key of Object.keys(slot)) {
|
|
if (!~keys.indexOf(slot_key)) {
|
|
console.warn(`<${name}> received an unexpected slot "${slot_key}".`);
|
|
}
|
|
}
|
|
}
|
|
/**
|
|
* Base class for Svelte components with some minor dev-enhancements. Used when dev=true.
|
|
*/
|
|
class SvelteComponentDev extends SvelteComponent {
|
|
constructor(options) {
|
|
if (!options || (!options.target && !options.$$inline)) {
|
|
throw new Error("'target' is a required option");
|
|
}
|
|
super();
|
|
}
|
|
$destroy() {
|
|
super.$destroy();
|
|
this.$destroy = () => {
|
|
console.warn("Component was already destroyed"); // eslint-disable-line no-console
|
|
};
|
|
}
|
|
$capture_state() {}
|
|
$inject_state() {}
|
|
}
|
|
|
|
/* src/Marker.svelte generated by Svelte v3.59.2 */
|
|
const file$5 = "src/Marker.svelte";
|
|
|
|
function get_each_context$3(ctx, list, i) {
|
|
const child_ctx = ctx.slice();
|
|
child_ctx[7] = list[i];
|
|
return child_ctx;
|
|
}
|
|
|
|
// (92:6) {#each OPTIONS as name}
|
|
function create_each_block$3(ctx) {
|
|
let option;
|
|
let t_value = /*name*/ ctx[7] + "";
|
|
let t;
|
|
|
|
const block = {
|
|
c: function create() {
|
|
option = element("option");
|
|
t = text(t_value);
|
|
set_style(option, "background-color", "var(--gray)");
|
|
option.__value = /*name*/ ctx[7];
|
|
option.value = option.__value;
|
|
add_location(option, file$5, 92, 8, 3418);
|
|
},
|
|
m: function mount(target, anchor) {
|
|
insert_dev(target, option, anchor);
|
|
append_dev(option, t);
|
|
},
|
|
p: noop,
|
|
d: function destroy(detaching) {
|
|
if (detaching) detach_dev(option);
|
|
},
|
|
};
|
|
|
|
dispatch_dev("SvelteRegisterBlock", {
|
|
block,
|
|
id: create_each_block$3.name,
|
|
type: "each",
|
|
source: "(92:6) {#each OPTIONS as name}",
|
|
ctx,
|
|
});
|
|
|
|
return block;
|
|
}
|
|
|
|
function create_fragment$5(ctx) {
|
|
let div4;
|
|
let div0;
|
|
let div0_data_offset_value;
|
|
let t0;
|
|
let div2;
|
|
let div1;
|
|
let div1_class_value;
|
|
let div1_aria_valuenow_value;
|
|
let t1;
|
|
let span;
|
|
let div3;
|
|
let svg0;
|
|
let path0;
|
|
let t2;
|
|
let select;
|
|
let t3;
|
|
let svg1;
|
|
let path1;
|
|
let mounted;
|
|
let dispose;
|
|
let each_value = OPTIONS;
|
|
validate_each_argument(each_value);
|
|
let each_blocks = [];
|
|
|
|
for (let i = 0; i < each_value.length; i += 1) {
|
|
each_blocks[i] = create_each_block$3(
|
|
get_each_context$3(ctx, each_value, i)
|
|
);
|
|
}
|
|
|
|
const block = {
|
|
c: function create() {
|
|
div4 = element("div");
|
|
div0 = element("div");
|
|
t0 = space();
|
|
div2 = element("div");
|
|
div1 = element("div");
|
|
t1 = space();
|
|
span = element("span");
|
|
div3 = element("div");
|
|
svg0 = svg_element("svg");
|
|
path0 = svg_element("path");
|
|
t2 = space();
|
|
select = element("select");
|
|
|
|
for (let i = 0; i < each_blocks.length; i += 1) {
|
|
each_blocks[i].c();
|
|
}
|
|
|
|
t3 = space();
|
|
svg1 = svg_element("svg");
|
|
path1 = svg_element("path");
|
|
attr_dev(div0, "class", "scrubber-item svelte-zeu5yg");
|
|
set_style(
|
|
div0,
|
|
"background-position",
|
|
"-" +
|
|
/*frame*/ ctx[0].offset[0] +
|
|
"px -" +
|
|
/*frame*/ ctx[0].offset[1] +
|
|
"px"
|
|
);
|
|
set_style(div0, "background-image", "url('" + /*url*/ ctx[1] + "')");
|
|
attr_dev(
|
|
div0,
|
|
"data-offset",
|
|
(div0_data_offset_value = /*frame*/ ctx[0].offset)
|
|
);
|
|
add_location(div0, file$5, 47, 2, 1619);
|
|
attr_dev(
|
|
div1,
|
|
"class",
|
|
(div1_class_value =
|
|
"progress-bar progress-bar-striped bg-" +
|
|
confidence$1(/*frame*/ ctx[0].tag.prob) +
|
|
" svelte-zeu5yg")
|
|
);
|
|
attr_dev(div1, "role", "progressbar");
|
|
set_style(div1, "width", /*frame*/ ctx[0].tag.prob * 100 + "%");
|
|
attr_dev(
|
|
div1,
|
|
"aria-valuenow",
|
|
(div1_aria_valuenow_value = /*frame*/ ctx[0].tag.prob * 100)
|
|
);
|
|
attr_dev(div1, "aria-valuemin", 0);
|
|
attr_dev(div1, "aria-valuemax", 100);
|
|
add_location(div1, file$5, 59, 4, 1978);
|
|
attr_dev(div2, "class", "progress");
|
|
set_style(div2, "height", "5px");
|
|
add_location(div2, file$5, 58, 2, 1931);
|
|
attr_dev(
|
|
path0,
|
|
"d",
|
|
"M313.4 32.9c26 5.2 42.9 30.5 37.7 56.5l-2.3 11.4c-5.3 26.7-15.1 52.1-28.8 75.2H464c26.5 0 48 21.5 48 48c0 18.5-10.5 34.6-25.9 42.6C497 275.4 504 288.9 504 304c0 23.4-16.8 42.9-38.9 47.1c4.4 7.3 6.9 15.8 6.9 24.9c0 21.3-13.9 39.4-33.1 45.6c.7 3.3 1.1 6.8 1.1 10.4c0 26.5-21.5 48-48 48H294.5c-19 0-37.5-5.6-53.3-16.1l-38.5-25.7C176 420.4 160 390.4 160 358.3V320 272 247.1c0-29.2 13.3-56.7 36-75l7.4-5.9c26.5-21.2 44.6-51 51.2-84.2l2.3-11.4c5.2-26 30.5-42.9 56.5-37.7zM32 192H96c17.7 0 32 14.3 32 32V448c0 17.7-14.3 32-32 32H32c-17.7 0-32-14.3-32-32V224c0-17.7 14.3-32 32-32z"
|
|
);
|
|
add_location(path0, file$5, 81, 9, 2640);
|
|
attr_dev(svg0, "class", "tag-item-accept svelte-zeu5yg");
|
|
attr_dev(svg0, "xmlns", "http://www.w3.org/2000/svg");
|
|
attr_dev(svg0, "height", "1em");
|
|
attr_dev(svg0, "viewBox", "0 0 512 512");
|
|
add_location(svg0, file$5, 76, 6, 2500);
|
|
set_style(div3, "padding-right", "10px");
|
|
set_style(div3, "display", "inline");
|
|
add_location(div3, file$5, 70, 4, 2355);
|
|
set_style(select, "color", "#f5f8fa");
|
|
attr_dev(select, "class", "tag-item-select svelte-zeu5yg");
|
|
if (/*frame*/ ctx[0].tag.label === void 0)
|
|
add_render_callback(() =>
|
|
/*select_change_handler*/ ctx[5].call(select)
|
|
);
|
|
add_location(select, file$5, 86, 4, 3272);
|
|
attr_dev(
|
|
path1,
|
|
"d",
|
|
"M14.348 14.849c-0.469 0.469-1.229 0.469-1.697 0l-2.651-3.030-2.651 3.029c-0.469 0.469-1.229 0.469-1.697 0-0.469-0.469-0.469-1.229 0-1.697l2.758-3.15-2.759-3.152c-0.469-0.469-0.469-1.228 0-1.697s1.228-0.469 1.697 0l2.652 3.031 2.651-3.031c0.469-0.469 1.228-0.469 1.697 0s0.469 1.229 0 1.697l-2.758 3.152 2.758 3.15c0.469 0.469 0.469 1.229 0 1.698z"
|
|
);
|
|
add_location(path1, file$5, 105, 7, 3754);
|
|
attr_dev(svg1, "height", "20");
|
|
attr_dev(svg1, "width", "20");
|
|
attr_dev(svg1, "viewBox", "0 0 20 20");
|
|
attr_dev(svg1, "aria-hidden", "true");
|
|
attr_dev(svg1, "focusable", "false");
|
|
attr_dev(svg1, "class", "tag-item-reject svelte-zeu5yg");
|
|
add_location(svg1, file$5, 95, 4, 3526);
|
|
attr_dev(span, "class", "tag-item badge badge-secondary svelte-zeu5yg");
|
|
add_location(span, file$5, 68, 2, 2244);
|
|
set_style(div4, "padding", "10px");
|
|
add_location(div4, file$5, 45, 0, 1529);
|
|
},
|
|
l: function claim(nodes) {
|
|
throw new Error(
|
|
"options.hydrate only works if the component was compiled with the `hydratable: true` option"
|
|
);
|
|
},
|
|
m: function mount(target, anchor) {
|
|
insert_dev(target, div4, anchor);
|
|
append_dev(div4, div0);
|
|
append_dev(div4, t0);
|
|
append_dev(div4, div2);
|
|
append_dev(div2, div1);
|
|
append_dev(div4, t1);
|
|
append_dev(div4, span);
|
|
append_dev(span, div3);
|
|
append_dev(div3, svg0);
|
|
append_dev(svg0, path0);
|
|
append_dev(span, t2);
|
|
append_dev(span, select);
|
|
|
|
for (let i = 0; i < each_blocks.length; i += 1) {
|
|
if (each_blocks[i]) {
|
|
each_blocks[i].m(select, null);
|
|
}
|
|
}
|
|
|
|
select_option(select, /*frame*/ ctx[0].tag.label, true);
|
|
append_dev(span, t3);
|
|
append_dev(span, svg1);
|
|
append_dev(svg1, path1);
|
|
|
|
if (!mounted) {
|
|
dispose = [
|
|
listen_dev(
|
|
div0,
|
|
"click",
|
|
/*click_handler*/ ctx[3],
|
|
false,
|
|
false,
|
|
false,
|
|
false
|
|
),
|
|
listen_dev(
|
|
div0,
|
|
"mousemove",
|
|
scrubberMove$1,
|
|
false,
|
|
false,
|
|
false,
|
|
false
|
|
),
|
|
listen_dev(
|
|
div0,
|
|
"mouseleave",
|
|
scrubberReset$1,
|
|
false,
|
|
false,
|
|
false,
|
|
false
|
|
),
|
|
listen_dev(
|
|
div3,
|
|
"click",
|
|
/*click_handler_1*/ ctx[4],
|
|
{ once: true },
|
|
false,
|
|
false,
|
|
false
|
|
),
|
|
listen_dev(select, "change", /*select_change_handler*/ ctx[5]),
|
|
listen_dev(
|
|
svg1,
|
|
"click",
|
|
/*click_handler_2*/ ctx[6],
|
|
{ once: true },
|
|
false,
|
|
false,
|
|
false
|
|
),
|
|
];
|
|
|
|
mounted = true;
|
|
}
|
|
},
|
|
p: function update(ctx, [dirty]) {
|
|
if (dirty & /*frame*/ 1) {
|
|
set_style(
|
|
div0,
|
|
"background-position",
|
|
"-" +
|
|
/*frame*/ ctx[0].offset[0] +
|
|
"px -" +
|
|
/*frame*/ ctx[0].offset[1] +
|
|
"px"
|
|
);
|
|
}
|
|
|
|
if (dirty & /*url*/ 2) {
|
|
set_style(div0, "background-image", "url('" + /*url*/ ctx[1] + "')");
|
|
}
|
|
|
|
if (
|
|
dirty & /*frame, OPTIONS*/ 1 &&
|
|
div0_data_offset_value !==
|
|
(div0_data_offset_value = /*frame*/ ctx[0].offset)
|
|
) {
|
|
attr_dev(div0, "data-offset", div0_data_offset_value);
|
|
}
|
|
|
|
if (
|
|
dirty & /*frame, OPTIONS*/ 1 &&
|
|
div1_class_value !==
|
|
(div1_class_value =
|
|
"progress-bar progress-bar-striped bg-" +
|
|
confidence$1(/*frame*/ ctx[0].tag.prob) +
|
|
" svelte-zeu5yg")
|
|
) {
|
|
attr_dev(div1, "class", div1_class_value);
|
|
}
|
|
|
|
if (dirty & /*frame*/ 1) {
|
|
set_style(div1, "width", /*frame*/ ctx[0].tag.prob * 100 + "%");
|
|
}
|
|
|
|
if (
|
|
dirty & /*frame, OPTIONS*/ 1 &&
|
|
div1_aria_valuenow_value !==
|
|
(div1_aria_valuenow_value = /*frame*/ ctx[0].tag.prob * 100)
|
|
) {
|
|
attr_dev(div1, "aria-valuenow", div1_aria_valuenow_value);
|
|
}
|
|
|
|
if (dirty & /*OPTIONS*/ 0) {
|
|
each_value = OPTIONS;
|
|
validate_each_argument(each_value);
|
|
let i;
|
|
|
|
for (i = 0; i < each_value.length; i += 1) {
|
|
const child_ctx = get_each_context$3(ctx, each_value, i);
|
|
|
|
if (each_blocks[i]) {
|
|
each_blocks[i].p(child_ctx, dirty);
|
|
} else {
|
|
each_blocks[i] = create_each_block$3(child_ctx);
|
|
each_blocks[i].c();
|
|
each_blocks[i].m(select, null);
|
|
}
|
|
}
|
|
|
|
for (; i < each_blocks.length; i += 1) {
|
|
each_blocks[i].d(1);
|
|
}
|
|
|
|
each_blocks.length = each_value.length;
|
|
}
|
|
|
|
if (dirty & /*frame, OPTIONS*/ 1) {
|
|
select_option(select, /*frame*/ ctx[0].tag.label);
|
|
}
|
|
},
|
|
i: noop,
|
|
o: noop,
|
|
d: function destroy(detaching) {
|
|
if (detaching) detach_dev(div4);
|
|
destroy_each(each_blocks, detaching);
|
|
mounted = false;
|
|
run_all(dispose);
|
|
},
|
|
};
|
|
|
|
dispatch_dev("SvelteRegisterBlock", {
|
|
block,
|
|
id: create_fragment$5.name,
|
|
type: "component",
|
|
source: "",
|
|
ctx,
|
|
});
|
|
|
|
return block;
|
|
}
|
|
|
|
function confidence$1(prob) {
|
|
prob = prob * 100;
|
|
|
|
if (prob < 50.0) {
|
|
return "danger";
|
|
} else if (prob < 75.0) {
|
|
return "warning";
|
|
} else {
|
|
return "success";
|
|
}
|
|
}
|
|
|
|
function scrubberMove$1(event) {
|
|
let target = event.target;
|
|
let imageWidth = 160;
|
|
let left = 53;
|
|
let right = 106;
|
|
let backgroundPosition = target.style.backgroundPosition.split(" ");
|
|
let offset = Number(target.getAttribute("data-offset").split(",")[0]);
|
|
|
|
if (event.offsetX < left) {
|
|
backgroundPosition[0] = `-${offset - imageWidth}px`;
|
|
target.style.backgroundPosition = backgroundPosition.join(" ");
|
|
} else if (event.offsetX > left && event.offsetX < right) {
|
|
backgroundPosition[0] = `-${offset}px`;
|
|
target.style.backgroundPosition = backgroundPosition.join(" ");
|
|
} else if (event.offsetX > right) {
|
|
backgroundPosition[0] = `-${offset + imageWidth}px`;
|
|
target.style.backgroundPosition = backgroundPosition.join(" ");
|
|
}
|
|
}
|
|
|
|
function scrubberReset$1(event) {
|
|
let backgroundPosition = event.target.style.backgroundPosition.split(" ");
|
|
let offset = Number(event.target.getAttribute("data-offset").split(",")[0]);
|
|
backgroundPosition[0] = `-${offset}px`;
|
|
event.target.style.backgroundPosition = backgroundPosition.join(" ");
|
|
}
|
|
|
|
function instance$5($$self, $$props, $$invalidate) {
|
|
let { $$slots: slots = {}, $$scope } = $$props;
|
|
validate_slots("Marker", slots, []);
|
|
const dispatch = createEventDispatcher();
|
|
let { frame } = $$props;
|
|
let { url = "" } = $$props;
|
|
|
|
$$self.$$.on_mount.push(function () {
|
|
if (
|
|
frame === undefined &&
|
|
!("frame" in $$props || $$self.$$.bound[$$self.$$.props["frame"]])
|
|
) {
|
|
console.warn("<Marker> was created without expected prop 'frame'");
|
|
}
|
|
});
|
|
|
|
const writable_props = ["frame", "url"];
|
|
|
|
Object.keys($$props).forEach((key) => {
|
|
if (
|
|
!~writable_props.indexOf(key) &&
|
|
key.slice(0, 2) !== "$$" &&
|
|
key !== "slot"
|
|
)
|
|
console.warn(`<Marker> was created with unknown prop '${key}'`);
|
|
});
|
|
|
|
const click_handler = () => {
|
|
dispatch("select", frame);
|
|
};
|
|
|
|
const click_handler_1 = () => {
|
|
dispatch("addMarker", frame);
|
|
};
|
|
|
|
function select_change_handler() {
|
|
frame.tag.label = select_value(this);
|
|
$$invalidate(0, frame);
|
|
}
|
|
|
|
const click_handler_2 = () => {
|
|
dispatch("remove", frame.id);
|
|
};
|
|
|
|
$$self.$$set = ($$props) => {
|
|
if ("frame" in $$props) $$invalidate(0, (frame = $$props.frame));
|
|
if ("url" in $$props) $$invalidate(1, (url = $$props.url));
|
|
};
|
|
|
|
$$self.$capture_state = () => ({
|
|
OPTIONS,
|
|
createEventDispatcher,
|
|
dispatch,
|
|
frame,
|
|
url,
|
|
confidence: confidence$1,
|
|
scrubberMove: scrubberMove$1,
|
|
scrubberReset: scrubberReset$1,
|
|
});
|
|
|
|
$$self.$inject_state = ($$props) => {
|
|
if ("frame" in $$props) $$invalidate(0, (frame = $$props.frame));
|
|
if ("url" in $$props) $$invalidate(1, (url = $$props.url));
|
|
};
|
|
|
|
if ($$props && "$$inject" in $$props) {
|
|
$$self.$inject_state($$props.$$inject);
|
|
}
|
|
|
|
return [
|
|
frame,
|
|
url,
|
|
dispatch,
|
|
click_handler,
|
|
click_handler_1,
|
|
select_change_handler,
|
|
click_handler_2,
|
|
];
|
|
}
|
|
|
|
class Marker extends SvelteComponentDev {
|
|
constructor(options) {
|
|
super(options);
|
|
init(this, options, instance$5, create_fragment$5, safe_not_equal, {
|
|
frame: 0,
|
|
url: 1,
|
|
});
|
|
|
|
dispatch_dev("SvelteRegisterComponent", {
|
|
component: this,
|
|
tagName: "Marker",
|
|
options,
|
|
id: create_fragment$5.name,
|
|
});
|
|
}
|
|
|
|
get frame() {
|
|
throw new Error(
|
|
"<Marker>: Props cannot be read directly from the component instance unless compiling with 'accessors: true' or '<svelte:options accessors/>'"
|
|
);
|
|
}
|
|
|
|
set frame(value) {
|
|
throw new Error(
|
|
"<Marker>: Props cannot be set directly on the component instance unless compiling with 'accessors: true' or '<svelte:options accessors/>'"
|
|
);
|
|
}
|
|
|
|
get url() {
|
|
throw new Error(
|
|
"<Marker>: Props cannot be read directly from the component instance unless compiling with 'accessors: true' or '<svelte:options accessors/>'"
|
|
);
|
|
}
|
|
|
|
set url(value) {
|
|
throw new Error(
|
|
"<Marker>: Props cannot be set directly on the component instance unless compiling with 'accessors: true' or '<svelte:options accessors/>'"
|
|
);
|
|
}
|
|
}
|
|
|
|
function cubicOut(t) {
|
|
const f = t - 1.0;
|
|
return f * f * f + 1.0;
|
|
}
|
|
function quintOut(t) {
|
|
return --t * t * t * t * t + 1;
|
|
}
|
|
|
|
function flip(node, { from, to }, params = {}) {
|
|
const style = getComputedStyle(node);
|
|
const transform = style.transform === "none" ? "" : style.transform;
|
|
const [ox, oy] = style.transformOrigin.split(" ").map(parseFloat);
|
|
const dx = from.left + (from.width * ox) / to.width - (to.left + ox);
|
|
const dy = from.top + (from.height * oy) / to.height - (to.top + oy);
|
|
const {
|
|
delay = 0,
|
|
duration = (d) => Math.sqrt(d) * 120,
|
|
easing = cubicOut,
|
|
} = params;
|
|
return {
|
|
delay,
|
|
duration: is_function(duration)
|
|
? duration(Math.sqrt(dx * dx + dy * dy))
|
|
: duration,
|
|
easing,
|
|
css: (t, u) => {
|
|
const x = u * dx;
|
|
const y = u * dy;
|
|
const sx = t + (u * from.width) / to.width;
|
|
const sy = t + (u * from.height) / to.height;
|
|
return `transform: ${transform} translate(${x}px, ${y}px) scale(${sx}, ${sy});`;
|
|
},
|
|
};
|
|
}
|
|
|
|
function fade(node, { delay = 0, duration = 400, easing = identity } = {}) {
|
|
const o = +getComputedStyle(node).opacity;
|
|
return {
|
|
delay,
|
|
duration,
|
|
easing,
|
|
css: (t) => `opacity: ${t * o}`,
|
|
};
|
|
}
|
|
function fly(
|
|
node,
|
|
{
|
|
delay = 0,
|
|
duration = 400,
|
|
easing = cubicOut,
|
|
x = 0,
|
|
y = 0,
|
|
opacity = 0,
|
|
} = {}
|
|
) {
|
|
const style = getComputedStyle(node);
|
|
const target_opacity = +style.opacity;
|
|
const transform = style.transform === "none" ? "" : style.transform;
|
|
const od = target_opacity * (1 - opacity);
|
|
const [xValue, xUnit] = split_css_unit(x);
|
|
const [yValue, yUnit] = split_css_unit(y);
|
|
return {
|
|
delay,
|
|
duration,
|
|
easing,
|
|
css: (t, u) => `
|
|
transform: ${transform} translate(${(1 - t) * xValue}${xUnit}, ${(1 - t) * yValue}${yUnit});
|
|
opacity: ${target_opacity - od * u}`,
|
|
};
|
|
}
|
|
|
|
/* src/MarkerMatches.svelte generated by Svelte v3.59.2 */
|
|
const file$4 = "src/MarkerMatches.svelte";
|
|
|
|
function get_each_context$2(ctx, list, i) {
|
|
const child_ctx = ctx.slice();
|
|
child_ctx[19] = list[i];
|
|
child_ctx[20] = list;
|
|
child_ctx[21] = i;
|
|
return child_ctx;
|
|
}
|
|
|
|
// (97:10) {#each filteredFrames as frame (frame.id)}
|
|
function create_each_block$2(key_1, ctx) {
|
|
let div;
|
|
let marker;
|
|
let updating_frame;
|
|
let t;
|
|
let div_intro;
|
|
let div_outro;
|
|
let rect;
|
|
let stop_animation = noop;
|
|
let current;
|
|
|
|
function marker_frame_binding(value) {
|
|
/*marker_frame_binding*/ ctx[14](
|
|
value,
|
|
/*frame*/ ctx[19],
|
|
/*each_value*/ ctx[20],
|
|
/*frame_index*/ ctx[21]
|
|
);
|
|
}
|
|
|
|
let marker_props = { url: /*url*/ ctx[1] };
|
|
|
|
if (/*frame*/ ctx[19] !== void 0) {
|
|
marker_props.frame = /*frame*/ ctx[19];
|
|
}
|
|
|
|
marker = new Marker({ props: marker_props, $$inline: true });
|
|
binding_callbacks.push(() => bind(marker, "frame", marker_frame_binding));
|
|
marker.$on("addMarker", /*addMarker_handler*/ ctx[15]);
|
|
marker.$on("remove", /*remove_handler*/ ctx[16]);
|
|
marker.$on("select", /*select*/ ctx[7]);
|
|
|
|
const block = {
|
|
key: key_1,
|
|
first: null,
|
|
c: function create() {
|
|
div = element("div");
|
|
create_component(marker.$$.fragment);
|
|
t = space();
|
|
attr_dev(div, "class", "svelte-qsvzsw");
|
|
toggle_class(
|
|
div,
|
|
"selected",
|
|
/*selected*/ ctx[3] === /*frame*/ ctx[19].id
|
|
);
|
|
add_location(div, file$4, 97, 12, 2701);
|
|
this.first = div;
|
|
},
|
|
m: function mount(target, anchor) {
|
|
insert_dev(target, div, anchor);
|
|
mount_component(marker, div, null);
|
|
append_dev(div, t);
|
|
current = true;
|
|
},
|
|
p: function update(new_ctx, dirty) {
|
|
ctx = new_ctx;
|
|
const marker_changes = {};
|
|
if (dirty & /*url*/ 2) marker_changes.url = /*url*/ ctx[1];
|
|
|
|
if (!updating_frame && dirty & /*filteredFrames*/ 32) {
|
|
updating_frame = true;
|
|
marker_changes.frame = /*frame*/ ctx[19];
|
|
add_flush_callback(() => (updating_frame = false));
|
|
}
|
|
|
|
marker.$set(marker_changes);
|
|
|
|
if (!current || dirty & /*selected, filteredFrames*/ 40) {
|
|
toggle_class(
|
|
div,
|
|
"selected",
|
|
/*selected*/ ctx[3] === /*frame*/ ctx[19].id
|
|
);
|
|
}
|
|
},
|
|
r: function measure() {
|
|
rect = div.getBoundingClientRect();
|
|
},
|
|
f: function fix() {
|
|
fix_position(div);
|
|
stop_animation();
|
|
add_transform(div, rect);
|
|
},
|
|
a: function animate() {
|
|
stop_animation();
|
|
stop_animation = create_animation(div, rect, flip, {
|
|
duration: 250,
|
|
easing: quintOut,
|
|
});
|
|
},
|
|
i: function intro(local) {
|
|
if (current) return;
|
|
transition_in(marker.$$.fragment, local);
|
|
|
|
add_render_callback(() => {
|
|
if (!current) return;
|
|
if (div_outro) div_outro.end(1);
|
|
div_intro = create_in_transition(div, fade, {});
|
|
div_intro.start();
|
|
});
|
|
|
|
current = true;
|
|
},
|
|
o: function outro(local) {
|
|
transition_out(marker.$$.fragment, local);
|
|
if (div_intro) div_intro.invalidate();
|
|
div_outro = create_out_transition(div, fade, {});
|
|
current = false;
|
|
},
|
|
d: function destroy(detaching) {
|
|
if (detaching) detach_dev(div);
|
|
destroy_component(marker);
|
|
if (detaching && div_outro) div_outro.end();
|
|
},
|
|
};
|
|
|
|
dispatch_dev("SvelteRegisterBlock", {
|
|
block,
|
|
id: create_each_block$2.name,
|
|
type: "each",
|
|
source: "(97:10) {#each filteredFrames as frame (frame.id)}",
|
|
ctx,
|
|
});
|
|
|
|
return block;
|
|
}
|
|
|
|
// (118:12) {#if saving}
|
|
function create_if_block$1(ctx) {
|
|
let div;
|
|
|
|
const block = {
|
|
c: function create() {
|
|
div = element("div");
|
|
attr_dev(div, "class", "lds-dual-ring");
|
|
add_location(div, file$4, 118, 14, 3481);
|
|
},
|
|
m: function mount(target, anchor) {
|
|
insert_dev(target, div, anchor);
|
|
},
|
|
d: function destroy(detaching) {
|
|
if (detaching) detach_dev(div);
|
|
},
|
|
};
|
|
|
|
dispatch_dev("SvelteRegisterBlock", {
|
|
block,
|
|
id: create_if_block$1.name,
|
|
type: "if",
|
|
source: "(118:12) {#if saving}",
|
|
ctx,
|
|
});
|
|
|
|
return block;
|
|
}
|
|
|
|
function create_fragment$4(ctx) {
|
|
let div7;
|
|
let div6;
|
|
let div5;
|
|
let div0;
|
|
let t0;
|
|
let input;
|
|
let t1;
|
|
let t2_value = /*threshold*/ ctx[0] * 100 + "";
|
|
let t2;
|
|
let t3;
|
|
let t4;
|
|
let div2;
|
|
let div1;
|
|
let each_blocks = [];
|
|
let each_1_lookup = new Map();
|
|
let t5;
|
|
let div4;
|
|
let div3;
|
|
let button0;
|
|
let t7;
|
|
let button1;
|
|
let t8;
|
|
let current;
|
|
let mounted;
|
|
let dispose;
|
|
let each_value = /*filteredFrames*/ ctx[5];
|
|
validate_each_argument(each_value);
|
|
const get_key = (ctx) => /*frame*/ ctx[19].id;
|
|
validate_each_keys(ctx, each_value, get_each_context$2, get_key);
|
|
|
|
for (let i = 0; i < each_value.length; i += 1) {
|
|
let child_ctx = get_each_context$2(ctx, each_value, i);
|
|
let key = get_key(child_ctx);
|
|
each_1_lookup.set(
|
|
key,
|
|
(each_blocks[i] = create_each_block$2(key, child_ctx))
|
|
);
|
|
}
|
|
|
|
let if_block = /*saving*/ ctx[4] && create_if_block$1(ctx);
|
|
|
|
const block = {
|
|
c: function create() {
|
|
div7 = element("div");
|
|
div6 = element("div");
|
|
div5 = element("div");
|
|
div0 = element("div");
|
|
t0 = text("Threshold: ");
|
|
input = element("input");
|
|
t1 = space();
|
|
t2 = text(t2_value);
|
|
t3 = text(" %");
|
|
t4 = space();
|
|
div2 = element("div");
|
|
div1 = element("div");
|
|
|
|
for (let i = 0; i < each_blocks.length; i += 1) {
|
|
each_blocks[i].c();
|
|
}
|
|
|
|
t5 = space();
|
|
div4 = element("div");
|
|
div3 = element("div");
|
|
button0 = element("button");
|
|
button0.textContent = "Close";
|
|
t7 = space();
|
|
button1 = element("button");
|
|
if (if_block) if_block.c();
|
|
t8 = text("\n Add All Markers");
|
|
attr_dev(input, "type", "range");
|
|
attr_dev(input, "min", "0.4");
|
|
attr_dev(input, "max", "0.9");
|
|
attr_dev(input, "step", "0.1");
|
|
attr_dev(input, "id", "stash-tag-threshold");
|
|
set_style(input, "margin", "0px");
|
|
set_style(input, "height", "10px");
|
|
add_location(input, file$4, 82, 19, 2204);
|
|
attr_dev(div0, "class", "modal-header svelte-qsvzsw");
|
|
add_location(div0, file$4, 81, 6, 2158);
|
|
attr_dev(div1, "class", "row justify-content-center");
|
|
add_location(div1, file$4, 95, 8, 2595);
|
|
attr_dev(div2, "class", "modal-body");
|
|
add_location(div2, file$4, 94, 6, 2562);
|
|
attr_dev(button0, "id", "tags-cancel");
|
|
attr_dev(button0, "type", "button");
|
|
attr_dev(button0, "class", "ml-2 btn btn-secondary");
|
|
add_location(button0, file$4, 110, 10, 3183);
|
|
attr_dev(button1, "id", "tags-accept");
|
|
attr_dev(button1, "type", "button");
|
|
attr_dev(button1, "class", "ml-2 btn btn-primary");
|
|
add_location(button1, file$4, 116, 10, 3354);
|
|
add_location(div3, file$4, 109, 8, 3167);
|
|
attr_dev(div4, "class", "ModalFooter modal-footer svelte-qsvzsw");
|
|
add_location(div4, file$4, 108, 6, 3120);
|
|
attr_dev(div5, "class", "modal-content");
|
|
add_location(div5, file$4, 80, 4, 2124);
|
|
attr_dev(div6, "class", "modal-dialog modal-xl top-accent");
|
|
add_location(div6, file$4, 79, 2, 2073);
|
|
attr_dev(div7, "class", "tagger-tabs svelte-qsvzsw");
|
|
add_location(div7, file$4, 78, 0, 2028);
|
|
},
|
|
l: function claim(nodes) {
|
|
throw new Error(
|
|
"options.hydrate only works if the component was compiled with the `hydratable: true` option"
|
|
);
|
|
},
|
|
m: function mount(target, anchor) {
|
|
insert_dev(target, div7, anchor);
|
|
append_dev(div7, div6);
|
|
append_dev(div6, div5);
|
|
append_dev(div5, div0);
|
|
append_dev(div0, t0);
|
|
append_dev(div0, input);
|
|
set_input_value(input, /*threshold*/ ctx[0]);
|
|
append_dev(div0, t1);
|
|
append_dev(div0, t2);
|
|
append_dev(div0, t3);
|
|
append_dev(div5, t4);
|
|
append_dev(div5, div2);
|
|
append_dev(div2, div1);
|
|
|
|
for (let i = 0; i < each_blocks.length; i += 1) {
|
|
if (each_blocks[i]) {
|
|
each_blocks[i].m(div1, null);
|
|
}
|
|
}
|
|
|
|
append_dev(div5, t5);
|
|
append_dev(div5, div4);
|
|
append_dev(div4, div3);
|
|
append_dev(div3, button0);
|
|
append_dev(div3, t7);
|
|
append_dev(div3, button1);
|
|
if (if_block) if_block.m(button1, null);
|
|
append_dev(button1, t8);
|
|
/*div7_binding*/ ctx[17](div7);
|
|
current = true;
|
|
|
|
if (!mounted) {
|
|
dispose = [
|
|
listen_dev(input, "change", /*input_change_input_handler*/ ctx[12]),
|
|
listen_dev(input, "input", /*input_change_input_handler*/ ctx[12]),
|
|
listen_dev(
|
|
input,
|
|
"change",
|
|
/*change_handler*/ ctx[13],
|
|
false,
|
|
false,
|
|
false,
|
|
false
|
|
),
|
|
listen_dev(
|
|
button0,
|
|
"click",
|
|
/*close*/ ctx[6],
|
|
false,
|
|
false,
|
|
false,
|
|
false
|
|
),
|
|
listen_dev(
|
|
button1,
|
|
"click",
|
|
/*saveAll*/ ctx[10],
|
|
false,
|
|
false,
|
|
false,
|
|
false
|
|
),
|
|
];
|
|
|
|
mounted = true;
|
|
}
|
|
},
|
|
p: function update(ctx, [dirty]) {
|
|
if (dirty & /*threshold*/ 1) {
|
|
set_input_value(input, /*threshold*/ ctx[0]);
|
|
}
|
|
|
|
if (
|
|
(!current || dirty & /*threshold*/ 1) &&
|
|
t2_value !== (t2_value = /*threshold*/ ctx[0] * 100 + "")
|
|
)
|
|
set_data_dev(t2, t2_value);
|
|
|
|
if (
|
|
dirty &
|
|
/*selected, filteredFrames, url, addMarker, remove, select*/ 938
|
|
) {
|
|
each_value = /*filteredFrames*/ ctx[5];
|
|
validate_each_argument(each_value);
|
|
group_outros();
|
|
for (let i = 0; i < each_blocks.length; i += 1) each_blocks[i].r();
|
|
validate_each_keys(ctx, each_value, get_each_context$2, get_key);
|
|
each_blocks = update_keyed_each(
|
|
each_blocks,
|
|
dirty,
|
|
get_key,
|
|
1,
|
|
ctx,
|
|
each_value,
|
|
each_1_lookup,
|
|
div1,
|
|
fix_and_outro_and_destroy_block,
|
|
create_each_block$2,
|
|
null,
|
|
get_each_context$2
|
|
);
|
|
for (let i = 0; i < each_blocks.length; i += 1) each_blocks[i].a();
|
|
check_outros();
|
|
}
|
|
|
|
if (/*saving*/ ctx[4]) {
|
|
if (if_block);
|
|
else {
|
|
if_block = create_if_block$1(ctx);
|
|
if_block.c();
|
|
if_block.m(button1, t8);
|
|
}
|
|
} else if (if_block) {
|
|
if_block.d(1);
|
|
if_block = null;
|
|
}
|
|
},
|
|
i: function intro(local) {
|
|
if (current) return;
|
|
|
|
for (let i = 0; i < each_value.length; i += 1) {
|
|
transition_in(each_blocks[i]);
|
|
}
|
|
|
|
current = true;
|
|
},
|
|
o: function outro(local) {
|
|
for (let i = 0; i < each_blocks.length; i += 1) {
|
|
transition_out(each_blocks[i]);
|
|
}
|
|
|
|
current = false;
|
|
},
|
|
d: function destroy(detaching) {
|
|
if (detaching) detach_dev(div7);
|
|
|
|
for (let i = 0; i < each_blocks.length; i += 1) {
|
|
each_blocks[i].d();
|
|
}
|
|
|
|
if (if_block) if_block.d();
|
|
/*div7_binding*/ ctx[17](null);
|
|
mounted = false;
|
|
run_all(dispose);
|
|
},
|
|
};
|
|
|
|
dispatch_dev("SvelteRegisterBlock", {
|
|
block,
|
|
id: create_fragment$4.name,
|
|
type: "component",
|
|
source: "",
|
|
ctx,
|
|
});
|
|
|
|
return block;
|
|
}
|
|
|
|
function getCurrentVideo() {
|
|
return document.querySelector("#VideoJsPlayer_html5_api");
|
|
}
|
|
|
|
async function playVideoAtTime(time) {
|
|
const video = getCurrentVideo();
|
|
await video.play();
|
|
video.currentTime = time;
|
|
}
|
|
|
|
function instance$4($$self, $$props, $$invalidate) {
|
|
let filteredFrames;
|
|
let { $$slots: slots = {}, $$scope } = $$props;
|
|
validate_slots("MarkerMatches", slots, []);
|
|
let { url = "" } = $$props;
|
|
let { frames = [] } = $$props;
|
|
let { threshold = 0.4 } = $$props;
|
|
let tags;
|
|
let self;
|
|
let selected = null;
|
|
let saving = false;
|
|
|
|
onMount(async () => {
|
|
tags = await getAllTags();
|
|
$$invalidate(
|
|
0,
|
|
(threshold =
|
|
Number(localStorage.getItem("stash-marker-threshold")) || 0.4)
|
|
);
|
|
});
|
|
|
|
async function close() {
|
|
self.remove();
|
|
}
|
|
|
|
function select(event) {
|
|
let frame = event.detail;
|
|
|
|
if (selected === frame.id) {
|
|
$$invalidate(3, (selected = null));
|
|
} else {
|
|
$$invalidate(3, (selected = frame.id));
|
|
playVideoAtTime(frame.time);
|
|
}
|
|
}
|
|
|
|
async function remove(id) {
|
|
$$invalidate(11, (frames = frames.filter((x) => x.id !== id)));
|
|
}
|
|
|
|
async function addMarker(frame) {
|
|
const [, scene_id] = getScenarioAndID();
|
|
let time;
|
|
let tagId;
|
|
const tagLower = frame.tag.label.toLowerCase();
|
|
|
|
if (tags[tagLower] === undefined) {
|
|
const tagID = await createTag(tagLower);
|
|
tags[tagLower] = tagID;
|
|
tagId = tagID;
|
|
} else {
|
|
tagId = tags[tagLower];
|
|
}
|
|
|
|
if (selected && selected === frame.id) {
|
|
const video = getCurrentVideo();
|
|
time = video.currentTime;
|
|
} else {
|
|
time = frame.time;
|
|
}
|
|
|
|
await createMarker(scene_id, tagId, time);
|
|
remove(frame.id);
|
|
$$invalidate(3, (selected = null));
|
|
}
|
|
|
|
async function saveAll() {
|
|
$$invalidate(3, (selected = null));
|
|
$$invalidate(4, (saving = true));
|
|
|
|
for (const frame of filteredFrames) {
|
|
await addMarker(frame);
|
|
}
|
|
|
|
$$invalidate(4, (saving = false));
|
|
window.location.reload();
|
|
close();
|
|
}
|
|
|
|
const writable_props = ["url", "frames", "threshold"];
|
|
|
|
Object.keys($$props).forEach((key) => {
|
|
if (
|
|
!~writable_props.indexOf(key) &&
|
|
key.slice(0, 2) !== "$$" &&
|
|
key !== "slot"
|
|
)
|
|
console.warn(`<MarkerMatches> was created with unknown prop '${key}'`);
|
|
});
|
|
|
|
function input_change_input_handler() {
|
|
threshold = to_number(this.value);
|
|
$$invalidate(0, threshold);
|
|
}
|
|
|
|
const change_handler = () => {
|
|
localStorage.setItem("stash-marker-threshold", String(threshold));
|
|
};
|
|
|
|
function marker_frame_binding(value, frame, each_value, frame_index) {
|
|
each_value[frame_index] = value;
|
|
($$invalidate(5, filteredFrames), $$invalidate(11, frames)),
|
|
$$invalidate(0, threshold);
|
|
}
|
|
|
|
const addMarker_handler = (event) => {
|
|
addMarker(event.detail);
|
|
};
|
|
|
|
const remove_handler = (event) => {
|
|
remove(event.detail);
|
|
};
|
|
|
|
function div7_binding($$value) {
|
|
binding_callbacks[$$value ? "unshift" : "push"](() => {
|
|
self = $$value;
|
|
$$invalidate(2, self);
|
|
});
|
|
}
|
|
|
|
$$self.$$set = ($$props) => {
|
|
if ("url" in $$props) $$invalidate(1, (url = $$props.url));
|
|
if ("frames" in $$props) $$invalidate(11, (frames = $$props.frames));
|
|
if ("threshold" in $$props)
|
|
$$invalidate(0, (threshold = $$props.threshold));
|
|
};
|
|
|
|
$$self.$capture_state = () => ({
|
|
Marker,
|
|
flip,
|
|
quintOut,
|
|
fade,
|
|
createMarker,
|
|
getAllTags,
|
|
createTag,
|
|
getScenarioAndID,
|
|
onMount,
|
|
url,
|
|
frames,
|
|
threshold,
|
|
tags,
|
|
self,
|
|
selected,
|
|
saving,
|
|
getCurrentVideo,
|
|
close,
|
|
select,
|
|
playVideoAtTime,
|
|
remove,
|
|
addMarker,
|
|
saveAll,
|
|
filteredFrames,
|
|
});
|
|
|
|
$$self.$inject_state = ($$props) => {
|
|
if ("url" in $$props) $$invalidate(1, (url = $$props.url));
|
|
if ("frames" in $$props) $$invalidate(11, (frames = $$props.frames));
|
|
if ("threshold" in $$props)
|
|
$$invalidate(0, (threshold = $$props.threshold));
|
|
if ("tags" in $$props) tags = $$props.tags;
|
|
if ("self" in $$props) $$invalidate(2, (self = $$props.self));
|
|
if ("selected" in $$props) $$invalidate(3, (selected = $$props.selected));
|
|
if ("saving" in $$props) $$invalidate(4, (saving = $$props.saving));
|
|
if ("filteredFrames" in $$props)
|
|
$$invalidate(5, (filteredFrames = $$props.filteredFrames));
|
|
};
|
|
|
|
if ($$props && "$$inject" in $$props) {
|
|
$$self.$inject_state($$props.$$inject);
|
|
}
|
|
|
|
$$self.$$.update = () => {
|
|
if ($$self.$$.dirty & /*frames, threshold*/ 2049) {
|
|
$$invalidate(
|
|
5,
|
|
(filteredFrames = frames.filter((x) => x.tag.prob > threshold))
|
|
);
|
|
}
|
|
};
|
|
|
|
return [
|
|
threshold,
|
|
url,
|
|
self,
|
|
selected,
|
|
saving,
|
|
filteredFrames,
|
|
close,
|
|
select,
|
|
remove,
|
|
addMarker,
|
|
saveAll,
|
|
frames,
|
|
input_change_input_handler,
|
|
change_handler,
|
|
marker_frame_binding,
|
|
addMarker_handler,
|
|
remove_handler,
|
|
div7_binding,
|
|
];
|
|
}
|
|
|
|
class MarkerMatches extends SvelteComponentDev {
|
|
constructor(options) {
|
|
super(options);
|
|
init(this, options, instance$4, create_fragment$4, safe_not_equal, {
|
|
url: 1,
|
|
frames: 11,
|
|
threshold: 0,
|
|
});
|
|
|
|
dispatch_dev("SvelteRegisterComponent", {
|
|
component: this,
|
|
tagName: "MarkerMatches",
|
|
options,
|
|
id: create_fragment$4.name,
|
|
});
|
|
}
|
|
|
|
get url() {
|
|
throw new Error(
|
|
"<MarkerMatches>: Props cannot be read directly from the component instance unless compiling with 'accessors: true' or '<svelte:options accessors/>'"
|
|
);
|
|
}
|
|
|
|
set url(value) {
|
|
throw new Error(
|
|
"<MarkerMatches>: Props cannot be set directly on the component instance unless compiling with 'accessors: true' or '<svelte:options accessors/>'"
|
|
);
|
|
}
|
|
|
|
get frames() {
|
|
throw new Error(
|
|
"<MarkerMatches>: Props cannot be read directly from the component instance unless compiling with 'accessors: true' or '<svelte:options accessors/>'"
|
|
);
|
|
}
|
|
|
|
set frames(value) {
|
|
throw new Error(
|
|
"<MarkerMatches>: Props cannot be set directly on the component instance unless compiling with 'accessors: true' or '<svelte:options accessors/>'"
|
|
);
|
|
}
|
|
|
|
get threshold() {
|
|
throw new Error(
|
|
"<MarkerMatches>: Props cannot be read directly from the component instance unless compiling with 'accessors: true' or '<svelte:options accessors/>'"
|
|
);
|
|
}
|
|
|
|
set threshold(value) {
|
|
throw new Error(
|
|
"<MarkerMatches>: Props cannot be set directly on the component instance unless compiling with 'accessors: true' or '<svelte:options accessors/>'"
|
|
);
|
|
}
|
|
}
|
|
|
|
/* src/MarkerButton.svelte generated by Svelte v3.59.2 */
|
|
const file$3 = "src/MarkerButton.svelte";
|
|
|
|
function create_fragment$3(ctx) {
|
|
let button;
|
|
let svg;
|
|
let path;
|
|
let mounted;
|
|
let dispose;
|
|
|
|
const block = {
|
|
c: function create() {
|
|
button = element("button");
|
|
svg = svg_element("svg");
|
|
path = svg_element("path");
|
|
attr_dev(
|
|
path,
|
|
"d",
|
|
"M215.7 499.2C267 435 384 279.4 384 192C384 86 298 0 192 0S0 86 0 192c0 87.4 117 243 168.3 307.2c12.3 15.3 35.1 15.3 47.4 0zM192 128a64 64 0 1 1 0 128 64 64 0 1 1 0-128z"
|
|
);
|
|
add_location(path, file$3, 70, 77, 2369);
|
|
attr_dev(svg, "xmlns", "http://www.w3.org/2000/svg");
|
|
attr_dev(svg, "height", "1em");
|
|
attr_dev(svg, "viewBox", "0 0 384 512");
|
|
attr_dev(svg, "class", "svelte-1m5gxnd");
|
|
add_location(svg, file$3, 70, 2, 2294);
|
|
attr_dev(button, "id", "stashmarker");
|
|
attr_dev(button, "title", "Scan for markers");
|
|
attr_dev(button, "class", "svelte-1m5gxnd");
|
|
toggle_class(button, "scanner", /*scanner*/ ctx[0]);
|
|
add_location(button, file$3, 69, 0, 2205);
|
|
},
|
|
l: function claim(nodes) {
|
|
throw new Error(
|
|
"options.hydrate only works if the component was compiled with the `hydratable: true` option"
|
|
);
|
|
},
|
|
m: function mount(target, anchor) {
|
|
insert_dev(target, button, anchor);
|
|
append_dev(button, svg);
|
|
append_dev(svg, path);
|
|
|
|
if (!mounted) {
|
|
dispose = listen_dev(
|
|
button,
|
|
"click",
|
|
/*getMarkers*/ ctx[1],
|
|
false,
|
|
false,
|
|
false,
|
|
false
|
|
);
|
|
mounted = true;
|
|
}
|
|
},
|
|
p: function update(ctx, [dirty]) {
|
|
if (dirty & /*scanner*/ 1) {
|
|
toggle_class(button, "scanner", /*scanner*/ ctx[0]);
|
|
}
|
|
},
|
|
i: noop,
|
|
o: noop,
|
|
d: function destroy(detaching) {
|
|
if (detaching) detach_dev(button);
|
|
mounted = false;
|
|
dispose();
|
|
},
|
|
};
|
|
|
|
dispatch_dev("SvelteRegisterBlock", {
|
|
block,
|
|
id: create_fragment$3.name,
|
|
type: "component",
|
|
source: "",
|
|
ctx,
|
|
});
|
|
|
|
return block;
|
|
}
|
|
|
|
async function download(url) {
|
|
const vblob = await fetch(url).then((res) => res.blob());
|
|
|
|
return new Promise((resolve) => {
|
|
let reader = new FileReader();
|
|
reader.onload = () => resolve(reader.result);
|
|
reader.readAsDataURL(vblob);
|
|
});
|
|
}
|
|
|
|
function instance$3($$self, $$props, $$invalidate) {
|
|
let { $$slots: slots = {}, $$scope } = $$props;
|
|
validate_slots("MarkerButton", slots, []);
|
|
let scanner = false;
|
|
|
|
async function getMarkers() {
|
|
$$invalidate(0, (scanner = true));
|
|
const [, scene_id] = getScenarioAndID();
|
|
let url = await getUrlSprite(scene_id);
|
|
|
|
if (!url) {
|
|
alert(
|
|
"No sprite found, please ensure you have sprites enabled and generated for your scenes."
|
|
);
|
|
$$invalidate(0, (scanner = false));
|
|
return;
|
|
}
|
|
|
|
// get image blob
|
|
let image = await download(url);
|
|
|
|
// get vtt blob
|
|
const vtt_url = url.replace("_sprite.jpg", "_thumbs.vtt");
|
|
|
|
let vtt = await download(vtt_url);
|
|
|
|
// query the api with a threshold of 0.4 as we want to do the filtering ourselves
|
|
var data = { data: [image, vtt, 0.4] };
|
|
|
|
fetch(STASHMARKER_API_URL + "_1", {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/json; charset=utf-8",
|
|
},
|
|
body: JSON.stringify(data),
|
|
})
|
|
.then((response) => {
|
|
if (response.status !== 200) {
|
|
$$invalidate(0, (scanner = false));
|
|
alert(
|
|
"Something went wrong. It's likely a server issue, Please try again later."
|
|
);
|
|
return;
|
|
}
|
|
|
|
return response.json();
|
|
})
|
|
.then((data) => {
|
|
$$invalidate(0, (scanner = false));
|
|
let frames = data.data[0];
|
|
$$invalidate(0, (scanner = false));
|
|
|
|
if (frames.length === 0) {
|
|
alert("No tags found");
|
|
return;
|
|
}
|
|
|
|
// find a div with class row
|
|
let row = document.querySelector(".row");
|
|
|
|
new MarkerMatches({ target: row, props: { frames, url } });
|
|
})
|
|
.catch((error) => {
|
|
$$invalidate(0, (scanner = false));
|
|
|
|
if (error.message === "") {
|
|
alert("Error: Service may be down. please try again later.");
|
|
} else {
|
|
alert("Error: " + error.message);
|
|
}
|
|
});
|
|
}
|
|
|
|
const writable_props = [];
|
|
|
|
Object.keys($$props).forEach((key) => {
|
|
if (
|
|
!~writable_props.indexOf(key) &&
|
|
key.slice(0, 2) !== "$$" &&
|
|
key !== "slot"
|
|
)
|
|
console.warn(`<MarkerButton> was created with unknown prop '${key}'`);
|
|
});
|
|
|
|
$$self.$capture_state = () => ({
|
|
getScenarioAndID,
|
|
getUrlSprite,
|
|
STASHMARKER_API_URL,
|
|
MarkerMatches,
|
|
scanner,
|
|
download,
|
|
getMarkers,
|
|
});
|
|
|
|
$$self.$inject_state = ($$props) => {
|
|
if ("scanner" in $$props) $$invalidate(0, (scanner = $$props.scanner));
|
|
};
|
|
|
|
if ($$props && "$$inject" in $$props) {
|
|
$$self.$inject_state($$props.$$inject);
|
|
}
|
|
|
|
return [scanner, getMarkers];
|
|
}
|
|
|
|
class MarkerButton extends SvelteComponentDev {
|
|
constructor(options) {
|
|
super(options);
|
|
init(this, options, instance$3, create_fragment$3, safe_not_equal, {});
|
|
|
|
dispatch_dev("SvelteRegisterComponent", {
|
|
component: this,
|
|
tagName: "MarkerButton",
|
|
options,
|
|
id: create_fragment$3.name,
|
|
});
|
|
}
|
|
}
|
|
|
|
/* src/Tag.svelte generated by Svelte v3.59.2 */
|
|
const file$2 = "src/Tag.svelte";
|
|
|
|
function get_each_context$1(ctx, list, i) {
|
|
const child_ctx = ctx.slice();
|
|
child_ctx[0] = list[i];
|
|
return child_ctx;
|
|
}
|
|
|
|
// (74:6) {#each OPTIONS as name}
|
|
function create_each_block$1(ctx) {
|
|
let option;
|
|
let t_value = /*name*/ ctx[0] + "";
|
|
let t;
|
|
|
|
const block = {
|
|
c: function create() {
|
|
option = element("option");
|
|
t = text(t_value);
|
|
set_style(option, "color", "#f5f8fa");
|
|
option.__value = /*name*/ ctx[0];
|
|
option.value = option.__value;
|
|
add_location(option, file$2, 74, 8, 2272);
|
|
},
|
|
m: function mount(target, anchor) {
|
|
insert_dev(target, option, anchor);
|
|
append_dev(option, t);
|
|
},
|
|
p: noop,
|
|
d: function destroy(detaching) {
|
|
if (detaching) detach_dev(option);
|
|
},
|
|
};
|
|
|
|
dispatch_dev("SvelteRegisterBlock", {
|
|
block,
|
|
id: create_each_block$1.name,
|
|
type: "each",
|
|
source: "(74:6) {#each OPTIONS as name}",
|
|
ctx,
|
|
});
|
|
|
|
return block;
|
|
}
|
|
|
|
function create_fragment$2(ctx) {
|
|
let div3;
|
|
let div0;
|
|
let div0_data_offset_value;
|
|
let t0;
|
|
let div2;
|
|
let div1;
|
|
let div1_class_value;
|
|
let div1_aria_valuenow_value;
|
|
let t1;
|
|
let span;
|
|
let select;
|
|
let t2;
|
|
let svg;
|
|
let path;
|
|
let mounted;
|
|
let dispose;
|
|
let each_value = OPTIONS;
|
|
validate_each_argument(each_value);
|
|
let each_blocks = [];
|
|
|
|
for (let i = 0; i < each_value.length; i += 1) {
|
|
each_blocks[i] = create_each_block$1(
|
|
get_each_context$1(ctx, each_value, i)
|
|
);
|
|
}
|
|
|
|
const block = {
|
|
c: function create() {
|
|
div3 = element("div");
|
|
div0 = element("div");
|
|
t0 = space();
|
|
div2 = element("div");
|
|
div1 = element("div");
|
|
t1 = space();
|
|
span = element("span");
|
|
select = element("select");
|
|
|
|
for (let i = 0; i < each_blocks.length; i += 1) {
|
|
each_blocks[i].c();
|
|
}
|
|
|
|
t2 = space();
|
|
svg = svg_element("svg");
|
|
path = svg_element("path");
|
|
attr_dev(div0, "class", "scrubber-item svelte-1d03wug");
|
|
set_style(
|
|
div0,
|
|
"background-position",
|
|
"-" +
|
|
/*data*/ ctx[1].offset[0] +
|
|
"px -" +
|
|
/*data*/ ctx[1].offset[1] +
|
|
"px"
|
|
);
|
|
set_style(div0, "background-image", "url('" + /*url*/ ctx[2] + "')");
|
|
attr_dev(
|
|
div0,
|
|
"data-offset",
|
|
(div0_data_offset_value = /*data*/ ctx[1].offset)
|
|
);
|
|
add_location(div0, file$2, 54, 2, 1571);
|
|
attr_dev(
|
|
div1,
|
|
"class",
|
|
(div1_class_value =
|
|
"progress-bar progress-bar-striped bg-" +
|
|
confidence(/*data*/ ctx[1].prob) +
|
|
" svelte-1d03wug")
|
|
);
|
|
attr_dev(div1, "role", "progressbar");
|
|
set_style(div1, "width", /*data*/ ctx[1].prob * 100 + "%");
|
|
attr_dev(
|
|
div1,
|
|
"aria-valuenow",
|
|
(div1_aria_valuenow_value = /*data*/ ctx[1].prob * 100)
|
|
);
|
|
attr_dev(div1, "aria-valuemin", "0");
|
|
attr_dev(div1, "aria-valuemax", "100");
|
|
add_location(div1, file$2, 62, 4, 1858);
|
|
attr_dev(div2, "class", "progress");
|
|
set_style(div2, "height", "5px");
|
|
add_location(div2, file$2, 61, 2, 1811);
|
|
set_style(select, "color", "#f5f8fa");
|
|
attr_dev(select, "class", "tag-item-select svelte-1d03wug");
|
|
if (/*name*/ ctx[0] === void 0)
|
|
add_render_callback(() =>
|
|
/*select_change_handler*/ ctx[4].call(select)
|
|
);
|
|
add_location(select, file$2, 72, 4, 2159);
|
|
attr_dev(
|
|
path,
|
|
"d",
|
|
"M14.348 14.849c-0.469 0.469-1.229 0.469-1.697 0l-2.651-3.030-2.651 3.029c-0.469 0.469-1.229 0.469-1.697 0-0.469-0.469-0.469-1.229 0-1.697l2.758-3.15-2.759-3.152c-0.469-0.469-0.469-1.228 0-1.697s1.228-0.469 1.697 0l2.652 3.031 2.651-3.031c0.469-0.469 1.228-0.469 1.697 0s0.469 1.229 0 1.697l-2.758 3.152 2.758 3.15c0.469 0.469 0.469 1.229 0 1.698z"
|
|
);
|
|
add_location(path, file$2, 87, 7, 2586);
|
|
attr_dev(svg, "height", "20");
|
|
attr_dev(svg, "width", "20");
|
|
attr_dev(svg, "viewBox", "0 0 20 20");
|
|
attr_dev(svg, "aria-hidden", "true");
|
|
attr_dev(svg, "focusable", "false");
|
|
attr_dev(svg, "class", "tag-item-reject svelte-1d03wug");
|
|
add_location(svg, file$2, 77, 4, 2364);
|
|
attr_dev(
|
|
span,
|
|
"class",
|
|
"tag-item badge badge-secondary svelte-1d03wug"
|
|
);
|
|
add_location(span, file$2, 71, 2, 2109);
|
|
set_style(div3, "padding", "20px");
|
|
add_location(div3, file$2, 53, 0, 1540);
|
|
},
|
|
l: function claim(nodes) {
|
|
throw new Error(
|
|
"options.hydrate only works if the component was compiled with the `hydratable: true` option"
|
|
);
|
|
},
|
|
m: function mount(target, anchor) {
|
|
insert_dev(target, div3, anchor);
|
|
append_dev(div3, div0);
|
|
append_dev(div3, t0);
|
|
append_dev(div3, div2);
|
|
append_dev(div2, div1);
|
|
append_dev(div3, t1);
|
|
append_dev(div3, span);
|
|
append_dev(span, select);
|
|
|
|
for (let i = 0; i < each_blocks.length; i += 1) {
|
|
if (each_blocks[i]) {
|
|
each_blocks[i].m(select, null);
|
|
}
|
|
}
|
|
|
|
select_option(select, /*name*/ ctx[0], true);
|
|
append_dev(span, t2);
|
|
append_dev(span, svg);
|
|
append_dev(svg, path);
|
|
|
|
if (!mounted) {
|
|
dispose = [
|
|
listen_dev(
|
|
div0,
|
|
"mousemove",
|
|
scrubberMove,
|
|
false,
|
|
false,
|
|
false,
|
|
false
|
|
),
|
|
listen_dev(
|
|
div0,
|
|
"mouseleave",
|
|
scrubberReset,
|
|
false,
|
|
false,
|
|
false,
|
|
false
|
|
),
|
|
listen_dev(select, "change", /*select_change_handler*/ ctx[4]),
|
|
listen_dev(
|
|
svg,
|
|
"click",
|
|
/*click_handler*/ ctx[5],
|
|
false,
|
|
false,
|
|
false,
|
|
false
|
|
),
|
|
];
|
|
|
|
mounted = true;
|
|
}
|
|
},
|
|
p: function update(ctx, [dirty]) {
|
|
if (dirty & /*data*/ 2) {
|
|
set_style(
|
|
div0,
|
|
"background-position",
|
|
"-" +
|
|
/*data*/ ctx[1].offset[0] +
|
|
"px -" +
|
|
/*data*/ ctx[1].offset[1] +
|
|
"px"
|
|
);
|
|
}
|
|
|
|
if (dirty & /*url*/ 4) {
|
|
set_style(div0, "background-image", "url('" + /*url*/ ctx[2] + "')");
|
|
}
|
|
|
|
if (
|
|
dirty & /*data*/ 2 &&
|
|
div0_data_offset_value !==
|
|
(div0_data_offset_value = /*data*/ ctx[1].offset)
|
|
) {
|
|
attr_dev(div0, "data-offset", div0_data_offset_value);
|
|
}
|
|
|
|
if (
|
|
dirty & /*data*/ 2 &&
|
|
div1_class_value !==
|
|
(div1_class_value =
|
|
"progress-bar progress-bar-striped bg-" +
|
|
confidence(/*data*/ ctx[1].prob) +
|
|
" svelte-1d03wug")
|
|
) {
|
|
attr_dev(div1, "class", div1_class_value);
|
|
}
|
|
|
|
if (dirty & /*data*/ 2) {
|
|
set_style(div1, "width", /*data*/ ctx[1].prob * 100 + "%");
|
|
}
|
|
|
|
if (
|
|
dirty & /*data*/ 2 &&
|
|
div1_aria_valuenow_value !==
|
|
(div1_aria_valuenow_value = /*data*/ ctx[1].prob * 100)
|
|
) {
|
|
attr_dev(div1, "aria-valuenow", div1_aria_valuenow_value);
|
|
}
|
|
|
|
if (dirty & /*OPTIONS*/ 0) {
|
|
each_value = OPTIONS;
|
|
validate_each_argument(each_value);
|
|
let i;
|
|
|
|
for (i = 0; i < each_value.length; i += 1) {
|
|
const child_ctx = get_each_context$1(ctx, each_value, i);
|
|
|
|
if (each_blocks[i]) {
|
|
each_blocks[i].p(child_ctx, dirty);
|
|
} else {
|
|
each_blocks[i] = create_each_block$1(child_ctx);
|
|
each_blocks[i].c();
|
|
each_blocks[i].m(select, null);
|
|
}
|
|
}
|
|
|
|
for (; i < each_blocks.length; i += 1) {
|
|
each_blocks[i].d(1);
|
|
}
|
|
|
|
each_blocks.length = each_value.length;
|
|
}
|
|
|
|
if (dirty & /*name, OPTIONS*/ 1) {
|
|
select_option(select, /*name*/ ctx[0]);
|
|
}
|
|
},
|
|
i: noop,
|
|
o: noop,
|
|
d: function destroy(detaching) {
|
|
if (detaching) detach_dev(div3);
|
|
destroy_each(each_blocks, detaching);
|
|
mounted = false;
|
|
run_all(dispose);
|
|
},
|
|
};
|
|
|
|
dispatch_dev("SvelteRegisterBlock", {
|
|
block,
|
|
id: create_fragment$2.name,
|
|
type: "component",
|
|
source: "",
|
|
ctx,
|
|
});
|
|
|
|
return block;
|
|
}
|
|
|
|
function confidence(prob) {
|
|
prob = prob * 100;
|
|
|
|
if (prob < 50.0) {
|
|
return "danger";
|
|
} else if (prob < 75.0) {
|
|
return "warning";
|
|
} else {
|
|
return "success";
|
|
}
|
|
}
|
|
|
|
function scrubberMove(event) {
|
|
let target = event.target;
|
|
let imageWidth = 160;
|
|
let backgroundPosition = target.style.backgroundPosition.split(" ");
|
|
let offset = Number(target.getAttribute("data-offset").split(",")[0]);
|
|
|
|
if (event.offsetX < 53) {
|
|
backgroundPosition[0] = `-${offset - imageWidth}px`;
|
|
target.style.backgroundPosition = backgroundPosition.join(" ");
|
|
} else if (
|
|
event.offsetX > 53 &&
|
|
event.offsetX < imageWidth &&
|
|
event.offsetX < 106
|
|
) {
|
|
backgroundPosition[0] = `-${offset}px`;
|
|
target.style.backgroundPosition = backgroundPosition.join(" ");
|
|
} else if (event.offsetX > 106) {
|
|
backgroundPosition[0] = `-${offset + imageWidth}px`;
|
|
target.style.backgroundPosition = backgroundPosition.join(" ");
|
|
}
|
|
}
|
|
|
|
function scrubberReset(event) {
|
|
let backgroundPosition = event.target.style.backgroundPosition.split(" ");
|
|
let offset = Number(event.target.getAttribute("data-offset").split(",")[0]);
|
|
backgroundPosition[0] = `-${offset}px`;
|
|
event.target.style.backgroundPosition = backgroundPosition.join(" ");
|
|
}
|
|
|
|
function instance$2($$self, $$props, $$invalidate) {
|
|
let { $$slots: slots = {}, $$scope } = $$props;
|
|
validate_slots("Tag", slots, []);
|
|
let { name } = $$props;
|
|
let { data } = $$props;
|
|
let { url = "" } = $$props;
|
|
const dispatch = createEventDispatcher();
|
|
|
|
$$self.$$.on_mount.push(function () {
|
|
if (
|
|
name === undefined &&
|
|
!("name" in $$props || $$self.$$.bound[$$self.$$.props["name"]])
|
|
) {
|
|
console.warn("<Tag> was created without expected prop 'name'");
|
|
}
|
|
|
|
if (
|
|
data === undefined &&
|
|
!("data" in $$props || $$self.$$.bound[$$self.$$.props["data"]])
|
|
) {
|
|
console.warn("<Tag> was created without expected prop 'data'");
|
|
}
|
|
});
|
|
|
|
const writable_props = ["name", "data", "url"];
|
|
|
|
Object.keys($$props).forEach((key) => {
|
|
if (
|
|
!~writable_props.indexOf(key) &&
|
|
key.slice(0, 2) !== "$$" &&
|
|
key !== "slot"
|
|
)
|
|
console.warn(`<Tag> was created with unknown prop '${key}'`);
|
|
});
|
|
|
|
function select_change_handler() {
|
|
name = select_value(this);
|
|
$$invalidate(0, name);
|
|
}
|
|
|
|
const click_handler = () => {
|
|
dispatch("remove", data.id);
|
|
};
|
|
|
|
$$self.$$set = ($$props) => {
|
|
if ("name" in $$props) $$invalidate(0, (name = $$props.name));
|
|
if ("data" in $$props) $$invalidate(1, (data = $$props.data));
|
|
if ("url" in $$props) $$invalidate(2, (url = $$props.url));
|
|
};
|
|
|
|
$$self.$capture_state = () => ({
|
|
OPTIONS,
|
|
createEventDispatcher,
|
|
name,
|
|
data,
|
|
url,
|
|
dispatch,
|
|
confidence,
|
|
scrubberMove,
|
|
scrubberReset,
|
|
});
|
|
|
|
$$self.$inject_state = ($$props) => {
|
|
if ("name" in $$props) $$invalidate(0, (name = $$props.name));
|
|
if ("data" in $$props) $$invalidate(1, (data = $$props.data));
|
|
if ("url" in $$props) $$invalidate(2, (url = $$props.url));
|
|
};
|
|
|
|
if ($$props && "$$inject" in $$props) {
|
|
$$self.$inject_state($$props.$$inject);
|
|
}
|
|
|
|
return [name, data, url, dispatch, select_change_handler, click_handler];
|
|
}
|
|
|
|
class Tag extends SvelteComponentDev {
|
|
constructor(options) {
|
|
super(options);
|
|
init(this, options, instance$2, create_fragment$2, safe_not_equal, {
|
|
name: 0,
|
|
data: 1,
|
|
url: 2,
|
|
});
|
|
|
|
dispatch_dev("SvelteRegisterComponent", {
|
|
component: this,
|
|
tagName: "Tag",
|
|
options,
|
|
id: create_fragment$2.name,
|
|
});
|
|
}
|
|
|
|
get name() {
|
|
throw new Error(
|
|
"<Tag>: Props cannot be read directly from the component instance unless compiling with 'accessors: true' or '<svelte:options accessors/>'"
|
|
);
|
|
}
|
|
|
|
set name(value) {
|
|
throw new Error(
|
|
"<Tag>: Props cannot be set directly on the component instance unless compiling with 'accessors: true' or '<svelte:options accessors/>'"
|
|
);
|
|
}
|
|
|
|
get data() {
|
|
throw new Error(
|
|
"<Tag>: Props cannot be read directly from the component instance unless compiling with 'accessors: true' or '<svelte:options accessors/>'"
|
|
);
|
|
}
|
|
|
|
set data(value) {
|
|
throw new Error(
|
|
"<Tag>: Props cannot be set directly on the component instance unless compiling with 'accessors: true' or '<svelte:options accessors/>'"
|
|
);
|
|
}
|
|
|
|
get url() {
|
|
throw new Error(
|
|
"<Tag>: Props cannot be read directly from the component instance unless compiling with 'accessors: true' or '<svelte:options accessors/>'"
|
|
);
|
|
}
|
|
|
|
set url(value) {
|
|
throw new Error(
|
|
"<Tag>: Props cannot be set directly on the component instance unless compiling with 'accessors: true' or '<svelte:options accessors/>'"
|
|
);
|
|
}
|
|
}
|
|
|
|
/* src/TagMatches.svelte generated by Svelte v3.59.2 */
|
|
|
|
const { Object: Object_1 } = globals;
|
|
|
|
const file$1 = "src/TagMatches.svelte";
|
|
|
|
function get_each_context(ctx, list, i) {
|
|
const child_ctx = ctx.slice();
|
|
child_ctx[15] = list[i][0];
|
|
child_ctx[16] = list[i][1];
|
|
child_ctx[17] = list;
|
|
child_ctx[18] = i;
|
|
return child_ctx;
|
|
}
|
|
|
|
// (81:0) {#if visible}
|
|
function create_if_block(ctx) {
|
|
let div8;
|
|
let div7;
|
|
let div6;
|
|
let div0;
|
|
let h3;
|
|
let t1;
|
|
let div2;
|
|
let div1;
|
|
let each_blocks = [];
|
|
let each_1_lookup = new Map();
|
|
let t2;
|
|
let div5;
|
|
let div3;
|
|
let button0;
|
|
let t4;
|
|
let button1;
|
|
let t5;
|
|
let t6;
|
|
let div4;
|
|
let t7;
|
|
let input;
|
|
let t8;
|
|
let t9_value = /*threshold*/ ctx[0] * 100 + "";
|
|
let t9;
|
|
let t10;
|
|
let div8_intro;
|
|
let div8_outro;
|
|
let current;
|
|
let mounted;
|
|
let dispose;
|
|
let each_value = /*filteredMatches*/ ctx[5];
|
|
validate_each_argument(each_value);
|
|
const get_key = (ctx) => /*tagData*/ ctx[16].id;
|
|
validate_each_keys(ctx, each_value, get_each_context, get_key);
|
|
|
|
for (let i = 0; i < each_value.length; i += 1) {
|
|
let child_ctx = get_each_context(ctx, each_value, i);
|
|
let key = get_key(child_ctx);
|
|
each_1_lookup.set(
|
|
key,
|
|
(each_blocks[i] = create_each_block(key, child_ctx))
|
|
);
|
|
}
|
|
|
|
let if_block = /*saving*/ ctx[3] && create_if_block_1(ctx);
|
|
|
|
const block = {
|
|
c: function create() {
|
|
div8 = element("div");
|
|
div7 = element("div");
|
|
div6 = element("div");
|
|
div0 = element("div");
|
|
h3 = element("h3");
|
|
h3.textContent = "Stash Tag";
|
|
t1 = space();
|
|
div2 = element("div");
|
|
div1 = element("div");
|
|
|
|
for (let i = 0; i < each_blocks.length; i += 1) {
|
|
each_blocks[i].c();
|
|
}
|
|
|
|
t2 = space();
|
|
div5 = element("div");
|
|
div3 = element("div");
|
|
button0 = element("button");
|
|
button0.textContent = "Close";
|
|
t4 = space();
|
|
button1 = element("button");
|
|
if (if_block) if_block.c();
|
|
t5 = text("\n Add Tags");
|
|
t6 = space();
|
|
div4 = element("div");
|
|
t7 = text("Threshold: ");
|
|
input = element("input");
|
|
t8 = space();
|
|
t9 = text(t9_value);
|
|
t10 = text(" %");
|
|
attr_dev(h3, "class", "modal-title");
|
|
add_location(h3, file$1, 94, 10, 2253);
|
|
attr_dev(div0, "class", "modal-header svelte-9viihb");
|
|
add_location(div0, file$1, 93, 8, 2216);
|
|
attr_dev(div1, "class", "row justify-content-center");
|
|
add_location(div1, file$1, 97, 10, 2350);
|
|
attr_dev(div2, "class", "modal-body");
|
|
add_location(div2, file$1, 96, 8, 2315);
|
|
attr_dev(button0, "id", "tags-cancel");
|
|
attr_dev(button0, "type", "button");
|
|
attr_dev(button0, "class", "ml-2 btn btn-secondary");
|
|
add_location(button0, file$1, 116, 12, 2933);
|
|
attr_dev(button1, "id", "tags-accept");
|
|
attr_dev(button1, "type", "button");
|
|
attr_dev(button1, "class", "ml-2 btn btn-primary");
|
|
add_location(button1, file$1, 122, 12, 3116);
|
|
add_location(div3, file$1, 115, 10, 2915);
|
|
attr_dev(input, "type", "range");
|
|
attr_dev(input, "min", "0.2");
|
|
attr_dev(input, "max", "0.9");
|
|
attr_dev(input, "step", "0.1");
|
|
attr_dev(input, "id", "stash-tag-threshold");
|
|
set_style(input, "margin", "0px");
|
|
set_style(input, "height", "10px");
|
|
add_location(input, file$1, 135, 23, 3464);
|
|
add_location(div4, file$1, 134, 10, 3435);
|
|
attr_dev(div5, "class", "ModalFooter modal-footer svelte-9viihb");
|
|
add_location(div5, file$1, 114, 8, 2866);
|
|
attr_dev(div6, "class", "modal-content");
|
|
add_location(div6, file$1, 92, 6, 2180);
|
|
attr_dev(
|
|
div7,
|
|
"class",
|
|
"modal-dialog modal-xl top-accent svelte-9viihb"
|
|
);
|
|
add_location(div7, file$1, 91, 4, 2127);
|
|
attr_dev(div8, "role", "dialog");
|
|
attr_dev(div8, "aria-modal", "true");
|
|
attr_dev(div8, "class", "fade ModalComponent modal show");
|
|
attr_dev(div8, "tabindex", "-1");
|
|
set_style(div8, "display", "block");
|
|
add_location(div8, file$1, 81, 2, 1884);
|
|
},
|
|
m: function mount(target, anchor) {
|
|
insert_dev(target, div8, anchor);
|
|
append_dev(div8, div7);
|
|
append_dev(div7, div6);
|
|
append_dev(div6, div0);
|
|
append_dev(div0, h3);
|
|
append_dev(div6, t1);
|
|
append_dev(div6, div2);
|
|
append_dev(div2, div1);
|
|
|
|
for (let i = 0; i < each_blocks.length; i += 1) {
|
|
if (each_blocks[i]) {
|
|
each_blocks[i].m(div1, null);
|
|
}
|
|
}
|
|
|
|
append_dev(div6, t2);
|
|
append_dev(div6, div5);
|
|
append_dev(div5, div3);
|
|
append_dev(div3, button0);
|
|
append_dev(div3, t4);
|
|
append_dev(div3, button1);
|
|
if (if_block) if_block.m(button1, null);
|
|
append_dev(button1, t5);
|
|
append_dev(div5, t6);
|
|
append_dev(div5, div4);
|
|
append_dev(div4, t7);
|
|
append_dev(div4, input);
|
|
set_input_value(input, /*threshold*/ ctx[0]);
|
|
append_dev(div4, t8);
|
|
append_dev(div4, t9);
|
|
append_dev(div4, t10);
|
|
/*div8_binding*/ ctx[13](div8);
|
|
current = true;
|
|
|
|
if (!mounted) {
|
|
dispose = [
|
|
listen_dev(
|
|
button0,
|
|
"click",
|
|
/*close*/ ctx[6],
|
|
false,
|
|
false,
|
|
false,
|
|
false
|
|
),
|
|
listen_dev(
|
|
button1,
|
|
"click",
|
|
/*save*/ ctx[8],
|
|
false,
|
|
false,
|
|
false,
|
|
false
|
|
),
|
|
listen_dev(input, "change", /*input_change_input_handler*/ ctx[12]),
|
|
listen_dev(input, "input", /*input_change_input_handler*/ ctx[12]),
|
|
listen_dev(
|
|
input,
|
|
"change",
|
|
/*changeThreshold*/ ctx[9],
|
|
false,
|
|
false,
|
|
false,
|
|
false
|
|
),
|
|
];
|
|
|
|
mounted = true;
|
|
}
|
|
},
|
|
p: function update(ctx, dirty) {
|
|
if (dirty & /*filteredMatches, url, remove*/ 162) {
|
|
each_value = /*filteredMatches*/ ctx[5];
|
|
validate_each_argument(each_value);
|
|
group_outros();
|
|
for (let i = 0; i < each_blocks.length; i += 1) each_blocks[i].r();
|
|
validate_each_keys(ctx, each_value, get_each_context, get_key);
|
|
each_blocks = update_keyed_each(
|
|
each_blocks,
|
|
dirty,
|
|
get_key,
|
|
1,
|
|
ctx,
|
|
each_value,
|
|
each_1_lookup,
|
|
div1,
|
|
fix_and_outro_and_destroy_block,
|
|
create_each_block,
|
|
null,
|
|
get_each_context
|
|
);
|
|
for (let i = 0; i < each_blocks.length; i += 1) each_blocks[i].a();
|
|
check_outros();
|
|
}
|
|
|
|
if (/*saving*/ ctx[3]) {
|
|
if (if_block);
|
|
else {
|
|
if_block = create_if_block_1(ctx);
|
|
if_block.c();
|
|
if_block.m(button1, t5);
|
|
}
|
|
} else if (if_block) {
|
|
if_block.d(1);
|
|
if_block = null;
|
|
}
|
|
|
|
if (dirty & /*threshold*/ 1) {
|
|
set_input_value(input, /*threshold*/ ctx[0]);
|
|
}
|
|
|
|
if (
|
|
(!current || dirty & /*threshold*/ 1) &&
|
|
t9_value !== (t9_value = /*threshold*/ ctx[0] * 100 + "")
|
|
)
|
|
set_data_dev(t9, t9_value);
|
|
},
|
|
i: function intro(local) {
|
|
if (current) return;
|
|
|
|
for (let i = 0; i < each_value.length; i += 1) {
|
|
transition_in(each_blocks[i]);
|
|
}
|
|
|
|
add_render_callback(() => {
|
|
if (!current) return;
|
|
if (div8_outro) div8_outro.end(1);
|
|
div8_intro = create_in_transition(div8, fly, {
|
|
y: 100,
|
|
duration: 400,
|
|
});
|
|
div8_intro.start();
|
|
});
|
|
|
|
current = true;
|
|
},
|
|
o: function outro(local) {
|
|
for (let i = 0; i < each_blocks.length; i += 1) {
|
|
transition_out(each_blocks[i]);
|
|
}
|
|
|
|
if (div8_intro) div8_intro.invalidate();
|
|
div8_outro = create_out_transition(div8, fly, {
|
|
y: -100,
|
|
duration: 400,
|
|
});
|
|
current = false;
|
|
},
|
|
d: function destroy(detaching) {
|
|
if (detaching) detach_dev(div8);
|
|
|
|
for (let i = 0; i < each_blocks.length; i += 1) {
|
|
each_blocks[i].d();
|
|
}
|
|
|
|
if (if_block) if_block.d();
|
|
/*div8_binding*/ ctx[13](null);
|
|
if (detaching && div8_outro) div8_outro.end();
|
|
mounted = false;
|
|
run_all(dispose);
|
|
},
|
|
};
|
|
|
|
dispatch_dev("SvelteRegisterBlock", {
|
|
block,
|
|
id: create_if_block.name,
|
|
type: "if",
|
|
source: "(81:0) {#if visible}",
|
|
ctx,
|
|
});
|
|
|
|
return block;
|
|
}
|
|
|
|
// (99:12) {#each filteredMatches as [tagName, tagData] (tagData.id)}
|
|
function create_each_block(key_1, ctx) {
|
|
let div;
|
|
let tag;
|
|
let updating_name;
|
|
let t;
|
|
let div_intro;
|
|
let div_outro;
|
|
let rect;
|
|
let stop_animation = noop;
|
|
let current;
|
|
|
|
function tag_name_binding(value) {
|
|
/*tag_name_binding*/ ctx[11](
|
|
value,
|
|
/*tagName*/ ctx[15],
|
|
/*each_value*/ ctx[17],
|
|
/*each_index*/ ctx[18]
|
|
);
|
|
}
|
|
|
|
let tag_props = {
|
|
data: /*tagData*/ ctx[16],
|
|
url: /*url*/ ctx[1],
|
|
};
|
|
|
|
if (/*tagName*/ ctx[15] !== void 0) {
|
|
tag_props.name = /*tagName*/ ctx[15];
|
|
}
|
|
|
|
tag = new Tag({ props: tag_props, $$inline: true });
|
|
binding_callbacks.push(() => bind(tag, "name", tag_name_binding));
|
|
tag.$on("remove", /*remove*/ ctx[7]);
|
|
|
|
const block = {
|
|
key: key_1,
|
|
first: null,
|
|
c: function create() {
|
|
div = element("div");
|
|
create_component(tag.$$.fragment);
|
|
t = space();
|
|
add_location(div, file$1, 99, 14, 2476);
|
|
this.first = div;
|
|
},
|
|
m: function mount(target, anchor) {
|
|
insert_dev(target, div, anchor);
|
|
mount_component(tag, div, null);
|
|
append_dev(div, t);
|
|
current = true;
|
|
},
|
|
p: function update(new_ctx, dirty) {
|
|
ctx = new_ctx;
|
|
const tag_changes = {};
|
|
if (dirty & /*filteredMatches*/ 32)
|
|
tag_changes.data = /*tagData*/ ctx[16];
|
|
if (dirty & /*url*/ 2) tag_changes.url = /*url*/ ctx[1];
|
|
|
|
if (!updating_name && dirty & /*filteredMatches*/ 32) {
|
|
updating_name = true;
|
|
tag_changes.name = /*tagName*/ ctx[15];
|
|
add_flush_callback(() => (updating_name = false));
|
|
}
|
|
|
|
tag.$set(tag_changes);
|
|
},
|
|
r: function measure() {
|
|
rect = div.getBoundingClientRect();
|
|
},
|
|
f: function fix() {
|
|
fix_position(div);
|
|
stop_animation();
|
|
add_transform(div, rect);
|
|
},
|
|
a: function animate() {
|
|
stop_animation();
|
|
stop_animation = create_animation(div, rect, flip, {
|
|
duration: 250,
|
|
easing: quintOut,
|
|
});
|
|
},
|
|
i: function intro(local) {
|
|
if (current) return;
|
|
transition_in(tag.$$.fragment, local);
|
|
|
|
add_render_callback(() => {
|
|
if (!current) return;
|
|
if (div_outro) div_outro.end(1);
|
|
div_intro = create_in_transition(div, fade, {});
|
|
div_intro.start();
|
|
});
|
|
|
|
current = true;
|
|
},
|
|
o: function outro(local) {
|
|
transition_out(tag.$$.fragment, local);
|
|
if (div_intro) div_intro.invalidate();
|
|
div_outro = create_out_transition(div, fade, {});
|
|
current = false;
|
|
},
|
|
d: function destroy(detaching) {
|
|
if (detaching) detach_dev(div);
|
|
destroy_component(tag);
|
|
if (detaching && div_outro) div_outro.end();
|
|
},
|
|
};
|
|
|
|
dispatch_dev("SvelteRegisterBlock", {
|
|
block,
|
|
id: create_each_block.name,
|
|
type: "each",
|
|
source:
|
|
"(99:12) {#each filteredMatches as [tagName, tagData] (tagData.id)}",
|
|
ctx,
|
|
});
|
|
|
|
return block;
|
|
}
|
|
|
|
// (129:14) {#if saving}
|
|
function create_if_block_1(ctx) {
|
|
let div;
|
|
|
|
const block = {
|
|
c: function create() {
|
|
div = element("div");
|
|
attr_dev(div, "class", "lds-dual-ring svelte-9viihb");
|
|
add_location(div, file$1, 129, 16, 3313);
|
|
},
|
|
m: function mount(target, anchor) {
|
|
insert_dev(target, div, anchor);
|
|
},
|
|
d: function destroy(detaching) {
|
|
if (detaching) detach_dev(div);
|
|
},
|
|
};
|
|
|
|
dispatch_dev("SvelteRegisterBlock", {
|
|
block,
|
|
id: create_if_block_1.name,
|
|
type: "if",
|
|
source: "(129:14) {#if saving}",
|
|
ctx,
|
|
});
|
|
|
|
return block;
|
|
}
|
|
|
|
function create_fragment$1(ctx) {
|
|
let if_block_anchor;
|
|
let current;
|
|
let if_block = /*visible*/ ctx[2] && create_if_block(ctx);
|
|
|
|
const block = {
|
|
c: function create() {
|
|
if (if_block) if_block.c();
|
|
if_block_anchor = empty();
|
|
},
|
|
l: function claim(nodes) {
|
|
throw new Error(
|
|
"options.hydrate only works if the component was compiled with the `hydratable: true` option"
|
|
);
|
|
},
|
|
m: function mount(target, anchor) {
|
|
if (if_block) if_block.m(target, anchor);
|
|
insert_dev(target, if_block_anchor, anchor);
|
|
current = true;
|
|
},
|
|
p: function update(ctx, [dirty]) {
|
|
if (/*visible*/ ctx[2]) {
|
|
if (if_block) {
|
|
if_block.p(ctx, dirty);
|
|
|
|
if (dirty & /*visible*/ 4) {
|
|
transition_in(if_block, 1);
|
|
}
|
|
} else {
|
|
if_block = create_if_block(ctx);
|
|
if_block.c();
|
|
transition_in(if_block, 1);
|
|
if_block.m(if_block_anchor.parentNode, if_block_anchor);
|
|
}
|
|
} else if (if_block) {
|
|
group_outros();
|
|
|
|
transition_out(if_block, 1, 1, () => {
|
|
if_block = null;
|
|
});
|
|
|
|
check_outros();
|
|
}
|
|
},
|
|
i: function intro(local) {
|
|
if (current) return;
|
|
transition_in(if_block);
|
|
current = true;
|
|
},
|
|
o: function outro(local) {
|
|
transition_out(if_block);
|
|
current = false;
|
|
},
|
|
d: function destroy(detaching) {
|
|
if (if_block) if_block.d(detaching);
|
|
if (detaching) detach_dev(if_block_anchor);
|
|
},
|
|
};
|
|
|
|
dispatch_dev("SvelteRegisterBlock", {
|
|
block,
|
|
id: create_fragment$1.name,
|
|
type: "component",
|
|
source: "",
|
|
ctx,
|
|
});
|
|
|
|
return block;
|
|
}
|
|
|
|
function instance$1($$self, $$props, $$invalidate) {
|
|
let filteredMatches;
|
|
let { $$slots: slots = {}, $$scope } = $$props;
|
|
validate_slots("TagMatches", slots, []);
|
|
let { matches = [] } = $$props;
|
|
let { url = "" } = $$props;
|
|
let { threshold = 0.2 } = $$props;
|
|
let visible = false;
|
|
let saving = false;
|
|
let modal;
|
|
let tags;
|
|
matches = Object.entries(matches)
|
|
.sort((a, b) => b[1].frame - a[1].frame)
|
|
.reverse();
|
|
|
|
// add random id to each match
|
|
matches = matches.map((x) => {
|
|
x[1].id = Math.random().toString(36).substring(7);
|
|
return x;
|
|
});
|
|
|
|
onMount(async () => {
|
|
// so we see a nice transition
|
|
$$invalidate(2, (visible = true));
|
|
|
|
tags = await getAllTags();
|
|
});
|
|
|
|
async function close() {
|
|
// so we see a nice transition
|
|
$$invalidate(2, (visible = false));
|
|
|
|
setTimeout(() => {
|
|
modal.remove();
|
|
}, 400);
|
|
}
|
|
|
|
function remove(event) {
|
|
const id = event.detail;
|
|
$$invalidate(10, (matches = matches.filter((x) => x[1].id !== id)));
|
|
}
|
|
|
|
async function save() {
|
|
$$invalidate(3, (saving = true));
|
|
const [, scene_id] = getScenarioAndID();
|
|
let existingTags = await getTagsForScene(scene_id);
|
|
|
|
for (const [tag] of filteredMatches) {
|
|
let tagLower = tag.toLowerCase();
|
|
|
|
// if tag doesn't exist, create it
|
|
if (tags[tagLower] === undefined) {
|
|
existingTags.push(await createTag(tag));
|
|
} else if (!existingTags.includes(tags[tagLower])) {
|
|
existingTags.push(tags[tagLower]);
|
|
}
|
|
}
|
|
|
|
await updateScene(scene_id, existingTags);
|
|
$$invalidate(3, (saving = false));
|
|
close();
|
|
location.reload();
|
|
}
|
|
|
|
function changeThreshold() {
|
|
localStorage.setItem("stash-tag-threshold", threshold);
|
|
}
|
|
|
|
const writable_props = ["matches", "url", "threshold"];
|
|
|
|
Object_1.keys($$props).forEach((key) => {
|
|
if (
|
|
!~writable_props.indexOf(key) &&
|
|
key.slice(0, 2) !== "$$" &&
|
|
key !== "slot"
|
|
)
|
|
console.warn(`<TagMatches> was created with unknown prop '${key}'`);
|
|
});
|
|
|
|
function tag_name_binding(value, tagName, each_value, each_index) {
|
|
each_value[each_index][0] = value;
|
|
($$invalidate(5, filteredMatches), $$invalidate(10, matches)),
|
|
$$invalidate(0, threshold);
|
|
}
|
|
|
|
function input_change_input_handler() {
|
|
threshold = to_number(this.value);
|
|
$$invalidate(0, threshold);
|
|
}
|
|
|
|
function div8_binding($$value) {
|
|
binding_callbacks[$$value ? "unshift" : "push"](() => {
|
|
modal = $$value;
|
|
$$invalidate(4, modal);
|
|
});
|
|
}
|
|
|
|
$$self.$$set = ($$props) => {
|
|
if ("matches" in $$props) $$invalidate(10, (matches = $$props.matches));
|
|
if ("url" in $$props) $$invalidate(1, (url = $$props.url));
|
|
if ("threshold" in $$props)
|
|
$$invalidate(0, (threshold = $$props.threshold));
|
|
};
|
|
|
|
$$self.$capture_state = () => ({
|
|
Tag,
|
|
onMount,
|
|
fly,
|
|
fade,
|
|
flip,
|
|
quintOut,
|
|
createTag,
|
|
getAllTags,
|
|
getTagsForScene,
|
|
updateScene,
|
|
getScenarioAndID,
|
|
matches,
|
|
url,
|
|
threshold,
|
|
visible,
|
|
saving,
|
|
modal,
|
|
tags,
|
|
close,
|
|
remove,
|
|
save,
|
|
changeThreshold,
|
|
filteredMatches,
|
|
});
|
|
|
|
$$self.$inject_state = ($$props) => {
|
|
if ("matches" in $$props) $$invalidate(10, (matches = $$props.matches));
|
|
if ("url" in $$props) $$invalidate(1, (url = $$props.url));
|
|
if ("threshold" in $$props)
|
|
$$invalidate(0, (threshold = $$props.threshold));
|
|
if ("visible" in $$props) $$invalidate(2, (visible = $$props.visible));
|
|
if ("saving" in $$props) $$invalidate(3, (saving = $$props.saving));
|
|
if ("modal" in $$props) $$invalidate(4, (modal = $$props.modal));
|
|
if ("tags" in $$props) tags = $$props.tags;
|
|
if ("filteredMatches" in $$props)
|
|
$$invalidate(5, (filteredMatches = $$props.filteredMatches));
|
|
};
|
|
|
|
if ($$props && "$$inject" in $$props) {
|
|
$$self.$inject_state($$props.$$inject);
|
|
}
|
|
|
|
$$self.$$.update = () => {
|
|
if ($$self.$$.dirty & /*matches, threshold*/ 1025) {
|
|
$$invalidate(
|
|
5,
|
|
(filteredMatches = matches.filter((x) => x[1].prob > threshold))
|
|
);
|
|
}
|
|
};
|
|
|
|
return [
|
|
threshold,
|
|
url,
|
|
visible,
|
|
saving,
|
|
modal,
|
|
filteredMatches,
|
|
close,
|
|
remove,
|
|
save,
|
|
changeThreshold,
|
|
matches,
|
|
tag_name_binding,
|
|
input_change_input_handler,
|
|
div8_binding,
|
|
];
|
|
}
|
|
|
|
class TagMatches extends SvelteComponentDev {
|
|
constructor(options) {
|
|
super(options);
|
|
init(this, options, instance$1, create_fragment$1, safe_not_equal, {
|
|
matches: 10,
|
|
url: 1,
|
|
threshold: 0,
|
|
});
|
|
|
|
dispatch_dev("SvelteRegisterComponent", {
|
|
component: this,
|
|
tagName: "TagMatches",
|
|
options,
|
|
id: create_fragment$1.name,
|
|
});
|
|
}
|
|
|
|
get matches() {
|
|
throw new Error(
|
|
"<TagMatches>: Props cannot be read directly from the component instance unless compiling with 'accessors: true' or '<svelte:options accessors/>'"
|
|
);
|
|
}
|
|
|
|
set matches(value) {
|
|
throw new Error(
|
|
"<TagMatches>: Props cannot be set directly on the component instance unless compiling with 'accessors: true' or '<svelte:options accessors/>'"
|
|
);
|
|
}
|
|
|
|
get url() {
|
|
throw new Error(
|
|
"<TagMatches>: Props cannot be read directly from the component instance unless compiling with 'accessors: true' or '<svelte:options accessors/>'"
|
|
);
|
|
}
|
|
|
|
set url(value) {
|
|
throw new Error(
|
|
"<TagMatches>: Props cannot be set directly on the component instance unless compiling with 'accessors: true' or '<svelte:options accessors/>'"
|
|
);
|
|
}
|
|
|
|
get threshold() {
|
|
throw new Error(
|
|
"<TagMatches>: Props cannot be read directly from the component instance unless compiling with 'accessors: true' or '<svelte:options accessors/>'"
|
|
);
|
|
}
|
|
|
|
set threshold(value) {
|
|
throw new Error(
|
|
"<TagMatches>: Props cannot be set directly on the component instance unless compiling with 'accessors: true' or '<svelte:options accessors/>'"
|
|
);
|
|
}
|
|
}
|
|
|
|
/* src/TagButton.svelte generated by Svelte v3.59.2 */
|
|
|
|
const { console: console_1 } = globals;
|
|
const file = "src/TagButton.svelte";
|
|
|
|
function create_fragment(ctx) {
|
|
let button;
|
|
let svg;
|
|
let path;
|
|
let mounted;
|
|
let dispose;
|
|
|
|
const block = {
|
|
c: function create() {
|
|
button = element("button");
|
|
svg = svg_element("svg");
|
|
path = svg_element("path");
|
|
attr_dev(path, "fill", "white");
|
|
attr_dev(
|
|
path,
|
|
"d",
|
|
"m21.41 11.58l-9-9C12.05 2.22 11.55 2 11 2H4a2 2 0 0 0-2 2v7c0 .55.22 1.05.59 1.42l9 9c.36.36.86.58 1.41.58c.55 0 1.05-.22 1.41-.59l7-7c.37-.36.59-.86.59-1.41c0-.55-.23-1.06-.59-1.42M5.5 7A1.5 1.5 0 0 1 4 5.5A1.5 1.5 0 0 1 5.5 4A1.5 1.5 0 0 1 7 5.5A1.5 1.5 0 0 1 5.5 7m11.77 8.27L13 19.54l-4.27-4.27A2.52 2.52 0 0 1 8 13.5a2.5 2.5 0 0 1 2.5-2.5c.69 0 1.32.28 1.77.74l.73.72l.73-.73c.45-.45 1.08-.73 1.77-.73a2.5 2.5 0 0 1 2.5 2.5c0 .69-.28 1.32-.73 1.77Z"
|
|
);
|
|
add_location(path, file, 78, 85, 2558);
|
|
attr_dev(svg, "xmlns", "http://www.w3.org/2000/svg");
|
|
attr_dev(svg, "width", "24");
|
|
attr_dev(svg, "height", "24");
|
|
attr_dev(svg, "viewBox", "0 0 24 24");
|
|
add_location(svg, file, 78, 2, 2475);
|
|
attr_dev(button, "id", "stashtag");
|
|
attr_dev(button, "title", "Scan for tags");
|
|
attr_dev(button, "class", "svelte-xcs6vi");
|
|
toggle_class(button, "scanner", /*scanner*/ ctx[0]);
|
|
add_location(button, file, 77, 0, 2395);
|
|
},
|
|
l: function claim(nodes) {
|
|
throw new Error(
|
|
"options.hydrate only works if the component was compiled with the `hydratable: true` option"
|
|
);
|
|
},
|
|
m: function mount(target, anchor) {
|
|
insert_dev(target, button, anchor);
|
|
append_dev(button, svg);
|
|
append_dev(svg, path);
|
|
|
|
if (!mounted) {
|
|
dispose = listen_dev(
|
|
button,
|
|
"click",
|
|
/*getTags*/ ctx[1],
|
|
false,
|
|
false,
|
|
false,
|
|
false
|
|
);
|
|
mounted = true;
|
|
}
|
|
},
|
|
p: function update(ctx, [dirty]) {
|
|
if (dirty & /*scanner*/ 1) {
|
|
toggle_class(button, "scanner", /*scanner*/ ctx[0]);
|
|
}
|
|
},
|
|
i: noop,
|
|
o: noop,
|
|
d: function destroy(detaching) {
|
|
if (detaching) detach_dev(button);
|
|
mounted = false;
|
|
dispose();
|
|
},
|
|
};
|
|
|
|
dispatch_dev("SvelteRegisterBlock", {
|
|
block,
|
|
id: create_fragment.name,
|
|
type: "component",
|
|
source: "",
|
|
ctx,
|
|
});
|
|
|
|
return block;
|
|
}
|
|
|
|
function instance($$self, $$props, $$invalidate) {
|
|
let { $$slots: slots = {}, $$scope } = $$props;
|
|
validate_slots("TagButton", slots, []);
|
|
let scanner = false;
|
|
|
|
async function getTags() {
|
|
$$invalidate(0, (scanner = true));
|
|
const [, scene_id] = getScenarioAndID();
|
|
let url = await getUrlSprite(scene_id);
|
|
console.log(url);
|
|
|
|
if (!url) {
|
|
alert(
|
|
"No sprite found, please ensure you have sprites enabled and generated for your scenes."
|
|
);
|
|
$$invalidate(0, (scanner = false));
|
|
return;
|
|
}
|
|
|
|
// get image blob
|
|
const iblob = await fetch(url).then((res) => res.blob());
|
|
|
|
let image = await new Promise((resolve) => {
|
|
let reader = new FileReader();
|
|
reader.onload = () => resolve(reader.result);
|
|
reader.readAsDataURL(iblob);
|
|
});
|
|
|
|
// get vtt blob
|
|
const vtt_url = url.replace("_sprite.jpg", "_thumbs.vtt");
|
|
|
|
const vblob = await fetch(vtt_url).then((res) => res.blob());
|
|
|
|
let vtt = await new Promise((resolve) => {
|
|
let reader = new FileReader();
|
|
reader.onload = () => resolve(reader.result);
|
|
reader.readAsDataURL(vblob);
|
|
});
|
|
|
|
// query the api with a threshold of 0.2 as we want to do the filtering ourselves
|
|
var data = { data: [image, vtt, 0.2] };
|
|
|
|
fetch(STASHMARKER_API_URL, {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/json; charset=utf-8",
|
|
},
|
|
body: JSON.stringify(data),
|
|
})
|
|
.then((response) => {
|
|
if (response.status !== 200) {
|
|
$$invalidate(0, (scanner = false));
|
|
alert(
|
|
"Something went wrong. It's likely a server issue, Please try again later."
|
|
);
|
|
return;
|
|
}
|
|
|
|
return response.json();
|
|
})
|
|
.then((data) => {
|
|
$$invalidate(0, (scanner = false));
|
|
|
|
if (data.data[0].length === 0) {
|
|
alert("No tags found");
|
|
return;
|
|
}
|
|
|
|
// grab stash-tag-threshold from local storage or set to default
|
|
let threshold = localStorage.getItem("stash-tag-threshold") || 0.4;
|
|
|
|
new TagMatches({
|
|
target: document.body,
|
|
props: { matches: data.data[0], url, threshold },
|
|
});
|
|
})
|
|
.catch((error) => {
|
|
$$invalidate(0, (scanner = false));
|
|
|
|
if (error.message === "") {
|
|
alert("Error: Service may be down. please try again later.");
|
|
} else {
|
|
alert("Error: " + error.message);
|
|
}
|
|
});
|
|
}
|
|
|
|
const writable_props = [];
|
|
|
|
Object.keys($$props).forEach((key) => {
|
|
if (
|
|
!~writable_props.indexOf(key) &&
|
|
key.slice(0, 2) !== "$$" &&
|
|
key !== "slot"
|
|
)
|
|
console_1.warn(`<TagButton> was created with unknown prop '${key}'`);
|
|
});
|
|
|
|
$$self.$capture_state = () => ({
|
|
getScenarioAndID,
|
|
getUrlSprite,
|
|
STASHMARKER_API_URL,
|
|
TagMatches,
|
|
scanner,
|
|
getTags,
|
|
});
|
|
|
|
$$self.$inject_state = ($$props) => {
|
|
if ("scanner" in $$props) $$invalidate(0, (scanner = $$props.scanner));
|
|
};
|
|
|
|
if ($$props && "$$inject" in $$props) {
|
|
$$self.$inject_state($$props.$$inject);
|
|
}
|
|
|
|
return [scanner, getTags];
|
|
}
|
|
|
|
class TagButton extends SvelteComponentDev {
|
|
constructor(options) {
|
|
super(options);
|
|
init(this, options, instance, create_fragment, safe_not_equal, {});
|
|
|
|
dispatch_dev("SvelteRegisterComponent", {
|
|
component: this,
|
|
tagName: "TagButton",
|
|
options,
|
|
id: create_fragment.name,
|
|
});
|
|
}
|
|
}
|
|
|
|
function addButtons(elms) {
|
|
if (!document.querySelector("#stashtag")) new TagButton({ target: elms });
|
|
if (!document.querySelector("#stashmarker"))
|
|
new MarkerButton({ target: elms });
|
|
}
|
|
// v25 and v24 compatibility
|
|
csLib.PathElementListener(
|
|
"/scenes/",
|
|
".scene-toolbar-group .btn-group, .ml-auto .btn-group",
|
|
addButtons
|
|
);
|
|
})();
|