diff --git "a/src/backend/gradio_molecule2d/templates/component/index.js" "b/src/backend/gradio_molecule2d/templates/component/index.js" new file mode 100644--- /dev/null +++ "b/src/backend/gradio_molecule2d/templates/component/index.js" @@ -0,0 +1,11013 @@ +const { + SvelteComponent: zf, + assign: Hf, + create_slot: Wf, + detach: qf, + element: Vf, + get_all_dirty_from_scope: Xf, + get_slot_changes: Yf, + get_spread_update: Gf, + init: Uf, + insert: Zf, + safe_not_equal: Kf, + set_dynamic_element_data: ta, + set_style: ot, + toggle_class: Mt, + transition_in: ja, + transition_out: Ja, + update_slot_base: jf +} = window.__gradio__svelte__internal; +function Jf(d) { + let e, t, r; + const i = ( + /*#slots*/ + d[18].default + ), s = Wf( + i, + d, + /*$$scope*/ + d[17], + null + ); + let a = [ + { "data-testid": ( + /*test_id*/ + d[7] + ) }, + { id: ( + /*elem_id*/ + d[2] + ) }, + { + class: t = "block " + /*elem_classes*/ + d[3].join(" ") + " svelte-nl1om8" + } + ], n = {}; + for (let h = 0; h < a.length; h += 1) + n = Hf(n, a[h]); + return { + c() { + e = Vf( + /*tag*/ + d[14] + ), s && s.c(), ta( + /*tag*/ + d[14] + )(e, n), Mt( + e, + "hidden", + /*visible*/ + d[10] === !1 + ), Mt( + e, + "padded", + /*padding*/ + d[6] + ), Mt( + e, + "border_focus", + /*border_mode*/ + d[5] === "focus" + ), Mt( + e, + "border_contrast", + /*border_mode*/ + d[5] === "contrast" + ), Mt(e, "hide-container", !/*explicit_call*/ + d[8] && !/*container*/ + d[9]), ot( + e, + "height", + /*get_dimension*/ + d[15]( + /*height*/ + d[0] + ) + ), ot(e, "width", typeof /*width*/ + d[1] == "number" ? `calc(min(${/*width*/ + d[1]}px, 100%))` : ( + /*get_dimension*/ + d[15]( + /*width*/ + d[1] + ) + )), ot( + e, + "border-style", + /*variant*/ + d[4] + ), ot( + e, + "overflow", + /*allow_overflow*/ + d[11] ? "visible" : "hidden" + ), ot( + e, + "flex-grow", + /*scale*/ + d[12] + ), ot(e, "min-width", `calc(min(${/*min_width*/ + d[13]}px, 100%))`), ot(e, "border-width", "var(--block-border-width)"); + }, + m(h, l) { + Zf(h, e, l), s && s.m(e, null), r = !0; + }, + p(h, l) { + s && s.p && (!r || l & /*$$scope*/ + 131072) && jf( + s, + i, + h, + /*$$scope*/ + h[17], + r ? Yf( + i, + /*$$scope*/ + h[17], + l, + null + ) : Xf( + /*$$scope*/ + h[17] + ), + null + ), ta( + /*tag*/ + h[14] + )(e, n = Gf(a, [ + (!r || l & /*test_id*/ + 128) && { "data-testid": ( + /*test_id*/ + h[7] + ) }, + (!r || l & /*elem_id*/ + 4) && { id: ( + /*elem_id*/ + h[2] + ) }, + (!r || l & /*elem_classes*/ + 8 && t !== (t = "block " + /*elem_classes*/ + h[3].join(" ") + " svelte-nl1om8")) && { class: t } + ])), Mt( + e, + "hidden", + /*visible*/ + h[10] === !1 + ), Mt( + e, + "padded", + /*padding*/ + h[6] + ), Mt( + e, + "border_focus", + /*border_mode*/ + h[5] === "focus" + ), Mt( + e, + "border_contrast", + /*border_mode*/ + h[5] === "contrast" + ), Mt(e, "hide-container", !/*explicit_call*/ + h[8] && !/*container*/ + h[9]), l & /*height*/ + 1 && ot( + e, + "height", + /*get_dimension*/ + h[15]( + /*height*/ + h[0] + ) + ), l & /*width*/ + 2 && ot(e, "width", typeof /*width*/ + h[1] == "number" ? `calc(min(${/*width*/ + h[1]}px, 100%))` : ( + /*get_dimension*/ + h[15]( + /*width*/ + h[1] + ) + )), l & /*variant*/ + 16 && ot( + e, + "border-style", + /*variant*/ + h[4] + ), l & /*allow_overflow*/ + 2048 && ot( + e, + "overflow", + /*allow_overflow*/ + h[11] ? "visible" : "hidden" + ), l & /*scale*/ + 4096 && ot( + e, + "flex-grow", + /*scale*/ + h[12] + ), l & /*min_width*/ + 8192 && ot(e, "min-width", `calc(min(${/*min_width*/ + h[13]}px, 100%))`); + }, + i(h) { + r || (ja(s, h), r = !0); + }, + o(h) { + Ja(s, h), r = !1; + }, + d(h) { + h && qf(e), s && s.d(h); + } + }; +} +function Qf(d) { + let e, t = ( + /*tag*/ + d[14] && Jf(d) + ); + return { + c() { + t && t.c(); + }, + m(r, i) { + t && t.m(r, i), e = !0; + }, + p(r, [i]) { + /*tag*/ + r[14] && t.p(r, i); + }, + i(r) { + e || (ja(t, r), e = !0); + }, + o(r) { + Ja(t, r), e = !1; + }, + d(r) { + t && t.d(r); + } + }; +} +function eu(d, e, t) { + let { $$slots: r = {}, $$scope: i } = e, { height: s = void 0 } = e, { width: a = void 0 } = e, { elem_id: n = "" } = e, { elem_classes: h = [] } = e, { variant: l = "solid" } = e, { border_mode: c = "base" } = e, { padding: u = !0 } = e, { type: g = "normal" } = e, { test_id: m = void 0 } = e, { explicit_call: _ = !1 } = e, { container: v = !0 } = e, { visible: N = !0 } = e, { allow_overflow: B = !0 } = e, { scale: x = null } = e, { min_width: L = 0 } = e, k = g === "fieldset" ? "fieldset" : "div"; + const z = (D) => { + if (D !== void 0) { + if (typeof D == "number") + return D + "px"; + if (typeof D == "string") + return D; + } + }; + return d.$$set = (D) => { + "height" in D && t(0, s = D.height), "width" in D && t(1, a = D.width), "elem_id" in D && t(2, n = D.elem_id), "elem_classes" in D && t(3, h = D.elem_classes), "variant" in D && t(4, l = D.variant), "border_mode" in D && t(5, c = D.border_mode), "padding" in D && t(6, u = D.padding), "type" in D && t(16, g = D.type), "test_id" in D && t(7, m = D.test_id), "explicit_call" in D && t(8, _ = D.explicit_call), "container" in D && t(9, v = D.container), "visible" in D && t(10, N = D.visible), "allow_overflow" in D && t(11, B = D.allow_overflow), "scale" in D && t(12, x = D.scale), "min_width" in D && t(13, L = D.min_width), "$$scope" in D && t(17, i = D.$$scope); + }, [ + s, + a, + n, + h, + l, + c, + u, + m, + _, + v, + N, + B, + x, + L, + k, + z, + g, + i, + r + ]; +} +class tu extends zf { + constructor(e) { + super(), Uf(this, e, eu, Qf, Kf, { + height: 0, + width: 1, + elem_id: 2, + elem_classes: 3, + variant: 4, + border_mode: 5, + padding: 6, + type: 16, + test_id: 7, + explicit_call: 8, + container: 9, + visible: 10, + allow_overflow: 11, + scale: 12, + min_width: 13 + }); + } +} +const { + SvelteComponent: ru, + attr: iu, + create_slot: nu, + detach: su, + element: au, + get_all_dirty_from_scope: lu, + get_slot_changes: ou, + init: hu, + insert: fu, + safe_not_equal: uu, + transition_in: cu, + transition_out: gu, + update_slot_base: du +} = window.__gradio__svelte__internal; +function pu(d) { + let e, t; + const r = ( + /*#slots*/ + d[1].default + ), i = nu( + r, + d, + /*$$scope*/ + d[0], + null + ); + return { + c() { + e = au("div"), i && i.c(), iu(e, "class", "svelte-1hnfib2"); + }, + m(s, a) { + fu(s, e, a), i && i.m(e, null), t = !0; + }, + p(s, [a]) { + i && i.p && (!t || a & /*$$scope*/ + 1) && du( + i, + r, + s, + /*$$scope*/ + s[0], + t ? ou( + r, + /*$$scope*/ + s[0], + a, + null + ) : lu( + /*$$scope*/ + s[0] + ), + null + ); + }, + i(s) { + t || (cu(i, s), t = !0); + }, + o(s) { + gu(i, s), t = !1; + }, + d(s) { + s && su(e), i && i.d(s); + } + }; +} +function vu(d, e, t) { + let { $$slots: r = {}, $$scope: i } = e; + return d.$$set = (s) => { + "$$scope" in s && t(0, i = s.$$scope); + }, [i, r]; +} +class mu extends ru { + constructor(e) { + super(), hu(this, e, vu, pu, uu, {}); + } +} +const { + SvelteComponent: bu, + attr: ra, + check_outros: wu, + create_component: yu, + create_slot: _u, + destroy_component: Su, + detach: Ni, + element: Cu, + empty: Au, + get_all_dirty_from_scope: Nu, + get_slot_changes: ku, + group_outros: Ru, + init: xu, + insert: ki, + mount_component: Tu, + safe_not_equal: Eu, + set_data: Lu, + space: Mu, + text: Bu, + toggle_class: kr, + transition_in: Gr, + transition_out: Ri, + update_slot_base: Du +} = window.__gradio__svelte__internal; +function ia(d) { + let e, t; + return e = new mu({ + props: { + $$slots: { default: [Pu] }, + $$scope: { ctx: d } + } + }), { + c() { + yu(e.$$.fragment); + }, + m(r, i) { + Tu(e, r, i), t = !0; + }, + p(r, i) { + const s = {}; + i & /*$$scope, info*/ + 10 && (s.$$scope = { dirty: i, ctx: r }), e.$set(s); + }, + i(r) { + t || (Gr(e.$$.fragment, r), t = !0); + }, + o(r) { + Ri(e.$$.fragment, r), t = !1; + }, + d(r) { + Su(e, r); + } + }; +} +function Pu(d) { + let e; + return { + c() { + e = Bu( + /*info*/ + d[1] + ); + }, + m(t, r) { + ki(t, e, r); + }, + p(t, r) { + r & /*info*/ + 2 && Lu( + e, + /*info*/ + t[1] + ); + }, + d(t) { + t && Ni(e); + } + }; +} +function $u(d) { + let e, t, r, i; + const s = ( + /*#slots*/ + d[2].default + ), a = _u( + s, + d, + /*$$scope*/ + d[3], + null + ); + let n = ( + /*info*/ + d[1] && ia(d) + ); + return { + c() { + e = Cu("span"), a && a.c(), t = Mu(), n && n.c(), r = Au(), ra(e, "data-testid", "block-info"), ra(e, "class", "svelte-22c38v"), kr(e, "sr-only", !/*show_label*/ + d[0]), kr(e, "hide", !/*show_label*/ + d[0]), kr( + e, + "has-info", + /*info*/ + d[1] != null + ); + }, + m(h, l) { + ki(h, e, l), a && a.m(e, null), ki(h, t, l), n && n.m(h, l), ki(h, r, l), i = !0; + }, + p(h, [l]) { + a && a.p && (!i || l & /*$$scope*/ + 8) && Du( + a, + s, + h, + /*$$scope*/ + h[3], + i ? ku( + s, + /*$$scope*/ + h[3], + l, + null + ) : Nu( + /*$$scope*/ + h[3] + ), + null + ), (!i || l & /*show_label*/ + 1) && kr(e, "sr-only", !/*show_label*/ + h[0]), (!i || l & /*show_label*/ + 1) && kr(e, "hide", !/*show_label*/ + h[0]), (!i || l & /*info*/ + 2) && kr( + e, + "has-info", + /*info*/ + h[1] != null + ), /*info*/ + h[1] ? n ? (n.p(h, l), l & /*info*/ + 2 && Gr(n, 1)) : (n = ia(h), n.c(), Gr(n, 1), n.m(r.parentNode, r)) : n && (Ru(), Ri(n, 1, 1, () => { + n = null; + }), wu()); + }, + i(h) { + i || (Gr(a, h), Gr(n), i = !0); + }, + o(h) { + Ri(a, h), Ri(n), i = !1; + }, + d(h) { + h && (Ni(e), Ni(t), Ni(r)), a && a.d(h), n && n.d(h); + } + }; +} +function Iu(d, e, t) { + let { $$slots: r = {}, $$scope: i } = e, { show_label: s = !0 } = e, { info: a = void 0 } = e; + return d.$$set = (n) => { + "show_label" in n && t(0, s = n.show_label), "info" in n && t(1, a = n.info), "$$scope" in n && t(3, i = n.$$scope); + }, [s, a, r, i]; +} +class Ou extends bu { + constructor(e) { + super(), xu(this, e, Iu, $u, Eu, { show_label: 0, info: 1 }); + } +} +const { + SvelteComponent: Fu, + append: On, + attr: qt, + bubble: zu, + create_component: Hu, + destroy_component: Wu, + detach: Qa, + element: Fn, + init: qu, + insert: el, + listen: Vu, + mount_component: Xu, + safe_not_equal: Yu, + set_data: Gu, + set_style: Rr, + space: Uu, + text: Zu, + toggle_class: rt, + transition_in: Ku, + transition_out: ju +} = window.__gradio__svelte__internal; +function na(d) { + let e, t; + return { + c() { + e = Fn("span"), t = Zu( + /*label*/ + d[1] + ), qt(e, "class", "svelte-1lrphxw"); + }, + m(r, i) { + el(r, e, i), On(e, t); + }, + p(r, i) { + i & /*label*/ + 2 && Gu( + t, + /*label*/ + r[1] + ); + }, + d(r) { + r && Qa(e); + } + }; +} +function Ju(d) { + let e, t, r, i, s, a, n, h = ( + /*show_label*/ + d[2] && na(d) + ); + return i = new /*Icon*/ + d[0]({}), { + c() { + e = Fn("button"), h && h.c(), t = Uu(), r = Fn("div"), Hu(i.$$.fragment), qt(r, "class", "svelte-1lrphxw"), rt( + r, + "small", + /*size*/ + d[4] === "small" + ), rt( + r, + "large", + /*size*/ + d[4] === "large" + ), rt( + r, + "medium", + /*size*/ + d[4] === "medium" + ), e.disabled = /*disabled*/ + d[7], qt( + e, + "aria-label", + /*label*/ + d[1] + ), qt( + e, + "aria-haspopup", + /*hasPopup*/ + d[8] + ), qt( + e, + "title", + /*label*/ + d[1] + ), qt(e, "class", "svelte-1lrphxw"), rt( + e, + "pending", + /*pending*/ + d[3] + ), rt( + e, + "padded", + /*padded*/ + d[5] + ), rt( + e, + "highlight", + /*highlight*/ + d[6] + ), rt( + e, + "transparent", + /*transparent*/ + d[9] + ), Rr(e, "color", !/*disabled*/ + d[7] && /*_color*/ + d[12] ? ( + /*_color*/ + d[12] + ) : "var(--block-label-text-color)"), Rr(e, "--bg-color", /*disabled*/ + d[7] ? "auto" : ( + /*background*/ + d[10] + )), Rr( + e, + "margin-left", + /*offset*/ + d[11] + "px" + ); + }, + m(l, c) { + el(l, e, c), h && h.m(e, null), On(e, t), On(e, r), Xu(i, r, null), s = !0, a || (n = Vu( + e, + "click", + /*click_handler*/ + d[14] + ), a = !0); + }, + p(l, [c]) { + /*show_label*/ + l[2] ? h ? h.p(l, c) : (h = na(l), h.c(), h.m(e, t)) : h && (h.d(1), h = null), (!s || c & /*size*/ + 16) && rt( + r, + "small", + /*size*/ + l[4] === "small" + ), (!s || c & /*size*/ + 16) && rt( + r, + "large", + /*size*/ + l[4] === "large" + ), (!s || c & /*size*/ + 16) && rt( + r, + "medium", + /*size*/ + l[4] === "medium" + ), (!s || c & /*disabled*/ + 128) && (e.disabled = /*disabled*/ + l[7]), (!s || c & /*label*/ + 2) && qt( + e, + "aria-label", + /*label*/ + l[1] + ), (!s || c & /*hasPopup*/ + 256) && qt( + e, + "aria-haspopup", + /*hasPopup*/ + l[8] + ), (!s || c & /*label*/ + 2) && qt( + e, + "title", + /*label*/ + l[1] + ), (!s || c & /*pending*/ + 8) && rt( + e, + "pending", + /*pending*/ + l[3] + ), (!s || c & /*padded*/ + 32) && rt( + e, + "padded", + /*padded*/ + l[5] + ), (!s || c & /*highlight*/ + 64) && rt( + e, + "highlight", + /*highlight*/ + l[6] + ), (!s || c & /*transparent*/ + 512) && rt( + e, + "transparent", + /*transparent*/ + l[9] + ), c & /*disabled, _color*/ + 4224 && Rr(e, "color", !/*disabled*/ + l[7] && /*_color*/ + l[12] ? ( + /*_color*/ + l[12] + ) : "var(--block-label-text-color)"), c & /*disabled, background*/ + 1152 && Rr(e, "--bg-color", /*disabled*/ + l[7] ? "auto" : ( + /*background*/ + l[10] + )), c & /*offset*/ + 2048 && Rr( + e, + "margin-left", + /*offset*/ + l[11] + "px" + ); + }, + i(l) { + s || (Ku(i.$$.fragment, l), s = !0); + }, + o(l) { + ju(i.$$.fragment, l), s = !1; + }, + d(l) { + l && Qa(e), h && h.d(), Wu(i), a = !1, n(); + } + }; +} +function Qu(d, e, t) { + let r, { Icon: i } = e, { label: s = "" } = e, { show_label: a = !1 } = e, { pending: n = !1 } = e, { size: h = "small" } = e, { padded: l = !0 } = e, { highlight: c = !1 } = e, { disabled: u = !1 } = e, { hasPopup: g = !1 } = e, { color: m = "var(--block-label-text-color)" } = e, { transparent: _ = !1 } = e, { background: v = "var(--background-fill-primary)" } = e, { offset: N = 0 } = e; + function B(x) { + zu.call(this, d, x); + } + return d.$$set = (x) => { + "Icon" in x && t(0, i = x.Icon), "label" in x && t(1, s = x.label), "show_label" in x && t(2, a = x.show_label), "pending" in x && t(3, n = x.pending), "size" in x && t(4, h = x.size), "padded" in x && t(5, l = x.padded), "highlight" in x && t(6, c = x.highlight), "disabled" in x && t(7, u = x.disabled), "hasPopup" in x && t(8, g = x.hasPopup), "color" in x && t(13, m = x.color), "transparent" in x && t(9, _ = x.transparent), "background" in x && t(10, v = x.background), "offset" in x && t(11, N = x.offset); + }, d.$$.update = () => { + d.$$.dirty & /*highlight, color*/ + 8256 && t(12, r = c ? "var(--color-accent)" : m); + }, [ + i, + s, + a, + n, + h, + l, + c, + u, + g, + _, + v, + N, + r, + m, + B + ]; +} +class tl extends Fu { + constructor(e) { + super(), qu(this, e, Qu, Ju, Yu, { + Icon: 0, + label: 1, + show_label: 2, + pending: 3, + size: 4, + padded: 5, + highlight: 6, + disabled: 7, + hasPopup: 8, + color: 13, + transparent: 9, + background: 10, + offset: 11 + }); + } +} +const { + SvelteComponent: ec, + append: kn, + attr: Nt, + detach: tc, + init: rc, + insert: ic, + noop: Rn, + safe_not_equal: nc, + set_style: Bt, + svg_element: yi +} = window.__gradio__svelte__internal; +function sc(d) { + let e, t, r, i; + return { + c() { + e = yi("svg"), t = yi("g"), r = yi("path"), i = yi("path"), Nt(r, "d", "M18,6L6.087,17.913"), Bt(r, "fill", "none"), Bt(r, "fill-rule", "nonzero"), Bt(r, "stroke-width", "2px"), Nt(t, "transform", "matrix(1.14096,-0.140958,-0.140958,1.14096,-0.0559523,0.0559523)"), Nt(i, "d", "M4.364,4.364L19.636,19.636"), Bt(i, "fill", "none"), Bt(i, "fill-rule", "nonzero"), Bt(i, "stroke-width", "2px"), Nt(e, "width", "100%"), Nt(e, "height", "100%"), Nt(e, "viewBox", "0 0 24 24"), Nt(e, "version", "1.1"), Nt(e, "xmlns", "http://www.w3.org/2000/svg"), Nt(e, "xmlns:xlink", "http://www.w3.org/1999/xlink"), Nt(e, "xml:space", "preserve"), Nt(e, "stroke", "currentColor"), Bt(e, "fill-rule", "evenodd"), Bt(e, "clip-rule", "evenodd"), Bt(e, "stroke-linecap", "round"), Bt(e, "stroke-linejoin", "round"); + }, + m(s, a) { + ic(s, e, a), kn(e, t), kn(t, r), kn(e, i); + }, + p: Rn, + i: Rn, + o: Rn, + d(s) { + s && tc(e); + } + }; +} +class rl extends ec { + constructor(e) { + super(), rc(this, e, null, sc, nc, {}); + } +} +const { + SvelteComponent: ac, + append: lc, + attr: kt, + detach: oc, + init: hc, + insert: fc, + noop: xn, + safe_not_equal: uc, + svg_element: sa +} = window.__gradio__svelte__internal; +function cc(d) { + let e, t; + return { + c() { + e = sa("svg"), t = sa("path"), kt(t, "d", "M17 3a2.828 2.828 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5L17 3z"), kt(e, "xmlns", "http://www.w3.org/2000/svg"), kt(e, "width", "100%"), kt(e, "height", "100%"), kt(e, "viewBox", "0 0 24 24"), kt(e, "fill", "none"), kt(e, "stroke", "currentColor"), kt(e, "stroke-width", "1.5"), kt(e, "stroke-linecap", "round"), kt(e, "stroke-linejoin", "round"), kt(e, "class", "feather feather-edit-2"); + }, + m(r, i) { + fc(r, e, i), lc(e, t); + }, + p: xn, + i: xn, + o: xn, + d(r) { + r && oc(e); + } + }; +} +class gc extends ac { + constructor(e) { + super(), hc(this, e, null, cc, uc, {}); + } +} +const dc = [ + { color: "red", primary: 600, secondary: 100 }, + { color: "green", primary: 600, secondary: 100 }, + { color: "blue", primary: 600, secondary: 100 }, + { color: "yellow", primary: 500, secondary: 100 }, + { color: "purple", primary: 600, secondary: 100 }, + { color: "teal", primary: 600, secondary: 100 }, + { color: "orange", primary: 600, secondary: 100 }, + { color: "cyan", primary: 600, secondary: 100 }, + { color: "lime", primary: 500, secondary: 100 }, + { color: "pink", primary: 600, secondary: 100 } +], aa = { + inherit: "inherit", + current: "currentColor", + transparent: "transparent", + black: "#000", + white: "#fff", + slate: { + 50: "#f8fafc", + 100: "#f1f5f9", + 200: "#e2e8f0", + 300: "#cbd5e1", + 400: "#94a3b8", + 500: "#64748b", + 600: "#475569", + 700: "#334155", + 800: "#1e293b", + 900: "#0f172a", + 950: "#020617" + }, + gray: { + 50: "#f9fafb", + 100: "#f3f4f6", + 200: "#e5e7eb", + 300: "#d1d5db", + 400: "#9ca3af", + 500: "#6b7280", + 600: "#4b5563", + 700: "#374151", + 800: "#1f2937", + 900: "#111827", + 950: "#030712" + }, + zinc: { + 50: "#fafafa", + 100: "#f4f4f5", + 200: "#e4e4e7", + 300: "#d4d4d8", + 400: "#a1a1aa", + 500: "#71717a", + 600: "#52525b", + 700: "#3f3f46", + 800: "#27272a", + 900: "#18181b", + 950: "#09090b" + }, + neutral: { + 50: "#fafafa", + 100: "#f5f5f5", + 200: "#e5e5e5", + 300: "#d4d4d4", + 400: "#a3a3a3", + 500: "#737373", + 600: "#525252", + 700: "#404040", + 800: "#262626", + 900: "#171717", + 950: "#0a0a0a" + }, + stone: { + 50: "#fafaf9", + 100: "#f5f5f4", + 200: "#e7e5e4", + 300: "#d6d3d1", + 400: "#a8a29e", + 500: "#78716c", + 600: "#57534e", + 700: "#44403c", + 800: "#292524", + 900: "#1c1917", + 950: "#0c0a09" + }, + red: { + 50: "#fef2f2", + 100: "#fee2e2", + 200: "#fecaca", + 300: "#fca5a5", + 400: "#f87171", + 500: "#ef4444", + 600: "#dc2626", + 700: "#b91c1c", + 800: "#991b1b", + 900: "#7f1d1d", + 950: "#450a0a" + }, + orange: { + 50: "#fff7ed", + 100: "#ffedd5", + 200: "#fed7aa", + 300: "#fdba74", + 400: "#fb923c", + 500: "#f97316", + 600: "#ea580c", + 700: "#c2410c", + 800: "#9a3412", + 900: "#7c2d12", + 950: "#431407" + }, + amber: { + 50: "#fffbeb", + 100: "#fef3c7", + 200: "#fde68a", + 300: "#fcd34d", + 400: "#fbbf24", + 500: "#f59e0b", + 600: "#d97706", + 700: "#b45309", + 800: "#92400e", + 900: "#78350f", + 950: "#451a03" + }, + yellow: { + 50: "#fefce8", + 100: "#fef9c3", + 200: "#fef08a", + 300: "#fde047", + 400: "#facc15", + 500: "#eab308", + 600: "#ca8a04", + 700: "#a16207", + 800: "#854d0e", + 900: "#713f12", + 950: "#422006" + }, + lime: { + 50: "#f7fee7", + 100: "#ecfccb", + 200: "#d9f99d", + 300: "#bef264", + 400: "#a3e635", + 500: "#84cc16", + 600: "#65a30d", + 700: "#4d7c0f", + 800: "#3f6212", + 900: "#365314", + 950: "#1a2e05" + }, + green: { + 50: "#f0fdf4", + 100: "#dcfce7", + 200: "#bbf7d0", + 300: "#86efac", + 400: "#4ade80", + 500: "#22c55e", + 600: "#16a34a", + 700: "#15803d", + 800: "#166534", + 900: "#14532d", + 950: "#052e16" + }, + emerald: { + 50: "#ecfdf5", + 100: "#d1fae5", + 200: "#a7f3d0", + 300: "#6ee7b7", + 400: "#34d399", + 500: "#10b981", + 600: "#059669", + 700: "#047857", + 800: "#065f46", + 900: "#064e3b", + 950: "#022c22" + }, + teal: { + 50: "#f0fdfa", + 100: "#ccfbf1", + 200: "#99f6e4", + 300: "#5eead4", + 400: "#2dd4bf", + 500: "#14b8a6", + 600: "#0d9488", + 700: "#0f766e", + 800: "#115e59", + 900: "#134e4a", + 950: "#042f2e" + }, + cyan: { + 50: "#ecfeff", + 100: "#cffafe", + 200: "#a5f3fc", + 300: "#67e8f9", + 400: "#22d3ee", + 500: "#06b6d4", + 600: "#0891b2", + 700: "#0e7490", + 800: "#155e75", + 900: "#164e63", + 950: "#083344" + }, + sky: { + 50: "#f0f9ff", + 100: "#e0f2fe", + 200: "#bae6fd", + 300: "#7dd3fc", + 400: "#38bdf8", + 500: "#0ea5e9", + 600: "#0284c7", + 700: "#0369a1", + 800: "#075985", + 900: "#0c4a6e", + 950: "#082f49" + }, + blue: { + 50: "#eff6ff", + 100: "#dbeafe", + 200: "#bfdbfe", + 300: "#93c5fd", + 400: "#60a5fa", + 500: "#3b82f6", + 600: "#2563eb", + 700: "#1d4ed8", + 800: "#1e40af", + 900: "#1e3a8a", + 950: "#172554" + }, + indigo: { + 50: "#eef2ff", + 100: "#e0e7ff", + 200: "#c7d2fe", + 300: "#a5b4fc", + 400: "#818cf8", + 500: "#6366f1", + 600: "#4f46e5", + 700: "#4338ca", + 800: "#3730a3", + 900: "#312e81", + 950: "#1e1b4b" + }, + violet: { + 50: "#f5f3ff", + 100: "#ede9fe", + 200: "#ddd6fe", + 300: "#c4b5fd", + 400: "#a78bfa", + 500: "#8b5cf6", + 600: "#7c3aed", + 700: "#6d28d9", + 800: "#5b21b6", + 900: "#4c1d95", + 950: "#2e1065" + }, + purple: { + 50: "#faf5ff", + 100: "#f3e8ff", + 200: "#e9d5ff", + 300: "#d8b4fe", + 400: "#c084fc", + 500: "#a855f7", + 600: "#9333ea", + 700: "#7e22ce", + 800: "#6b21a8", + 900: "#581c87", + 950: "#3b0764" + }, + fuchsia: { + 50: "#fdf4ff", + 100: "#fae8ff", + 200: "#f5d0fe", + 300: "#f0abfc", + 400: "#e879f9", + 500: "#d946ef", + 600: "#c026d3", + 700: "#a21caf", + 800: "#86198f", + 900: "#701a75", + 950: "#4a044e" + }, + pink: { + 50: "#fdf2f8", + 100: "#fce7f3", + 200: "#fbcfe8", + 300: "#f9a8d4", + 400: "#f472b6", + 500: "#ec4899", + 600: "#db2777", + 700: "#be185d", + 800: "#9d174d", + 900: "#831843", + 950: "#500724" + }, + rose: { + 50: "#fff1f2", + 100: "#ffe4e6", + 200: "#fecdd3", + 300: "#fda4af", + 400: "#fb7185", + 500: "#f43f5e", + 600: "#e11d48", + 700: "#be123c", + 800: "#9f1239", + 900: "#881337", + 950: "#4c0519" + } +}; +dc.reduce( + (d, { color: e, primary: t, secondary: r }) => ({ + ...d, + [e]: { + primary: aa[e][t], + secondary: aa[e][r] + } + }), + {} +); +function Mr(d) { + let e = ["", "k", "M", "G", "T", "P", "E", "Z"], t = 0; + for (; d > 1e3 && t < e.length - 1; ) + d /= 1e3, t++; + let r = e[t]; + return (Number.isInteger(d) ? d : d.toFixed(1)) + r; +} +function xi() { +} +function pc(d, e) { + return d != d ? e == e : d !== e || d && typeof d == "object" || typeof d == "function"; +} +const il = typeof window < "u"; +let la = il ? () => window.performance.now() : () => Date.now(), nl = il ? (d) => requestAnimationFrame(d) : xi; +const Br = /* @__PURE__ */ new Set(); +function sl(d) { + Br.forEach((e) => { + e.c(d) || (Br.delete(e), e.f()); + }), Br.size !== 0 && nl(sl); +} +function vc(d) { + let e; + return Br.size === 0 && nl(sl), { + promise: new Promise((t) => { + Br.add(e = { c: d, f: t }); + }), + abort() { + Br.delete(e); + } + }; +} +const xr = []; +function mc(d, e = xi) { + let t; + const r = /* @__PURE__ */ new Set(); + function i(n) { + if (pc(d, n) && (d = n, t)) { + const h = !xr.length; + for (const l of r) + l[1](), xr.push(l, d); + if (h) { + for (let l = 0; l < xr.length; l += 2) + xr[l][0](xr[l + 1]); + xr.length = 0; + } + } + } + function s(n) { + i(n(d)); + } + function a(n, h = xi) { + const l = [n, h]; + return r.add(l), r.size === 1 && (t = e(i, s) || xi), n(d), () => { + r.delete(l), r.size === 0 && t && (t(), t = null); + }; + } + return { set: i, update: s, subscribe: a }; +} +function oa(d) { + return Object.prototype.toString.call(d) === "[object Date]"; +} +function zn(d, e, t, r) { + if (typeof t == "number" || oa(t)) { + const i = r - t, s = (t - e) / (d.dt || 1 / 60), a = d.opts.stiffness * i, n = d.opts.damping * s, h = (a - n) * d.inv_mass, l = (s + h) * d.dt; + return Math.abs(l) < d.opts.precision && Math.abs(i) < d.opts.precision ? r : (d.settled = !1, oa(t) ? new Date(t.getTime() + l) : t + l); + } else { + if (Array.isArray(t)) + return t.map( + (i, s) => zn(d, e[s], t[s], r[s]) + ); + if (typeof t == "object") { + const i = {}; + for (const s in t) + i[s] = zn(d, e[s], t[s], r[s]); + return i; + } else + throw new Error(`Cannot spring ${typeof t} values`); + } +} +function ha(d, e = {}) { + const t = mc(d), { stiffness: r = 0.15, damping: i = 0.8, precision: s = 0.01 } = e; + let a, n, h, l = d, c = d, u = 1, g = 0, m = !1; + function _(N, B = {}) { + c = N; + const x = h = {}; + return d == null || B.hard || v.stiffness >= 1 && v.damping >= 1 ? (m = !0, a = la(), l = N, t.set(d = c), Promise.resolve()) : (B.soft && (g = 1 / ((B.soft === !0 ? 0.5 : +B.soft) * 60), u = 0), n || (a = la(), m = !1, n = vc((L) => { + if (m) + return m = !1, n = null, !1; + u = Math.min(u + g, 1); + const k = { + inv_mass: u, + opts: v, + settled: !0, + dt: (L - a) * 60 / 1e3 + }, z = zn(k, l, d, c); + return a = L, l = d, t.set(d = z), k.settled && (n = null), !k.settled; + })), new Promise((L) => { + n.promise.then(() => { + x === h && L(); + }); + })); + } + const v = { + set: _, + update: (N, B) => _(N(c, d), B), + subscribe: t.subscribe, + stiffness: r, + damping: i, + precision: s + }; + return v; +} +const { + SvelteComponent: bc, + append: Rt, + attr: ge, + component_subscribe: fa, + detach: wc, + element: yc, + init: _c, + insert: Sc, + noop: ua, + safe_not_equal: Cc, + set_style: _i, + svg_element: xt, + toggle_class: ca +} = window.__gradio__svelte__internal, { onMount: Ac } = window.__gradio__svelte__internal; +function Nc(d) { + let e, t, r, i, s, a, n, h, l, c, u, g; + return { + c() { + e = yc("div"), t = xt("svg"), r = xt("g"), i = xt("path"), s = xt("path"), a = xt("path"), n = xt("path"), h = xt("g"), l = xt("path"), c = xt("path"), u = xt("path"), g = xt("path"), ge(i, "d", "M255.926 0.754768L509.702 139.936V221.027L255.926 81.8465V0.754768Z"), ge(i, "fill", "#FF7C00"), ge(i, "fill-opacity", "0.4"), ge(i, "class", "svelte-43sxxs"), ge(s, "d", "M509.69 139.936L254.981 279.641V361.255L509.69 221.55V139.936Z"), ge(s, "fill", "#FF7C00"), ge(s, "class", "svelte-43sxxs"), ge(a, "d", "M0.250138 139.937L254.981 279.641V361.255L0.250138 221.55V139.937Z"), ge(a, "fill", "#FF7C00"), ge(a, "fill-opacity", "0.4"), ge(a, "class", "svelte-43sxxs"), ge(n, "d", "M255.923 0.232622L0.236328 139.936V221.55L255.923 81.8469V0.232622Z"), ge(n, "fill", "#FF7C00"), ge(n, "class", "svelte-43sxxs"), _i(r, "transform", "translate(" + /*$top*/ + d[1][0] + "px, " + /*$top*/ + d[1][1] + "px)"), ge(l, "d", "M255.926 141.5L509.702 280.681V361.773L255.926 222.592V141.5Z"), ge(l, "fill", "#FF7C00"), ge(l, "fill-opacity", "0.4"), ge(l, "class", "svelte-43sxxs"), ge(c, "d", "M509.69 280.679L254.981 420.384V501.998L509.69 362.293V280.679Z"), ge(c, "fill", "#FF7C00"), ge(c, "class", "svelte-43sxxs"), ge(u, "d", "M0.250138 280.681L254.981 420.386V502L0.250138 362.295V280.681Z"), ge(u, "fill", "#FF7C00"), ge(u, "fill-opacity", "0.4"), ge(u, "class", "svelte-43sxxs"), ge(g, "d", "M255.923 140.977L0.236328 280.68V362.294L255.923 222.591V140.977Z"), ge(g, "fill", "#FF7C00"), ge(g, "class", "svelte-43sxxs"), _i(h, "transform", "translate(" + /*$bottom*/ + d[2][0] + "px, " + /*$bottom*/ + d[2][1] + "px)"), ge(t, "viewBox", "-1200 -1200 3000 3000"), ge(t, "fill", "none"), ge(t, "xmlns", "http://www.w3.org/2000/svg"), ge(t, "class", "svelte-43sxxs"), ge(e, "class", "svelte-43sxxs"), ca( + e, + "margin", + /*margin*/ + d[0] + ); + }, + m(m, _) { + Sc(m, e, _), Rt(e, t), Rt(t, r), Rt(r, i), Rt(r, s), Rt(r, a), Rt(r, n), Rt(t, h), Rt(h, l), Rt(h, c), Rt(h, u), Rt(h, g); + }, + p(m, [_]) { + _ & /*$top*/ + 2 && _i(r, "transform", "translate(" + /*$top*/ + m[1][0] + "px, " + /*$top*/ + m[1][1] + "px)"), _ & /*$bottom*/ + 4 && _i(h, "transform", "translate(" + /*$bottom*/ + m[2][0] + "px, " + /*$bottom*/ + m[2][1] + "px)"), _ & /*margin*/ + 1 && ca( + e, + "margin", + /*margin*/ + m[0] + ); + }, + i: ua, + o: ua, + d(m) { + m && wc(e); + } + }; +} +function kc(d, e, t) { + let r, i; + var s = this && this.__awaiter || function(m, _, v, N) { + function B(x) { + return x instanceof v ? x : new v(function(L) { + L(x); + }); + } + return new (v || (v = Promise))(function(x, L) { + function k(Y) { + try { + D(N.next(Y)); + } catch (O) { + L(O); + } + } + function z(Y) { + try { + D(N.throw(Y)); + } catch (O) { + L(O); + } + } + function D(Y) { + Y.done ? x(Y.value) : B(Y.value).then(k, z); + } + D((N = N.apply(m, _ || [])).next()); + }); + }; + let { margin: a = !0 } = e; + const n = ha([0, 0]); + fa(d, n, (m) => t(1, r = m)); + const h = ha([0, 0]); + fa(d, h, (m) => t(2, i = m)); + let l; + function c() { + return s(this, void 0, void 0, function* () { + yield Promise.all([n.set([125, 140]), h.set([-125, -140])]), yield Promise.all([n.set([-125, 140]), h.set([125, -140])]), yield Promise.all([n.set([-125, 0]), h.set([125, -0])]), yield Promise.all([n.set([125, 0]), h.set([-125, 0])]); + }); + } + function u() { + return s(this, void 0, void 0, function* () { + yield c(), l || u(); + }); + } + function g() { + return s(this, void 0, void 0, function* () { + yield Promise.all([n.set([125, 0]), h.set([-125, 0])]), u(); + }); + } + return Ac(() => (g(), () => l = !0)), d.$$set = (m) => { + "margin" in m && t(0, a = m.margin); + }, [a, r, i, n, h]; +} +class Rc extends bc { + constructor(e) { + super(), _c(this, e, kc, Nc, Cc, { margin: 0 }); + } +} +const { + SvelteComponent: xc, + append: gr, + attr: Tt, + binding_callbacks: ga, + check_outros: al, + create_component: ll, + create_slot: Tc, + destroy_component: ol, + destroy_each: hl, + detach: ie, + element: $t, + empty: Ir, + ensure_array_like: Ei, + get_all_dirty_from_scope: Ec, + get_slot_changes: Lc, + group_outros: fl, + init: Mc, + insert: ne, + mount_component: ul, + noop: Hn, + safe_not_equal: Bc, + set_data: bt, + set_style: sr, + space: Et, + text: Re, + toggle_class: mt, + transition_in: dr, + transition_out: pr, + update_slot_base: Dc +} = window.__gradio__svelte__internal, { tick: Pc } = window.__gradio__svelte__internal, { onDestroy: $c } = window.__gradio__svelte__internal, { createEventDispatcher: Ic } = window.__gradio__svelte__internal, Oc = (d) => ({}), da = (d) => ({}); +function pa(d, e, t) { + const r = d.slice(); + return r[41] = e[t], r[43] = t, r; +} +function va(d, e, t) { + const r = d.slice(); + return r[41] = e[t], r; +} +function Fc(d) { + let e, t, r, i, s = ( + /*i18n*/ + d[1]("common.error") + "" + ), a, n, h; + t = new tl({ + props: { + Icon: rl, + label: ( + /*i18n*/ + d[1]("common.clear") + ), + disabled: !1 + } + }), t.$on( + "click", + /*click_handler*/ + d[32] + ); + const l = ( + /*#slots*/ + d[30].error + ), c = Tc( + l, + d, + /*$$scope*/ + d[29], + da + ); + return { + c() { + e = $t("div"), ll(t.$$.fragment), r = Et(), i = $t("span"), a = Re(s), n = Et(), c && c.c(), Tt(e, "class", "clear-status svelte-1yk38uw"), Tt(i, "class", "error svelte-1yk38uw"); + }, + m(u, g) { + ne(u, e, g), ul(t, e, null), ne(u, r, g), ne(u, i, g), gr(i, a), ne(u, n, g), c && c.m(u, g), h = !0; + }, + p(u, g) { + const m = {}; + g[0] & /*i18n*/ + 2 && (m.label = /*i18n*/ + u[1]("common.clear")), t.$set(m), (!h || g[0] & /*i18n*/ + 2) && s !== (s = /*i18n*/ + u[1]("common.error") + "") && bt(a, s), c && c.p && (!h || g[0] & /*$$scope*/ + 536870912) && Dc( + c, + l, + u, + /*$$scope*/ + u[29], + h ? Lc( + l, + /*$$scope*/ + u[29], + g, + Oc + ) : Ec( + /*$$scope*/ + u[29] + ), + da + ); + }, + i(u) { + h || (dr(t.$$.fragment, u), dr(c, u), h = !0); + }, + o(u) { + pr(t.$$.fragment, u), pr(c, u), h = !1; + }, + d(u) { + u && (ie(e), ie(r), ie(i), ie(n)), ol(t), c && c.d(u); + } + }; +} +function zc(d) { + let e, t, r, i, s, a, n, h, l, c = ( + /*variant*/ + d[8] === "default" && /*show_eta_bar*/ + d[18] && /*show_progress*/ + d[6] === "full" && ma(d) + ); + function u(L, k) { + if ( + /*progress*/ + L[7] + ) + return qc; + if ( + /*queue_position*/ + L[2] !== null && /*queue_size*/ + L[3] !== void 0 && /*queue_position*/ + L[2] >= 0 + ) + return Wc; + if ( + /*queue_position*/ + L[2] === 0 + ) + return Hc; + } + let g = u(d), m = g && g(d), _ = ( + /*timer*/ + d[5] && ya(d) + ); + const v = [Gc, Yc], N = []; + function B(L, k) { + return ( + /*last_progress_level*/ + L[15] != null ? 0 : ( + /*show_progress*/ + L[6] === "full" ? 1 : -1 + ) + ); + } + ~(s = B(d)) && (a = N[s] = v[s](d)); + let x = !/*timer*/ + d[5] && Ra(d); + return { + c() { + c && c.c(), e = Et(), t = $t("div"), m && m.c(), r = Et(), _ && _.c(), i = Et(), a && a.c(), n = Et(), x && x.c(), h = Ir(), Tt(t, "class", "progress-text svelte-1yk38uw"), mt( + t, + "meta-text-center", + /*variant*/ + d[8] === "center" + ), mt( + t, + "meta-text", + /*variant*/ + d[8] === "default" + ); + }, + m(L, k) { + c && c.m(L, k), ne(L, e, k), ne(L, t, k), m && m.m(t, null), gr(t, r), _ && _.m(t, null), ne(L, i, k), ~s && N[s].m(L, k), ne(L, n, k), x && x.m(L, k), ne(L, h, k), l = !0; + }, + p(L, k) { + /*variant*/ + L[8] === "default" && /*show_eta_bar*/ + L[18] && /*show_progress*/ + L[6] === "full" ? c ? c.p(L, k) : (c = ma(L), c.c(), c.m(e.parentNode, e)) : c && (c.d(1), c = null), g === (g = u(L)) && m ? m.p(L, k) : (m && m.d(1), m = g && g(L), m && (m.c(), m.m(t, r))), /*timer*/ + L[5] ? _ ? _.p(L, k) : (_ = ya(L), _.c(), _.m(t, null)) : _ && (_.d(1), _ = null), (!l || k[0] & /*variant*/ + 256) && mt( + t, + "meta-text-center", + /*variant*/ + L[8] === "center" + ), (!l || k[0] & /*variant*/ + 256) && mt( + t, + "meta-text", + /*variant*/ + L[8] === "default" + ); + let z = s; + s = B(L), s === z ? ~s && N[s].p(L, k) : (a && (fl(), pr(N[z], 1, 1, () => { + N[z] = null; + }), al()), ~s ? (a = N[s], a ? a.p(L, k) : (a = N[s] = v[s](L), a.c()), dr(a, 1), a.m(n.parentNode, n)) : a = null), /*timer*/ + L[5] ? x && (x.d(1), x = null) : x ? x.p(L, k) : (x = Ra(L), x.c(), x.m(h.parentNode, h)); + }, + i(L) { + l || (dr(a), l = !0); + }, + o(L) { + pr(a), l = !1; + }, + d(L) { + L && (ie(e), ie(t), ie(i), ie(n), ie(h)), c && c.d(L), m && m.d(), _ && _.d(), ~s && N[s].d(L), x && x.d(L); + } + }; +} +function ma(d) { + let e, t = `translateX(${/*eta_level*/ + (d[17] || 0) * 100 - 100}%)`; + return { + c() { + e = $t("div"), Tt(e, "class", "eta-bar svelte-1yk38uw"), sr(e, "transform", t); + }, + m(r, i) { + ne(r, e, i); + }, + p(r, i) { + i[0] & /*eta_level*/ + 131072 && t !== (t = `translateX(${/*eta_level*/ + (r[17] || 0) * 100 - 100}%)`) && sr(e, "transform", t); + }, + d(r) { + r && ie(e); + } + }; +} +function Hc(d) { + let e; + return { + c() { + e = Re("processing |"); + }, + m(t, r) { + ne(t, e, r); + }, + p: Hn, + d(t) { + t && ie(e); + } + }; +} +function Wc(d) { + let e, t = ( + /*queue_position*/ + d[2] + 1 + "" + ), r, i, s, a; + return { + c() { + e = Re("queue: "), r = Re(t), i = Re("/"), s = Re( + /*queue_size*/ + d[3] + ), a = Re(" |"); + }, + m(n, h) { + ne(n, e, h), ne(n, r, h), ne(n, i, h), ne(n, s, h), ne(n, a, h); + }, + p(n, h) { + h[0] & /*queue_position*/ + 4 && t !== (t = /*queue_position*/ + n[2] + 1 + "") && bt(r, t), h[0] & /*queue_size*/ + 8 && bt( + s, + /*queue_size*/ + n[3] + ); + }, + d(n) { + n && (ie(e), ie(r), ie(i), ie(s), ie(a)); + } + }; +} +function qc(d) { + let e, t = Ei( + /*progress*/ + d[7] + ), r = []; + for (let i = 0; i < t.length; i += 1) + r[i] = wa(va(d, t, i)); + return { + c() { + for (let i = 0; i < r.length; i += 1) + r[i].c(); + e = Ir(); + }, + m(i, s) { + for (let a = 0; a < r.length; a += 1) + r[a] && r[a].m(i, s); + ne(i, e, s); + }, + p(i, s) { + if (s[0] & /*progress*/ + 128) { + t = Ei( + /*progress*/ + i[7] + ); + let a; + for (a = 0; a < t.length; a += 1) { + const n = va(i, t, a); + r[a] ? r[a].p(n, s) : (r[a] = wa(n), r[a].c(), r[a].m(e.parentNode, e)); + } + for (; a < r.length; a += 1) + r[a].d(1); + r.length = t.length; + } + }, + d(i) { + i && ie(e), hl(r, i); + } + }; +} +function ba(d) { + let e, t = ( + /*p*/ + d[41].unit + "" + ), r, i, s = " ", a; + function n(c, u) { + return ( + /*p*/ + c[41].length != null ? Xc : Vc + ); + } + let h = n(d), l = h(d); + return { + c() { + l.c(), e = Et(), r = Re(t), i = Re(" | "), a = Re(s); + }, + m(c, u) { + l.m(c, u), ne(c, e, u), ne(c, r, u), ne(c, i, u), ne(c, a, u); + }, + p(c, u) { + h === (h = n(c)) && l ? l.p(c, u) : (l.d(1), l = h(c), l && (l.c(), l.m(e.parentNode, e))), u[0] & /*progress*/ + 128 && t !== (t = /*p*/ + c[41].unit + "") && bt(r, t); + }, + d(c) { + c && (ie(e), ie(r), ie(i), ie(a)), l.d(c); + } + }; +} +function Vc(d) { + let e = Mr( + /*p*/ + d[41].index || 0 + ) + "", t; + return { + c() { + t = Re(e); + }, + m(r, i) { + ne(r, t, i); + }, + p(r, i) { + i[0] & /*progress*/ + 128 && e !== (e = Mr( + /*p*/ + r[41].index || 0 + ) + "") && bt(t, e); + }, + d(r) { + r && ie(t); + } + }; +} +function Xc(d) { + let e = Mr( + /*p*/ + d[41].index || 0 + ) + "", t, r, i = Mr( + /*p*/ + d[41].length + ) + "", s; + return { + c() { + t = Re(e), r = Re("/"), s = Re(i); + }, + m(a, n) { + ne(a, t, n), ne(a, r, n), ne(a, s, n); + }, + p(a, n) { + n[0] & /*progress*/ + 128 && e !== (e = Mr( + /*p*/ + a[41].index || 0 + ) + "") && bt(t, e), n[0] & /*progress*/ + 128 && i !== (i = Mr( + /*p*/ + a[41].length + ) + "") && bt(s, i); + }, + d(a) { + a && (ie(t), ie(r), ie(s)); + } + }; +} +function wa(d) { + let e, t = ( + /*p*/ + d[41].index != null && ba(d) + ); + return { + c() { + t && t.c(), e = Ir(); + }, + m(r, i) { + t && t.m(r, i), ne(r, e, i); + }, + p(r, i) { + /*p*/ + r[41].index != null ? t ? t.p(r, i) : (t = ba(r), t.c(), t.m(e.parentNode, e)) : t && (t.d(1), t = null); + }, + d(r) { + r && ie(e), t && t.d(r); + } + }; +} +function ya(d) { + let e, t = ( + /*eta*/ + d[0] ? `/${/*formatted_eta*/ + d[19]}` : "" + ), r, i; + return { + c() { + e = Re( + /*formatted_timer*/ + d[20] + ), r = Re(t), i = Re("s"); + }, + m(s, a) { + ne(s, e, a), ne(s, r, a), ne(s, i, a); + }, + p(s, a) { + a[0] & /*formatted_timer*/ + 1048576 && bt( + e, + /*formatted_timer*/ + s[20] + ), a[0] & /*eta, formatted_eta*/ + 524289 && t !== (t = /*eta*/ + s[0] ? `/${/*formatted_eta*/ + s[19]}` : "") && bt(r, t); + }, + d(s) { + s && (ie(e), ie(r), ie(i)); + } + }; +} +function Yc(d) { + let e, t; + return e = new Rc({ + props: { margin: ( + /*variant*/ + d[8] === "default" + ) } + }), { + c() { + ll(e.$$.fragment); + }, + m(r, i) { + ul(e, r, i), t = !0; + }, + p(r, i) { + const s = {}; + i[0] & /*variant*/ + 256 && (s.margin = /*variant*/ + r[8] === "default"), e.$set(s); + }, + i(r) { + t || (dr(e.$$.fragment, r), t = !0); + }, + o(r) { + pr(e.$$.fragment, r), t = !1; + }, + d(r) { + ol(e, r); + } + }; +} +function Gc(d) { + let e, t, r, i, s, a = `${/*last_progress_level*/ + d[15] * 100}%`, n = ( + /*progress*/ + d[7] != null && _a(d) + ); + return { + c() { + e = $t("div"), t = $t("div"), n && n.c(), r = Et(), i = $t("div"), s = $t("div"), Tt(t, "class", "progress-level-inner svelte-1yk38uw"), Tt(s, "class", "progress-bar svelte-1yk38uw"), sr(s, "width", a), Tt(i, "class", "progress-bar-wrap svelte-1yk38uw"), Tt(e, "class", "progress-level svelte-1yk38uw"); + }, + m(h, l) { + ne(h, e, l), gr(e, t), n && n.m(t, null), gr(e, r), gr(e, i), gr(i, s), d[31](s); + }, + p(h, l) { + /*progress*/ + h[7] != null ? n ? n.p(h, l) : (n = _a(h), n.c(), n.m(t, null)) : n && (n.d(1), n = null), l[0] & /*last_progress_level*/ + 32768 && a !== (a = `${/*last_progress_level*/ + h[15] * 100}%`) && sr(s, "width", a); + }, + i: Hn, + o: Hn, + d(h) { + h && ie(e), n && n.d(), d[31](null); + } + }; +} +function _a(d) { + let e, t = Ei( + /*progress*/ + d[7] + ), r = []; + for (let i = 0; i < t.length; i += 1) + r[i] = ka(pa(d, t, i)); + return { + c() { + for (let i = 0; i < r.length; i += 1) + r[i].c(); + e = Ir(); + }, + m(i, s) { + for (let a = 0; a < r.length; a += 1) + r[a] && r[a].m(i, s); + ne(i, e, s); + }, + p(i, s) { + if (s[0] & /*progress_level, progress*/ + 16512) { + t = Ei( + /*progress*/ + i[7] + ); + let a; + for (a = 0; a < t.length; a += 1) { + const n = pa(i, t, a); + r[a] ? r[a].p(n, s) : (r[a] = ka(n), r[a].c(), r[a].m(e.parentNode, e)); + } + for (; a < r.length; a += 1) + r[a].d(1); + r.length = t.length; + } + }, + d(i) { + i && ie(e), hl(r, i); + } + }; +} +function Sa(d) { + let e, t, r, i, s = ( + /*i*/ + d[43] !== 0 && Uc() + ), a = ( + /*p*/ + d[41].desc != null && Ca(d) + ), n = ( + /*p*/ + d[41].desc != null && /*progress_level*/ + d[14] && /*progress_level*/ + d[14][ + /*i*/ + d[43] + ] != null && Aa() + ), h = ( + /*progress_level*/ + d[14] != null && Na(d) + ); + return { + c() { + s && s.c(), e = Et(), a && a.c(), t = Et(), n && n.c(), r = Et(), h && h.c(), i = Ir(); + }, + m(l, c) { + s && s.m(l, c), ne(l, e, c), a && a.m(l, c), ne(l, t, c), n && n.m(l, c), ne(l, r, c), h && h.m(l, c), ne(l, i, c); + }, + p(l, c) { + /*p*/ + l[41].desc != null ? a ? a.p(l, c) : (a = Ca(l), a.c(), a.m(t.parentNode, t)) : a && (a.d(1), a = null), /*p*/ + l[41].desc != null && /*progress_level*/ + l[14] && /*progress_level*/ + l[14][ + /*i*/ + l[43] + ] != null ? n || (n = Aa(), n.c(), n.m(r.parentNode, r)) : n && (n.d(1), n = null), /*progress_level*/ + l[14] != null ? h ? h.p(l, c) : (h = Na(l), h.c(), h.m(i.parentNode, i)) : h && (h.d(1), h = null); + }, + d(l) { + l && (ie(e), ie(t), ie(r), ie(i)), s && s.d(l), a && a.d(l), n && n.d(l), h && h.d(l); + } + }; +} +function Uc(d) { + let e; + return { + c() { + e = Re(" /"); + }, + m(t, r) { + ne(t, e, r); + }, + d(t) { + t && ie(e); + } + }; +} +function Ca(d) { + let e = ( + /*p*/ + d[41].desc + "" + ), t; + return { + c() { + t = Re(e); + }, + m(r, i) { + ne(r, t, i); + }, + p(r, i) { + i[0] & /*progress*/ + 128 && e !== (e = /*p*/ + r[41].desc + "") && bt(t, e); + }, + d(r) { + r && ie(t); + } + }; +} +function Aa(d) { + let e; + return { + c() { + e = Re("-"); + }, + m(t, r) { + ne(t, e, r); + }, + d(t) { + t && ie(e); + } + }; +} +function Na(d) { + let e = (100 * /*progress_level*/ + (d[14][ + /*i*/ + d[43] + ] || 0)).toFixed(1) + "", t, r; + return { + c() { + t = Re(e), r = Re("%"); + }, + m(i, s) { + ne(i, t, s), ne(i, r, s); + }, + p(i, s) { + s[0] & /*progress_level*/ + 16384 && e !== (e = (100 * /*progress_level*/ + (i[14][ + /*i*/ + i[43] + ] || 0)).toFixed(1) + "") && bt(t, e); + }, + d(i) { + i && (ie(t), ie(r)); + } + }; +} +function ka(d) { + let e, t = ( + /*p*/ + (d[41].desc != null || /*progress_level*/ + d[14] && /*progress_level*/ + d[14][ + /*i*/ + d[43] + ] != null) && Sa(d) + ); + return { + c() { + t && t.c(), e = Ir(); + }, + m(r, i) { + t && t.m(r, i), ne(r, e, i); + }, + p(r, i) { + /*p*/ + r[41].desc != null || /*progress_level*/ + r[14] && /*progress_level*/ + r[14][ + /*i*/ + r[43] + ] != null ? t ? t.p(r, i) : (t = Sa(r), t.c(), t.m(e.parentNode, e)) : t && (t.d(1), t = null); + }, + d(r) { + r && ie(e), t && t.d(r); + } + }; +} +function Ra(d) { + let e, t; + return { + c() { + e = $t("p"), t = Re( + /*loading_text*/ + d[9] + ), Tt(e, "class", "loading svelte-1yk38uw"); + }, + m(r, i) { + ne(r, e, i), gr(e, t); + }, + p(r, i) { + i[0] & /*loading_text*/ + 512 && bt( + t, + /*loading_text*/ + r[9] + ); + }, + d(r) { + r && ie(e); + } + }; +} +function Zc(d) { + let e, t, r, i, s; + const a = [zc, Fc], n = []; + function h(l, c) { + return ( + /*status*/ + l[4] === "pending" ? 0 : ( + /*status*/ + l[4] === "error" ? 1 : -1 + ) + ); + } + return ~(t = h(d)) && (r = n[t] = a[t](d)), { + c() { + e = $t("div"), r && r.c(), Tt(e, "class", i = "wrap " + /*variant*/ + d[8] + " " + /*show_progress*/ + d[6] + " svelte-1yk38uw"), mt(e, "hide", !/*status*/ + d[4] || /*status*/ + d[4] === "complete" || /*show_progress*/ + d[6] === "hidden"), mt( + e, + "translucent", + /*variant*/ + d[8] === "center" && /*status*/ + (d[4] === "pending" || /*status*/ + d[4] === "error") || /*translucent*/ + d[11] || /*show_progress*/ + d[6] === "minimal" + ), mt( + e, + "generating", + /*status*/ + d[4] === "generating" + ), mt( + e, + "border", + /*border*/ + d[12] + ), sr( + e, + "position", + /*absolute*/ + d[10] ? "absolute" : "static" + ), sr( + e, + "padding", + /*absolute*/ + d[10] ? "0" : "var(--size-8) 0" + ); + }, + m(l, c) { + ne(l, e, c), ~t && n[t].m(e, null), d[33](e), s = !0; + }, + p(l, c) { + let u = t; + t = h(l), t === u ? ~t && n[t].p(l, c) : (r && (fl(), pr(n[u], 1, 1, () => { + n[u] = null; + }), al()), ~t ? (r = n[t], r ? r.p(l, c) : (r = n[t] = a[t](l), r.c()), dr(r, 1), r.m(e, null)) : r = null), (!s || c[0] & /*variant, show_progress*/ + 320 && i !== (i = "wrap " + /*variant*/ + l[8] + " " + /*show_progress*/ + l[6] + " svelte-1yk38uw")) && Tt(e, "class", i), (!s || c[0] & /*variant, show_progress, status, show_progress*/ + 336) && mt(e, "hide", !/*status*/ + l[4] || /*status*/ + l[4] === "complete" || /*show_progress*/ + l[6] === "hidden"), (!s || c[0] & /*variant, show_progress, variant, status, translucent, show_progress*/ + 2384) && mt( + e, + "translucent", + /*variant*/ + l[8] === "center" && /*status*/ + (l[4] === "pending" || /*status*/ + l[4] === "error") || /*translucent*/ + l[11] || /*show_progress*/ + l[6] === "minimal" + ), (!s || c[0] & /*variant, show_progress, status*/ + 336) && mt( + e, + "generating", + /*status*/ + l[4] === "generating" + ), (!s || c[0] & /*variant, show_progress, border*/ + 4416) && mt( + e, + "border", + /*border*/ + l[12] + ), c[0] & /*absolute*/ + 1024 && sr( + e, + "position", + /*absolute*/ + l[10] ? "absolute" : "static" + ), c[0] & /*absolute*/ + 1024 && sr( + e, + "padding", + /*absolute*/ + l[10] ? "0" : "var(--size-8) 0" + ); + }, + i(l) { + s || (dr(r), s = !0); + }, + o(l) { + pr(r), s = !1; + }, + d(l) { + l && ie(e), ~t && n[t].d(), d[33](null); + } + }; +} +var Kc = function(d, e, t, r) { + function i(s) { + return s instanceof t ? s : new t(function(a) { + a(s); + }); + } + return new (t || (t = Promise))(function(s, a) { + function n(c) { + try { + l(r.next(c)); + } catch (u) { + a(u); + } + } + function h(c) { + try { + l(r.throw(c)); + } catch (u) { + a(u); + } + } + function l(c) { + c.done ? s(c.value) : i(c.value).then(n, h); + } + l((r = r.apply(d, e || [])).next()); + }); +}; +let Si = [], Tn = !1; +function jc(d) { + return Kc(this, arguments, void 0, function* (e, t = !0) { + if (!(window.__gradio_mode__ === "website" || window.__gradio_mode__ !== "app" && t !== !0)) { + if (Si.push(e), !Tn) + Tn = !0; + else + return; + yield Pc(), requestAnimationFrame(() => { + let r = [0, 0]; + for (let i = 0; i < Si.length; i++) { + const a = Si[i].getBoundingClientRect(); + (i === 0 || a.top + window.scrollY <= r[0]) && (r[0] = a.top + window.scrollY, r[1] = i); + } + window.scrollTo({ top: r[0] - 20, behavior: "smooth" }), Tn = !1, Si = []; + }); + } + }); +} +function Jc(d, e, t) { + let r, { $$slots: i = {}, $$scope: s } = e; + this && this.__awaiter; + const a = Ic(); + let { i18n: n } = e, { eta: h = null } = e, { queue_position: l } = e, { queue_size: c } = e, { status: u } = e, { scroll_to_output: g = !1 } = e, { timer: m = !0 } = e, { show_progress: _ = "full" } = e, { message: v = null } = e, { progress: N = null } = e, { variant: B = "default" } = e, { loading_text: x = "Loading..." } = e, { absolute: L = !0 } = e, { translucent: k = !1 } = e, { border: z = !1 } = e, { autoscroll: D } = e, Y, O = !1, Z = 0, j = 0, q = null, se = null, ye = 0, ke = null, xe, we = null, Ee = !0; + const Qe = () => { + t(0, h = t(27, q = t(19, Be = null))), t(25, Z = performance.now()), t(26, j = 0), O = !0, Ce(); + }; + function Ce() { + requestAnimationFrame(() => { + t(26, j = (performance.now() - Z) / 1e3), O && Ce(); + }); + } + function Ae() { + t(26, j = 0), t(0, h = t(27, q = t(19, Be = null))), O && (O = !1); + } + $c(() => { + O && Ae(); + }); + let Be = null; + function st(K) { + ga[K ? "unshift" : "push"](() => { + we = K, t(16, we), t(7, N), t(14, ke), t(15, xe); + }); + } + const It = () => { + a("clear_status"); + }; + function wt(K) { + ga[K ? "unshift" : "push"](() => { + Y = K, t(13, Y); + }); + } + return d.$$set = (K) => { + "i18n" in K && t(1, n = K.i18n), "eta" in K && t(0, h = K.eta), "queue_position" in K && t(2, l = K.queue_position), "queue_size" in K && t(3, c = K.queue_size), "status" in K && t(4, u = K.status), "scroll_to_output" in K && t(22, g = K.scroll_to_output), "timer" in K && t(5, m = K.timer), "show_progress" in K && t(6, _ = K.show_progress), "message" in K && t(23, v = K.message), "progress" in K && t(7, N = K.progress), "variant" in K && t(8, B = K.variant), "loading_text" in K && t(9, x = K.loading_text), "absolute" in K && t(10, L = K.absolute), "translucent" in K && t(11, k = K.translucent), "border" in K && t(12, z = K.border), "autoscroll" in K && t(24, D = K.autoscroll), "$$scope" in K && t(29, s = K.$$scope); + }, d.$$.update = () => { + d.$$.dirty[0] & /*eta, old_eta, timer_start, eta_from_start*/ + 436207617 && (h === null && t(0, h = q), h != null && q !== h && (t(28, se = (performance.now() - Z) / 1e3 + h), t(19, Be = se.toFixed(1)), t(27, q = h))), d.$$.dirty[0] & /*eta_from_start, timer_diff*/ + 335544320 && t(17, ye = se === null || se <= 0 || !j ? null : Math.min(j / se, 1)), d.$$.dirty[0] & /*progress*/ + 128 && N != null && t(18, Ee = !1), d.$$.dirty[0] & /*progress, progress_level, progress_bar, last_progress_level*/ + 114816 && (N != null ? t(14, ke = N.map((K) => { + if (K.index != null && K.length != null) + return K.index / K.length; + if (K.progress != null) + return K.progress; + })) : t(14, ke = null), ke ? (t(15, xe = ke[ke.length - 1]), we && (xe === 0 ? t(16, we.style.transition = "0", we) : t(16, we.style.transition = "150ms", we))) : t(15, xe = void 0)), d.$$.dirty[0] & /*status*/ + 16 && (u === "pending" ? Qe() : Ae()), d.$$.dirty[0] & /*el, scroll_to_output, status, autoscroll*/ + 20979728 && Y && g && (u === "pending" || u === "complete") && jc(Y, D), d.$$.dirty[0] & /*status, message*/ + 8388624, d.$$.dirty[0] & /*timer_diff*/ + 67108864 && t(20, r = j.toFixed(1)); + }, [ + h, + n, + l, + c, + u, + m, + _, + N, + B, + x, + L, + k, + z, + Y, + ke, + xe, + we, + ye, + Ee, + Be, + r, + a, + g, + v, + D, + Z, + j, + q, + se, + s, + i, + st, + It, + wt + ]; +} +class Qc extends xc { + constructor(e) { + super(), Mc( + this, + e, + Jc, + Zc, + Bc, + { + i18n: 1, + eta: 0, + queue_position: 2, + queue_size: 3, + status: 4, + scroll_to_output: 22, + timer: 5, + show_progress: 6, + message: 23, + progress: 7, + variant: 8, + loading_text: 9, + absolute: 10, + translucent: 11, + border: 12, + autoscroll: 24 + }, + null, + [-1, -1] + ); + } +} +var eg = typeof globalThis < "u" ? globalThis : typeof window < "u" ? window : typeof global < "u" ? global : typeof self < "u" ? self : {}; +function tg(d) { + return d && d.__esModule && Object.prototype.hasOwnProperty.call(d, "default") ? d.default : d; +} +let rg = class Wn { + /** + * Clone an array or an object. If an object is passed, a shallow clone will be created. + * + * @static + * @param {*} arr The array or object to be cloned. + * @returns {*} A clone of the array or object. + */ + static clone(e) { + let t = Array.isArray(e) ? Array() : {}; + for (let r in e) { + let i = e[r]; + typeof i.clone == "function" ? t[r] = i.clone() : t[r] = typeof i == "object" ? Wn.clone(i) : i; + } + return t; + } + /** + * Returns a boolean indicating whether or not the two arrays contain the same elements. + * Only supports 1d, non-nested arrays. + * + * @static + * @param {Array} arrA An array. + * @param {Array} arrB An array. + * @returns {Boolean} A boolean indicating whether or not the two arrays contain the same elements. + */ + static equals(e, t) { + if (e.length !== t.length) + return !1; + let r = e.slice().sort(), i = t.slice().sort(); + for (var s = 0; s < r.length; s++) + if (r[s] !== i[s]) + return !1; + return !0; + } + /** + * Returns a string representation of an array. If the array contains objects with an id property, the id property is printed for each of the elements. + * + * @static + * @param {Object[]} arr An array. + * @param {*} arr[].id If the array contains an object with the property 'id', the properties value is printed. Else, the array elements value is printend. + * @returns {String} A string representation of the array. + */ + static print(e) { + if (e.length == 0) + return ""; + let t = "("; + for (let r = 0; r < e.length; r++) + t += e[r].id ? e[r].id + ", " : e[r] + ", "; + return t = t.substring(0, t.length - 2), t + ")"; + } + /** + * Run a function for each element in the array. The element is supplied as an argument for the callback function + * + * @static + * @param {Array} arr An array. + * @param {Function} callback The callback function that is called for each element. + */ + static each(e, t) { + for (let r = 0; r < e.length; r++) + t(e[r]); + } + /** + * Return the array element from an array containing objects, where a property of the object is set to a given value. + * + * @static + * @param {Array} arr An array. + * @param {(String|Number)} property A property contained within an object in the array. + * @param {(String|Number)} value The value of the property. + * @returns {*} The array element matching the value. + */ + static get(e, t, r) { + for (let i = 0; i < e.length; i++) + if (e[i][t] == r) + return e[i]; + } + /** + * Checks whether or not an array contains a given value. the options object passed as a second argument can contain three properties. value: The value to be searched for. property: The property that is to be searched for a given value. func: A function that is used as a callback to return either true or false in order to do a custom comparison. + * + * @static + * @param {Array} arr An array. + * @param {Object} options See method description. + * @param {*} options.value The value for which to check. + * @param {String} [options.property=undefined] The property on which to check. + * @param {Function} [options.func=undefined] A custom property function. + * @returns {Boolean} A boolean whether or not the array contains a value. + */ + static contains(e, t) { + if (!t.property && !t.func) { + for (let r = 0; r < e.length; r++) + if (e[r] == t.value) + return !0; + } else if (t.func) { + for (let r = 0; r < e.length; r++) + if (t.func(e[r])) + return !0; + } else + for (let r = 0; r < e.length; r++) + if (e[r][t.property] == t.value) + return !0; + return !1; + } + /** + * Returns an array containing the intersection between two arrays. That is, values that are common to both arrays. + * + * @static + * @param {Array} arrA An array. + * @param {Array} arrB An array. + * @returns {Array} The intersecting vlaues. + */ + static intersection(e, t) { + let r = new Array(); + for (let i = 0; i < e.length; i++) + for (let s = 0; s < t.length; s++) + e[i] === t[s] && r.push(e[i]); + return r; + } + /** + * Returns an array of unique elements contained in an array. + * + * @static + * @param {Array} arr An array. + * @returns {Array} An array of unique elements contained within the array supplied as an argument. + */ + static unique(e) { + let t = {}; + return e.filter(function(r) { + return t[r] !== void 0 ? !1 : t[r] = !0; + }); + } + /** + * Count the number of occurences of a value in an array. + * + * @static + * @param {Array} arr An array. + * @param {*} value A value to be counted. + * @returns {Number} The number of occurences of a value in the array. + */ + static count(e, t) { + let r = 0; + for (let i = 0; i < e.length; i++) + e[i] === t && r++; + return r; + } + /** + * Toggles the value of an array. If a value is not contained in an array, the array returned will contain all the values of the original array including the value. If a value is contained in an array, the array returned will contain all the values of the original array excluding the value. + * + * @static + * @param {Array} arr An array. + * @param {*} value A value to be toggled. + * @returns {Array} The toggled array. + */ + static toggle(e, t) { + let r = Array(), i = !1; + for (let s = 0; s < e.length; s++) + e[s] !== t ? r.push(e[s]) : i = !0; + return i || r.push(t), r; + } + /** + * Remove a value from an array. + * + * @static + * @param {Array} arr An array. + * @param {*} value A value to be removed. + * @returns {Array} A new array with the element with a given value removed. + */ + static remove(e, t) { + let r = Array(); + for (let i = 0; i < e.length; i++) + e[i] !== t && r.push(e[i]); + return r; + } + /** + * Remove a value from an array with unique values. + * + * @static + * @param {Array} arr An array. + * @param {*} value A value to be removed. + * @returns {Array} An array with the element with a given value removed. + */ + static removeUnique(e, t) { + let r = e.indexOf(t); + return r > -1 && e.splice(r, 1), e; + } + /** + * Remove all elements contained in one array from another array. + * + * @static + * @param {Array} arrA The array to be filtered. + * @param {Array} arrB The array containing elements that will be removed from the other array. + * @returns {Array} The filtered array. + */ + static removeAll(e, t) { + return e.filter(function(r) { + return t.indexOf(r) === -1; + }); + } + /** + * Merges two arrays and returns the result. The first array will be appended to the second array. + * + * @static + * @param {Array} arrA An array. + * @param {Array} arrB An array. + * @returns {Array} The merged array. + */ + static merge(e, t) { + let r = new Array(e.length + t.length); + for (let i = 0; i < e.length; i++) + r[i] = e[i]; + for (let i = 0; i < t.length; i++) + r[e.length + i] = t[i]; + return r; + } + /** + * Checks whether or not an array contains all the elements of another array, without regard to the order. + * + * @static + * @param {Array} arrA An array. + * @param {Array} arrB An array. + * @returns {Boolean} A boolean indicating whether or not both array contain the same elements. + */ + static containsAll(e, t) { + let r = 0; + for (let i = 0; i < e.length; i++) + for (let s = 0; s < t.length; s++) + e[i] === t[s] && r++; + return r === t.length; + } + /** + * Sort an array of atomic number information. Where the number is indicated as x, x.y, x.y.z, ... + * + * @param {Object[]} arr An array of vertex ids with their associated atomic numbers. + * @param {Number} arr[].vertexId A vertex id. + * @param {String} arr[].atomicNumber The atomic number associated with the vertex id. + * @returns {Object[]} The array sorted by atomic number. Example of an array entry: { atomicNumber: 2, vertexId: 5 }. + */ + static sortByAtomicNumberDesc(e) { + let t = e.map(function(r, i) { + return { index: i, value: r.atomicNumber.split(".").map(Number) }; + }); + return t.sort(function(r, i) { + let s = Math.min(i.value.length, r.value.length), a = 0; + for (; a < s && i.value[a] === r.value[a]; ) + a++; + return a === s ? i.value.length - r.value.length : i.value[a] - r.value[a]; + }), t.map(function(r) { + return e[r.index]; + }); + } + /** + * Copies a an n-dimensional array. + * + * @param {Array} arr The array to be copied. + * @returns {Array} The copy. + */ + static deepCopy(e) { + let t = Array(); + for (let r = 0; r < e.length; r++) { + let i = e[r]; + i instanceof Array ? t[r] = Wn.deepCopy(i) : t[r] = i; + } + return t; + } +}; +var Zr = rg; +let ig = class cr { + /** + * Rounds a value to a given number of decimals. + * + * @static + * @param {Number} value A number. + * @param {Number} decimals The number of decimals. + * @returns {Number} A number rounded to a given number of decimals. + */ + static round(e, t) { + return t = t || 1, +(Math.round(e + "e" + t) + "e-" + t); + } + /** + * Returns the means of the angles contained in an array. In radians. + * + * @static + * @param {Number[]} arr An array containing angles (in radians). + * @returns {Number} The mean angle in radians. + */ + static meanAngle(e) { + let t = 0, r = 0; + for (var i = 0; i < e.length; i++) + t += Math.sin(e[i]), r += Math.cos(e[i]); + return Math.atan2(t / e.length, r / e.length); + } + /** + * Returns the inner angle of a n-sided regular polygon. + * + * @static + * @param {Number} n Number of sides of a regular polygon. + * @returns {Number} The inner angle of a given regular polygon. + */ + static innerAngle(e) { + return cr.toRad((e - 2) * 180 / e); + } + /** + * Returns the circumradius of a n-sided regular polygon with a given side-length. + * + * @static + * @param {Number} s The side length of the regular polygon. + * @param {Number} n The number of sides. + * @returns {Number} The circumradius of the regular polygon. + */ + static polyCircumradius(e, t) { + return e / (2 * Math.sin(Math.PI / t)); + } + /** + * Returns the apothem of a regular n-sided polygon based on its radius. + * + * @static + * @param {Number} r The radius. + * @param {Number} n The number of edges of the regular polygon. + * @returns {Number} The apothem of a n-sided polygon based on its radius. + */ + static apothem(e, t) { + return e * Math.cos(Math.PI / t); + } + static apothemFromSideLength(e, t) { + let r = cr.polyCircumradius(e, t); + return cr.apothem(r, t); + } + /** + * The central angle of a n-sided regular polygon. In radians. + * + * @static + * @param {Number} n The number of sides of the regular polygon. + * @returns {Number} The central angle of the n-sided polygon in radians. + */ + static centralAngle(e) { + return cr.toRad(360 / e); + } + /** + * Convertes radians to degrees. + * + * @static + * @param {Number} rad An angle in radians. + * @returns {Number} The angle in degrees. + */ + static toDeg(e) { + return e * cr.degFactor; + } + /** + * Converts degrees to radians. + * + * @static + * @param {Number} deg An angle in degrees. + * @returns {Number} The angle in radians. + */ + static toRad(e) { + return e * cr.radFactor; + } + /** + * Returns the parity of the permutation (1 or -1) + * @param {(Array|Uint8Array)} arr An array containing the permutation. + * @returns {Number} The parity of the permutation (1 or -1), where 1 means even and -1 means odd. + */ + static parityOfPermutation(e) { + let t = new Uint8Array(e.length), r = 0, i = function(a, n = 0) { + return t[a] === 1 ? n : (n++, t[a] = 1, i(e[a], n)); + }; + for (var s = 0; s < e.length; s++) { + if (t[s] === 1) + continue; + let a = i(s); + r += 1 - a % 2; + } + return r % 2 ? -1 : 1; + } + /** The factor to convert degrees to radians. */ + static get radFactor() { + return Math.PI / 180; + } + /** The factor to convert radians to degrees. */ + static get degFactor() { + return 180 / Math.PI; + } + /** Two times PI. */ + static get twoPI() { + return 2 * Math.PI; + } +}; +var Kr = ig; +let ng = class be { + /** + * The constructor of the class Vector2. + * + * @param {(Number|Vector2)} x The initial x coordinate value or, if the single argument, a Vector2 object. + * @param {Number} y The initial y coordinate value. + */ + constructor(e, t) { + arguments.length == 0 ? (this.x = 0, this.y = 0) : arguments.length == 1 ? (this.x = e.x, this.y = e.y) : (this.x = e, this.y = t); + } + /** + * Clones this vector and returns the clone. + * + * @returns {Vector2} The clone of this vector. + */ + clone() { + return new be(this.x, this.y); + } + /** + * Returns a string representation of this vector. + * + * @returns {String} A string representation of this vector. + */ + toString() { + return "(" + this.x + "," + this.y + ")"; + } + /** + * Add the x and y coordinate values of a vector to the x and y coordinate values of this vector. + * + * @param {Vector2} vec Another vector. + * @returns {Vector2} Returns itself. + */ + add(e) { + return this.x += e.x, this.y += e.y, this; + } + /** + * Subtract the x and y coordinate values of a vector from the x and y coordinate values of this vector. + * + * @param {Vector2} vec Another vector. + * @returns {Vector2} Returns itself. + */ + subtract(e) { + return this.x -= e.x, this.y -= e.y, this; + } + /** + * Divide the x and y coordinate values of this vector by a scalar. + * + * @param {Number} scalar The scalar. + * @returns {Vector2} Returns itself. + */ + divide(e) { + return this.x /= e, this.y /= e, this; + } + /** + * Multiply the x and y coordinate values of this vector by the values of another vector. + * + * @param {Vector2} v A vector. + * @returns {Vector2} Returns itself. + */ + multiply(e) { + return this.x *= e.x, this.y *= e.y, this; + } + /** + * Multiply the x and y coordinate values of this vector by a scalar. + * + * @param {Number} scalar The scalar. + * @returns {Vector2} Returns itself. + */ + multiplyScalar(e) { + return this.x *= e, this.y *= e, this; + } + /** + * Inverts this vector. Same as multiply(-1.0). + * + * @returns {Vector2} Returns itself. + */ + invert() { + return this.x = -this.x, this.y = -this.y, this; + } + /** + * Returns the angle of this vector in relation to the coordinate system. + * + * @returns {Number} The angle in radians. + */ + angle() { + return Math.atan2(this.y, this.x); + } + /** + * Returns the euclidean distance between this vector and another vector. + * + * @param {Vector2} vec A vector. + * @returns {Number} The euclidean distance between the two vectors. + */ + distance(e) { + return Math.sqrt((e.x - this.x) * (e.x - this.x) + (e.y - this.y) * (e.y - this.y)); + } + /** + * Returns the squared euclidean distance between this vector and another vector. When only the relative distances of a set of vectors are needed, this is is less expensive than using distance(vec). + * + * @param {Vector2} vec Another vector. + * @returns {Number} The squared euclidean distance of the two vectors. + */ + distanceSq(e) { + return (e.x - this.x) * (e.x - this.x) + (e.y - this.y) * (e.y - this.y); + } + /** + * Checks whether or not this vector is in a clockwise or counter-clockwise rotational direction compared to another vector in relation to the coordinate system. + * + * @param {Vector2} vec Another vector. + * @returns {Number} Returns -1, 0 or 1 if the vector supplied as an argument is clockwise, neutral or counter-clockwise respectively to this vector in relation to the coordinate system. + */ + clockwise(e) { + let t = this.y * e.x, r = this.x * e.y; + return t > r ? -1 : t === r ? 0 : 1; + } + /** + * Checks whether or not this vector is in a clockwise or counter-clockwise rotational direction compared to another vector in relation to an arbitrary third vector. + * + * @param {Vector2} center The central vector. + * @param {Vector2} vec Another vector. + * @returns {Number} Returns -1, 0 or 1 if the vector supplied as an argument is clockwise, neutral or counter-clockwise respectively to this vector in relation to an arbitrary third vector. + */ + relativeClockwise(e, t) { + let r = (this.y - e.y) * (t.x - e.x), i = (this.x - e.x) * (t.y - e.y); + return r > i ? -1 : r === i ? 0 : 1; + } + /** + * Rotates this vector by a given number of radians around the origin of the coordinate system. + * + * @param {Number} angle The angle in radians to rotate the vector. + * @returns {Vector2} Returns itself. + */ + rotate(e) { + let t = new be(0, 0), r = Math.cos(e), i = Math.sin(e); + return t.x = this.x * r - this.y * i, t.y = this.x * i + this.y * r, this.x = t.x, this.y = t.y, this; + } + /** + * Rotates this vector around another vector. + * + * @param {Number} angle The angle in radians to rotate the vector. + * @param {Vector2} vec The vector which is used as the rotational center. + * @returns {Vector2} Returns itself. + */ + rotateAround(e, t) { + let r = Math.sin(e), i = Math.cos(e); + this.x -= t.x, this.y -= t.y; + let s = this.x * i - this.y * r, a = this.x * r + this.y * i; + return this.x = s + t.x, this.y = a + t.y, this; + } + /** + * Rotate a vector around a given center to the same angle as another vector (so that the two vectors and the center are in a line, with both vectors on one side of the center), keeps the distance from this vector to the center. + * + * @param {Vector2} vec The vector to rotate this vector to. + * @param {Vector2} center The rotational center. + * @param {Number} [offsetAngle=0.0] An additional amount of radians to rotate the vector. + * @returns {Vector2} Returns itself. + */ + rotateTo(e, t, r = 0) { + this.x += 1e-3, this.y -= 1e-3; + let i = be.subtract(this, t), s = be.subtract(e, t), a = be.angle(s, i); + return this.rotateAround(a + r, t), this; + } + /** + * Rotates the vector away from a specified vector around a center. + * + * @param {Vector2} vec The vector this one is rotated away from. + * @param {Vector2} center The rotational center. + * @param {Number} angle The angle by which to rotate. + */ + rotateAwayFrom(e, t, r) { + this.rotateAround(r, t); + let i = this.distanceSq(e); + this.rotateAround(-2 * r, t), this.distanceSq(e) < i && this.rotateAround(2 * r, t); + } + /** + * Returns the angle in radians used to rotate this vector away from a given vector. + * + * @param {Vector2} vec The vector this one is rotated away from. + * @param {Vector2} center The rotational center. + * @param {Number} angle The angle by which to rotate. + * @returns {Number} The angle in radians. + */ + getRotateAwayFromAngle(e, t, r) { + let i = this.clone(); + i.rotateAround(r, t); + let s = i.distanceSq(e); + return i.rotateAround(-2 * r, t), i.distanceSq(e) < s ? r : -r; + } + /** + * Returns the angle in radians used to rotate this vector towards a given vector. + * + * @param {Vector2} vec The vector this one is rotated towards to. + * @param {Vector2} center The rotational center. + * @param {Number} angle The angle by which to rotate. + * @returns {Number} The angle in radians. + */ + getRotateTowardsAngle(e, t, r) { + let i = this.clone(); + i.rotateAround(r, t); + let s = i.distanceSq(e); + return i.rotateAround(-2 * r, t), i.distanceSq(e) > s ? r : -r; + } + /** + * Gets the angles between this vector and another vector around a common center of rotation. + * + * @param {Vector2} vec Another vector. + * @param {Vector2} center The center of rotation. + * @returns {Number} The angle between this vector and another vector around a center of rotation in radians. + */ + getRotateToAngle(e, t) { + let r = be.subtract(this, t), i = be.subtract(e, t), s = be.angle(i, r); + return Number.isNaN(s) ? 0 : s; + } + /** + * Checks whether a vector lies within a polygon spanned by a set of vectors. + * + * @param {Vector2[]} polygon An array of vectors spanning the polygon. + * @returns {Boolean} A boolean indicating whether or not this vector is within a polygon. + */ + isInPolygon(e) { + let t = !1; + for (let r = 0, i = e.length - 1; r < e.length; i = r++) + e[r].y > this.y != e[i].y > this.y && this.x < (e[i].x - e[r].x) * (this.y - e[r].y) / (e[i].y - e[r].y) + e[r].x && (t = !t); + return t; + } + /** + * Returns the length of this vector. + * + * @returns {Number} The length of this vector. + */ + length() { + return Math.sqrt(this.x * this.x + this.y * this.y); + } + /** + * Returns the square of the length of this vector. + * + * @returns {Number} The square of the length of this vector. + */ + lengthSq() { + return this.x * this.x + this.y * this.y; + } + /** + * Normalizes this vector. + * + * @returns {Vector2} Returns itself. + */ + normalize() { + return this.divide(this.length()), this; + } + /** + * Returns a normalized copy of this vector. + * + * @returns {Vector2} A normalized copy of this vector. + */ + normalized() { + return be.divideScalar(this, this.length()); + } + /** + * Calculates which side of a line spanned by two vectors this vector is. + * + * @param {Vector2} vecA A vector. + * @param {Vector2} vecB A vector. + * @returns {Number} A number indicating the side of this vector, given a line spanned by two other vectors. + */ + whichSide(e, t) { + return (this.x - e.x) * (t.y - e.y) - (this.y - e.y) * (t.x - e.x); + } + /** + * Checks whether or not this vector is on the same side of a line spanned by two vectors as another vector. + * + * @param {Vector2} vecA A vector spanning the line. + * @param {Vector2} vecB A vector spanning the line. + * @param {Vector2} vecC A vector to check whether or not it is on the same side as this vector. + * @returns {Boolean} Returns a boolean indicating whether or not this vector is on the same side as another vector. + */ + sameSideAs(e, t, r) { + let i = this.whichSide(e, t), s = r.whichSide(e, t); + return i < 0 && s < 0 || i == 0 && s == 0 || i > 0 && s > 0; + } + /** + * Adds two vectors and returns the result as a new vector. + * + * @static + * @param {Vector2} vecA A summand. + * @param {Vector2} vecB A summand. + * @returns {Vector2} Returns the sum of two vectors. + */ + static add(e, t) { + return new be(e.x + t.x, e.y + t.y); + } + /** + * Subtracts one vector from another and returns the result as a new vector. + * + * @static + * @param {Vector2} vecA The minuend. + * @param {Vector2} vecB The subtrahend. + * @returns {Vector2} Returns the difference of two vectors. + */ + static subtract(e, t) { + return new be(e.x - t.x, e.y - t.y); + } + /** + * Multiplies two vectors (value by value) and returns the result. + * + * @static + * @param {Vector2} vecA A vector. + * @param {Vector2} vecB A vector. + * @returns {Vector2} Returns the product of two vectors. + */ + static multiply(e, t) { + return new be(e.x * t.x, e.y * t.y); + } + /** + * Multiplies two vectors (value by value) and returns the result. + * + * @static + * @param {Vector2} vec A vector. + * @param {Number} scalar A scalar. + * @returns {Vector2} Returns the product of two vectors. + */ + static multiplyScalar(e, t) { + return new be(e.x, e.y).multiplyScalar(t); + } + /** + * Returns the midpoint of a line spanned by two vectors. + * + * @static + * @param {Vector2} vecA A vector spanning the line. + * @param {Vector2} vecB A vector spanning the line. + * @returns {Vector2} The midpoint of the line spanned by two vectors. + */ + static midpoint(e, t) { + return new be((e.x + t.x) / 2, (e.y + t.y) / 2); + } + /** + * Returns the normals of a line spanned by two vectors. + * + * @static + * @param {Vector2} vecA A vector spanning the line. + * @param {Vector2} vecB A vector spanning the line. + * @returns {Vector2[]} An array containing the two normals, each represented by a vector. + */ + static normals(e, t) { + let r = be.subtract(t, e); + return [ + new be(-r.y, r.x), + new be(r.y, -r.x) + ]; + } + /** + * Returns the unit (normalized normal) vectors of a line spanned by two vectors. + * + * @static + * @param {Vector2} vecA A vector spanning the line. + * @param {Vector2} vecB A vector spanning the line. + * @returns {Vector2[]} An array containing the two unit vectors. + */ + static units(e, t) { + let r = be.subtract(t, e); + return [ + new be(-r.y, r.x).normalize(), + new be(r.y, -r.x).normalize() + ]; + } + /** + * Divides a vector by another vector and returns the result as new vector. + * + * @static + * @param {Vector2} vecA The dividend. + * @param {Vector2} vecB The divisor. + * @returns {Vector2} The fraction of the two vectors. + */ + static divide(e, t) { + return new be(e.x / t.x, e.y / t.y); + } + /** + * Divides a vector by a scalar and returns the result as new vector. + * + * @static + * @param {Vector2} vecA The dividend. + * @param {Number} s The scalar. + * @returns {Vector2} The fraction of the two vectors. + */ + static divideScalar(e, t) { + return new be(e.x / t, e.y / t); + } + /** + * Returns the dot product of two vectors. + * + * @static + * @param {Vector2} vecA A vector. + * @param {Vector2} vecB A vector. + * @returns {Number} The dot product of two vectors. + */ + static dot(e, t) { + return e.x * t.x + e.y * t.y; + } + /** + * Returns the angle between two vectors. + * + * @static + * @param {Vector2} vecA A vector. + * @param {Vector2} vecB A vector. + * @returns {Number} The angle between two vectors in radians. + */ + static angle(e, t) { + let r = be.dot(e, t); + return Math.acos(r / (e.length() * t.length())); + } + /** + * Returns the angle between two vectors based on a third vector in between. + * + * @static + * @param {Vector2} vecA A vector. + * @param {Vector2} vecB A (central) vector. + * @param {Vector2} vecC A vector. + * @returns {Number} The angle in radians. + */ + static threePointangle(e, t, r) { + let i = be.subtract(t, e), s = be.subtract(r, t), a = e.distance(t), n = t.distance(r); + return Math.acos(be.dot(i, s) / (a * n)); + } + /** + * Returns the scalar projection of a vector on another vector. + * + * @static + * @param {Vector2} vecA The vector to be projected. + * @param {Vector2} vecB The vector to be projection upon. + * @returns {Number} The scalar component. + */ + static scalarProjection(e, t) { + let r = t.normalized(); + return be.dot(e, r); + } + /** + * Returns the average vector (normalized) of the input vectors. + * + * @static + * @param {Array} vecs An array containing vectors. + * @returns {Vector2} The resulting vector (normalized). + */ + static averageDirection(e) { + let t = new be(0, 0); + for (var r = 0; r < e.length; r++) { + let i = e[r]; + t.add(i); + } + return t.normalize(); + } +}; +var ar = ng, En, xa; +function Or() { + if (xa) + return En; + xa = 1; + const d = Kr, e = Zr, t = ar; + Li(); + class r { + /** + * The constructor for the class Vertex. + * + * @param {Atom} value The value associated with this vertex. + * @param {Number} [x=0] The initial x coordinate of the positional vector of this vertex. + * @param {Number} [y=0] The initial y coordinate of the positional vector of this vertex. + */ + constructor(s, a = 0, n = 0) { + this.id = null, this.value = s, this.position = new t(a || 0, n || 0), this.previousPosition = new t(0, 0), this.parentVertexId = null, this.children = Array(), this.spanningTreeChildren = Array(), this.edges = Array(), this.positioned = !1, this.angle = null, this.dir = 1, this.neighbourCount = 0, this.neighbours = Array(), this.neighbouringElements = Array(), this.forcePositioned = !1; + } + /** + * Set the 2D coordinates of the vertex. + * + * @param {Number} x The x component of the coordinates. + * @param {Number} y The y component of the coordinates. + * + */ + setPosition(s, a) { + this.position.x = s, this.position.y = a; + } + /** + * Set the 2D coordinates of the vertex from a Vector2. + * + * @param {Vector2} v A 2D vector. + * + */ + setPositionFromVector(s) { + this.position.x = s.x, this.position.y = s.y; + } + /** + * Add a child vertex id to this vertex. + * @param {Number} vertexId The id of a vertex to be added as a child to this vertex. + */ + addChild(s) { + this.children.push(s), this.neighbours.push(s), this.neighbourCount++; + } + /** + * Add a child vertex id to this vertex as the second child of the neighbours array, + * except this vertex is the first vertex of the SMILE string, then it is added as the first. + * This is used to get the correct ordering of neighbours for parity calculations. + * If a hydrogen is implicitly attached to the chiral center, insert as the third child. + * @param {Number} vertexId The id of a vertex to be added as a child to this vertex. + * @param {Number} ringbondIndex The index of the ringbond. + */ + addRingbondChild(s, a) { + if (this.children.push(s), this.value.bracket) { + let n = 1; + this.id === 0 && this.value.bracket.hcount === 0 && (n = 0), this.value.bracket.hcount === 1 && a === 0 && (n = 2), this.value.bracket.hcount === 1 && a === 1 && (this.neighbours.length < 3 ? n = 2 : n = 3), this.value.bracket.hcount === null && a === 0 && (n = 1), this.value.bracket.hcount === null && a === 1 && (this.neighbours.length < 3 ? n = 1 : n = 2), this.neighbours.splice(n, 0, s); + } else + this.neighbours.push(s); + this.neighbourCount++; + } + /** + * Set the vertex id of the parent. + * + * @param {Number} parentVertexId The parents vertex id. + */ + setParentVertexId(s) { + this.neighbourCount++, this.parentVertexId = s, this.neighbours.push(s); + } + /** + * Returns true if this vertex is terminal (has no parent or child vertices), otherwise returns false. Always returns true if associated value has property hasAttachedPseudoElements set to true. + * + * @returns {Boolean} A boolean indicating whether or not this vertex is terminal. + */ + isTerminal() { + return this.value.hasAttachedPseudoElements ? !0 : this.parentVertexId === null && this.children.length < 2 || this.children.length === 0; + } + /** + * Clones this vertex and returns the clone. + * + * @returns {Vertex} A clone of this vertex. + */ + clone() { + let s = new r(this.value, this.position.x, this.position.y); + return s.id = this.id, s.previousPosition = new t(this.previousPosition.x, this.previousPosition.y), s.parentVertexId = this.parentVertexId, s.children = e.clone(this.children), s.spanningTreeChildren = e.clone(this.spanningTreeChildren), s.edges = e.clone(this.edges), s.positioned = this.positioned, s.angle = this.angle, s.forcePositioned = this.forcePositioned, s; + } + /** + * Returns true if this vertex and the supplied vertex both have the same id, else returns false. + * + * @param {Vertex} vertex The vertex to check. + * @returns {Boolean} A boolean indicating whether or not the two vertices have the same id. + */ + equals(s) { + return this.id === s.id; + } + /** + * Returns the angle of this vertexes positional vector. If a reference vector is supplied in relations to this vector, else in relations to the coordinate system. + * + * @param {Vector2} [referenceVector=null] - The reference vector. + * @param {Boolean} [returnAsDegrees=false] - If true, returns angle in degrees, else in radians. + * @returns {Number} The angle of this vertex. + */ + getAngle(s = null, a = !1) { + let n = null; + return s ? n = t.subtract(this.position, s) : n = t.subtract(this.position, this.previousPosition), a ? d.toDeg(n.angle()) : n.angle(); + } + /** + * Returns the suggested text direction when text is added at the position of this vertex. + * + * @param {Vertex[]} vertices The array of vertices for the current molecule. + * @param {Boolean} onlyHorizontal In case the text direction should be limited to either left or right. + * @returns {String} The suggested direction of the text. + */ + getTextDirection(s, a = !1) { + let n = this.getDrawnNeighbours(s), h = Array(); + if (s.length === 1) + return "right"; + for (let c = 0; c < n.length; c++) + h.push(this.getAngle(s[n[c]].position)); + let l = d.meanAngle(h); + if (this.isTerminal() || a) + Math.round(l * 100) / 100 === 1.57 && (l = l - 0.2), l = Math.round(Math.round(l / Math.PI) * Math.PI); + else { + let c = Math.PI / 2; + l = Math.round(Math.round(l / c) * c); + } + return l === 2 ? "down" : l === -2 ? "up" : l === 0 || l === -0 ? "right" : l === 3 || l === -3 ? "left" : "down"; + } + /** + * Returns an array of ids of neighbouring vertices. + * + * @param {Number} [vertexId=null] If a value is supplied, the vertex with this id is excluded from the returned indices. + * @returns {Number[]} An array containing the ids of neighbouring vertices. + */ + getNeighbours(s = null) { + if (s === null) + return this.neighbours.slice(); + let a = Array(); + for (let n = 0; n < this.neighbours.length; n++) + this.neighbours[n] !== s && a.push(this.neighbours[n]); + return a; + } + /** + * Returns an array of ids of neighbouring vertices that will be drawn (vertex.value.isDrawn === true). + * + * @param {Vertex[]} vertices An array containing the vertices associated with the current molecule. + * @returns {Number[]} An array containing the ids of neighbouring vertices that will be drawn. + */ + getDrawnNeighbours(s) { + let a = Array(); + for (let n = 0; n < this.neighbours.length; n++) + s[this.neighbours[n]].value.isDrawn && a.push(this.neighbours[n]); + return a; + } + /** + * Returns the number of neighbours of this vertex. + * + * @returns {Number} The number of neighbours. + */ + getNeighbourCount() { + return this.neighbourCount; + } + /** + * Returns a list of ids of vertices neighbouring this one in the original spanning tree, excluding the ringbond connections. + * + * @param {Number} [vertexId=null] If supplied, the vertex with this id is excluded from the array returned. + * @returns {Number[]} An array containing the ids of the neighbouring vertices. + */ + getSpanningTreeNeighbours(s = null) { + let a = Array(); + for (let n = 0; n < this.spanningTreeChildren.length; n++) + (s === void 0 || s != this.spanningTreeChildren[n]) && a.push(this.spanningTreeChildren[n]); + return this.parentVertexId != null && (s === void 0 || s != this.parentVertexId) && a.push(this.parentVertexId), a; + } + /** + * Gets the next vertex in the ring in opposide direction to the supplied vertex id. + * + * @param {Vertex[]} vertices The array of vertices for the current molecule. + * @param {Number} ringId The id of the ring containing this vertex. + * @param {Number} previousVertexId The id of the previous vertex. The next vertex will be opposite from the vertex with this id as seen from this vertex. + * @returns {Number} The id of the next vertex in the ring. + */ + getNextInRing(s, a, n) { + let h = this.getNeighbours(); + for (let l = 0; l < h.length; l++) + if (e.contains(s[h[l]].value.rings, { + value: a + }) && h[l] != n) + return h[l]; + return null; + } + } + return En = r, En; +} +var Ln, Ta; +function cl() { + if (Ta) + return Ln; + Ta = 1, Or(), jr(); + class d { + /** + * The constructor for the class RingConnection. + * + * @param {Ring} firstRing A ring. + * @param {Ring} secondRing A ring. + */ + constructor(t, r) { + this.id = null, this.firstRingId = t.id, this.secondRingId = r.id, this.vertices = /* @__PURE__ */ new Set(); + for (var i = 0; i < t.members.length; i++) { + let s = t.members[i]; + for (let a = 0; a < r.members.length; a++) { + let n = r.members[a]; + s === n && this.addVertex(s); + } + } + } + /** + * Adding a vertex to the ring connection. + * + * @param {Number} vertexId A vertex id. + */ + addVertex(t) { + this.vertices.add(t); + } + /** + * Update the ring id of this ring connection that is not the ring id supplied as the second argument. + * + * @param {Number} ringId A ring id. The new ring id to be set. + * @param {Number} otherRingId A ring id. The id that is NOT to be updated. + */ + updateOther(t, r) { + this.firstRingId === r ? this.secondRingId = t : this.firstRingId = t; + } + /** + * Returns a boolean indicating whether or not a ring with a given id is participating in this ring connection. + * + * @param {Number} ringId A ring id. + * @returns {Boolean} A boolean indicating whether or not a ring with a given id participates in this ring connection. + */ + containsRing(t) { + return this.firstRingId === t || this.secondRingId === t; + } + /** + * Checks whether or not this ring connection is a bridge in a bridged ring. + * + * @param {Vertex[]} vertices The array of vertices associated with the current molecule. + * @returns {Boolean} A boolean indicating whether or not this ring connection is a bridge. + */ + isBridge(t) { + if (this.vertices.size > 2) + return !0; + for (let r of this.vertices) + if (t[r].value.rings.length > 2) + return !0; + return !1; + } + /** + * Checks whether or not two rings are connected by a bridged bond. + * + * @static + * @param {RingConnection[]} ringConnections An array of ring connections containing the ring connections associated with the current molecule. + * @param {Vertex[]} vertices An array of vertices containing the vertices associated with the current molecule. + * @param {Number} firstRingId A ring id. + * @param {Number} secondRingId A ring id. + * @returns {Boolean} A boolean indicating whether or not two rings ar connected by a bridged bond. + */ + static isBridge(t, r, i, s) { + let a = null; + for (let n = 0; n < t.length; n++) + if (a = t[n], a.firstRingId === i && a.secondRingId === s || a.firstRingId === s && a.secondRingId === i) + return a.isBridge(r); + return !1; + } + /** + * Retruns the neighbouring rings of a given ring. + * + * @static + * @param {RingConnection[]} ringConnections An array of ring connections containing ring connections associated with the current molecule. + * @param {Number} ringId A ring id. + * @returns {Number[]} An array of ring ids of neighbouring rings. + */ + static getNeighbours(t, r) { + let i = []; + for (let s = 0; s < t.length; s++) { + let a = t[s]; + a.firstRingId === r ? i.push(a.secondRingId) : a.secondRingId === r && i.push(a.firstRingId); + } + return i; + } + /** + * Returns an array of vertex ids associated with a given ring connection. + * + * @static + * @param {RingConnection[]} ringConnections An array of ring connections containing ring connections associated with the current molecule. + * @param {Number} firstRingId A ring id. + * @param {Number} secondRingId A ring id. + * @returns {Number[]} An array of vertex ids associated with the ring connection. + */ + static getVertices(t, r, i) { + for (let s = 0; s < t.length; s++) { + let a = t[s]; + if (a.firstRingId === r && a.secondRingId === i || a.firstRingId === i && a.secondRingId === r) + return [...a.vertices]; + } + } + } + return Ln = d, Ln; +} +var Mn, Ea; +function jr() { + if (Ea) + return Mn; + Ea = 1; + const d = Zr, e = ar; + Or(); + const t = cl(); + class r { + /** + * The constructor for the class Ring. + * + * @param {Number[]} members An array containing the vertex ids of the members of the ring to be created. + */ + constructor(s) { + this.id = null, this.members = s, this.edges = [], this.insiders = [], this.neighbours = [], this.positioned = !1, this.center = new e(0, 0), this.rings = [], this.isBridged = !1, this.isPartOfBridged = !1, this.isSpiro = !1, this.isFused = !1, this.centralAngle = 0, this.canFlip = !0; + } + /** + * Clones this ring and returns the clone. + * + * @returns {Ring} A clone of this ring. + */ + clone() { + let s = new r(this.members); + return s.id = this.id, s.insiders = d.clone(this.insiders), s.neighbours = d.clone(this.neighbours), s.positioned = this.positioned, s.center = this.center.clone(), s.rings = d.clone(this.rings), s.isBridged = this.isBridged, s.isPartOfBridged = this.isPartOfBridged, s.isSpiro = this.isSpiro, s.isFused = this.isFused, s.centralAngle = this.centralAngle, s.canFlip = this.canFlip, s; + } + /** + * Returns the size (number of members) of this ring. + * + * @returns {Number} The size (number of members) of this ring. + */ + getSize() { + return this.members.length; + } + /** + * Gets the polygon representation (an array of the ring-members positional vectors) of this ring. + * + * @param {Vertex[]} vertices An array of vertices representing the current molecule. + * @returns {Vector2[]} An array of the positional vectors of the ring members. + */ + getPolygon(s) { + let a = []; + for (let n = 0; n < this.members.length; n++) + a.push(s[this.members[n]].position); + return a; + } + /** + * Returns the angle of this ring in relation to the coordinate system. + * + * @returns {Number} The angle in radians. + */ + getAngle() { + return Math.PI - this.centralAngle; + } + /** + * Loops over the members of this ring from a given start position in a direction opposite to the vertex id passed as the previousId. + * + * @param {Vertex[]} vertices The vertices associated with the current molecule. + * @param {Function} callback A callback with the current vertex id as a parameter. + * @param {Number} startVertexId The vertex id of the start vertex. + * @param {Number} previousVertexId The vertex id of the previous vertex (the loop calling the callback function will run in the opposite direction of this vertex). + */ + eachMember(s, a, n, h) { + n = n || n === 0 ? n : this.members[0]; + let l = n, c = 0; + for (; l != null && c < 100; ) { + let u = l; + a(u), l = s[l].getNextInRing(s, this.id, h), h = u, l == n && (l = null), c++; + } + } + /** + * Returns an array containing the neighbouring rings of this ring ordered by ring size. + * + * @param {RingConnection[]} ringConnections An array of ring connections associated with the current molecule. + * @returns {Object[]} An array of neighbouring rings sorted by ring size. Example: { n: 5, neighbour: 1 }. + */ + getOrderedNeighbours(s) { + let a = Array(this.neighbours.length); + for (let n = 0; n < this.neighbours.length; n++) { + let h = t.getVertices(s, this.id, this.neighbours[n]); + a[n] = { + n: h.length, + neighbour: this.neighbours[n] + }; + } + return a.sort(function(n, h) { + return h.n - n.n; + }), a; + } + /** + * Check whether this ring is an implicitly defined benzene-like (e.g. C1=CC=CC=C1) with 6 members and 3 double bonds. + * + * @param {Vertex[]} vertices An array of vertices associated with the current molecule. + * @returns {Boolean} A boolean indicating whether or not this ring is an implicitly defined benzene-like. + */ + isBenzeneLike(s) { + let a = this.getDoubleBondCount(s), n = this.members.length; + return a === 3 && n === 6 || a === 2 && n === 5; + } + /** + * Get the number of double bonds inside this ring. + * + * @param {Vertex[]} vertices An array of vertices associated with the current molecule. + * @returns {Number} The number of double bonds inside this ring. + */ + getDoubleBondCount(s) { + let a = 0; + for (let n = 0; n < this.members.length; n++) { + let h = s[this.members[n]].value; + (h.bondType === "=" || h.branchBond === "=") && a++; + } + return a; + } + /** + * Checks whether or not this ring contains a member with a given vertex id. + * + * @param {Number} vertexId A vertex id. + * @returns {Boolean} A boolean indicating whether or not this ring contains a member with the given vertex id. + */ + contains(s) { + for (let a = 0; a < this.members.length; a++) + if (this.members[a] == s) + return !0; + return !1; + } + } + return Mn = r, Mn; +} +var Bn, La; +function Li() { + if (La) + return Bn; + La = 1; + const d = Zr; + Or(), jr(); + class e { + /** + * The constructor of the class Atom. + * + * @param {String} element The one-letter code of the element. + * @param {String} [bondType='-'] The type of the bond associated with this atom. + */ + constructor(r, i = "-") { + this.idx = null, this.element = r.length === 1 ? r.toUpperCase() : r, this.drawExplicit = !1, this.ringbonds = Array(), this.rings = Array(), this.bondType = i, this.branchBond = null, this.isBridge = !1, this.isBridgeNode = !1, this.originalRings = Array(), this.bridgedRing = null, this.anchoredRings = Array(), this.bracket = null, this.plane = 0, this.attachedPseudoElements = {}, this.hasAttachedPseudoElements = !1, this.isDrawn = !0, this.isConnectedToRing = !1, this.neighbouringElements = Array(), this.isPartOfAromaticRing = r !== this.element, this.bondCount = 0, this.chirality = "", this.isStereoCenter = !1, this.priority = 0, this.mainChain = !1, this.hydrogenDirection = "down", this.subtreeDepth = 1, this.hasHydrogen = !1, this.class = void 0; + } + /** + * Adds a neighbouring element to this atom. + * + * @param {String} element A string representing an element. + */ + addNeighbouringElement(r) { + this.neighbouringElements.push(r); + } + /** + * Attaches a pseudo element (e.g. Ac) to the atom. + * @param {String} element The element identifier (e.g. Br, C, ...). + * @param {String} previousElement The element that is part of the main chain (not the terminals that are converted to the pseudo element or concatinated). + * @param {Number} [hydrogenCount=0] The number of hydrogens for the element. + * @param {Number} [charge=0] The charge for the element. + */ + attachPseudoElement(r, i, s = 0, a = 0) { + s === null && (s = 0), a === null && (a = 0); + let n = s + r + a; + this.attachedPseudoElements[n] ? this.attachedPseudoElements[n].count += 1 : this.attachedPseudoElements[n] = { + element: r, + count: 1, + hydrogenCount: s, + previousElement: i, + charge: a + }, this.hasAttachedPseudoElements = !0; + } + /** + * Returns the attached pseudo elements sorted by hydrogen count (ascending). + * + * @returns {Object} The sorted attached pseudo elements. + */ + getAttachedPseudoElements() { + let r = {}, i = this; + return Object.keys(this.attachedPseudoElements).sort().forEach(function(s) { + r[s] = i.attachedPseudoElements[s]; + }), r; + } + /** + * Returns the number of attached pseudo elements. + * + * @returns {Number} The number of attached pseudo elements. + */ + getAttachedPseudoElementsCount() { + return Object.keys(this.attachedPseudoElements).length; + } + /** + * Returns whether this atom is a heteroatom (not C and not H). + * + * @returns {Boolean} A boolean indicating whether this atom is a heteroatom. + */ + isHeteroAtom() { + return this.element !== "C" && this.element !== "H"; + } + /** + * Defines this atom as the anchor for a ring. When doing repositionings of the vertices and the vertex associated with this atom is moved, the center of this ring is moved as well. + * + * @param {Number} ringId A ring id. + */ + addAnchoredRing(r) { + d.contains(this.anchoredRings, { + value: r + }) || this.anchoredRings.push(r); + } + /** + * Returns the number of ringbonds (breaks in rings to generate the MST of the smiles) within this atom is connected to. + * + * @returns {Number} The number of ringbonds this atom is connected to. + */ + getRingbondCount() { + return this.ringbonds.length; + } + /** + * Backs up the current rings. + */ + backupRings() { + this.originalRings = Array(this.rings.length); + for (let r = 0; r < this.rings.length; r++) + this.originalRings[r] = this.rings[r]; + } + /** + * Restores the most recent backed up rings. + */ + restoreRings() { + this.rings = Array(this.originalRings.length); + for (let r = 0; r < this.originalRings.length; r++) + this.rings[r] = this.originalRings[r]; + } + /** + * Checks whether or not two atoms share a common ringbond id. A ringbond is a break in a ring created when generating the spanning tree of a structure. + * + * @param {Atom} atomA An atom. + * @param {Atom} atomB An atom. + * @returns {Boolean} A boolean indicating whether or not two atoms share a common ringbond. + */ + haveCommonRingbond(r, i) { + for (let s = 0; s < r.ringbonds.length; s++) + for (let a = 0; a < i.ringbonds.length; a++) + if (r.ringbonds[s].id == i.ringbonds[a].id) + return !0; + return !1; + } + /** + * Check whether or not the neighbouring elements of this atom equal the supplied array. + * + * @param {String[]} arr An array containing all the elements that are neighbouring this atom. E.g. ['C', 'O', 'O', 'N'] + * @returns {Boolean} A boolean indicating whether or not the neighbours match the supplied array of elements. + */ + neighbouringElementsEqual(r) { + if (r.length !== this.neighbouringElements.length) + return !1; + r.sort(), this.neighbouringElements.sort(); + for (var i = 0; i < this.neighbouringElements.length; i++) + if (r[i] !== this.neighbouringElements[i]) + return !1; + return !0; + } + /** + * Get the atomic number of this atom. + * + * @returns {Number} The atomic number of this atom. + */ + getAtomicNumber() { + return e.atomicNumbers[this.element]; + } + /** + * Get the maximum number of bonds for this atom. + * + * @returns {Number} The maximum number of bonds of this atom. + */ + getMaxBonds() { + return e.maxBonds[this.element]; + } + /** + * A map mapping element symbols to their maximum bonds. + */ + static get maxBonds() { + return { + H: 1, + C: 4, + N: 3, + O: 2, + P: 3, + S: 2, + B: 3, + F: 1, + I: 1, + Cl: 1, + Br: 1 + }; + } + /** + * A map mapping element symbols to the atomic number. + */ + static get atomicNumbers() { + return { + H: 1, + He: 2, + Li: 3, + Be: 4, + B: 5, + b: 5, + C: 6, + c: 6, + N: 7, + n: 7, + O: 8, + o: 8, + F: 9, + Ne: 10, + Na: 11, + Mg: 12, + Al: 13, + Si: 14, + P: 15, + p: 15, + S: 16, + s: 16, + Cl: 17, + Ar: 18, + K: 19, + Ca: 20, + Sc: 21, + Ti: 22, + V: 23, + Cr: 24, + Mn: 25, + Fe: 26, + Co: 27, + Ni: 28, + Cu: 29, + Zn: 30, + Ga: 31, + Ge: 32, + As: 33, + Se: 34, + Br: 35, + Kr: 36, + Rb: 37, + Sr: 38, + Y: 39, + Zr: 40, + Nb: 41, + Mo: 42, + Tc: 43, + Ru: 44, + Rh: 45, + Pd: 46, + Ag: 47, + Cd: 48, + In: 49, + Sn: 50, + Sb: 51, + Te: 52, + I: 53, + Xe: 54, + Cs: 55, + Ba: 56, + La: 57, + Ce: 58, + Pr: 59, + Nd: 60, + Pm: 61, + Sm: 62, + Eu: 63, + Gd: 64, + Tb: 65, + Dy: 66, + Ho: 67, + Er: 68, + Tm: 69, + Yb: 70, + Lu: 71, + Hf: 72, + Ta: 73, + W: 74, + Re: 75, + Os: 76, + Ir: 77, + Pt: 78, + Au: 79, + Hg: 80, + Tl: 81, + Pb: 82, + Bi: 83, + Po: 84, + At: 85, + Rn: 86, + Fr: 87, + Ra: 88, + Ac: 89, + Th: 90, + Pa: 91, + U: 92, + Np: 93, + Pu: 94, + Am: 95, + Cm: 96, + Bk: 97, + Cf: 98, + Es: 99, + Fm: 100, + Md: 101, + No: 102, + Lr: 103, + Rf: 104, + Db: 105, + Sg: 106, + Bh: 107, + Hs: 108, + Mt: 109, + Ds: 110, + Rg: 111, + Cn: 112, + Uut: 113, + Uuq: 114, + Uup: 115, + Uuh: 116, + Uus: 117, + Uuo: 118 + }; + } + /** + * A map mapping element symbols to the atomic mass. + */ + static get mass() { + return { + H: 1, + He: 2, + Li: 3, + Be: 4, + B: 5, + b: 5, + C: 6, + c: 6, + N: 7, + n: 7, + O: 8, + o: 8, + F: 9, + Ne: 10, + Na: 11, + Mg: 12, + Al: 13, + Si: 14, + P: 15, + p: 15, + S: 16, + s: 16, + Cl: 17, + Ar: 18, + K: 19, + Ca: 20, + Sc: 21, + Ti: 22, + V: 23, + Cr: 24, + Mn: 25, + Fe: 26, + Co: 27, + Ni: 28, + Cu: 29, + Zn: 30, + Ga: 31, + Ge: 32, + As: 33, + Se: 34, + Br: 35, + Kr: 36, + Rb: 37, + Sr: 38, + Y: 39, + Zr: 40, + Nb: 41, + Mo: 42, + Tc: 43, + Ru: 44, + Rh: 45, + Pd: 46, + Ag: 47, + Cd: 48, + In: 49, + Sn: 50, + Sb: 51, + Te: 52, + I: 53, + Xe: 54, + Cs: 55, + Ba: 56, + La: 57, + Ce: 58, + Pr: 59, + Nd: 60, + Pm: 61, + Sm: 62, + Eu: 63, + Gd: 64, + Tb: 65, + Dy: 66, + Ho: 67, + Er: 68, + Tm: 69, + Yb: 70, + Lu: 71, + Hf: 72, + Ta: 73, + W: 74, + Re: 75, + Os: 76, + Ir: 77, + Pt: 78, + Au: 79, + Hg: 80, + Tl: 81, + Pb: 82, + Bi: 83, + Po: 84, + At: 85, + Rn: 86, + Fr: 87, + Ra: 88, + Ac: 89, + Th: 90, + Pa: 91, + U: 92, + Np: 93, + Pu: 94, + Am: 95, + Cm: 96, + Bk: 97, + Cf: 98, + Es: 99, + Fm: 100, + Md: 101, + No: 102, + Lr: 103, + Rf: 104, + Db: 105, + Sg: 106, + Bh: 107, + Hs: 108, + Mt: 109, + Ds: 110, + Rg: 111, + Cn: 112, + Uut: 113, + Uuq: 114, + Uup: 115, + Uuh: 116, + Uus: 117, + Uuo: 118 + }; + } + } + return Bn = e, Bn; +} +const Tr = ar; +let sg = class gl { + /** + * The constructor for the class Line. + * + * @param {Vector2} [from=new Vector2(0, 0)] A vector marking the beginning of the line. + * @param {Vector2} [to=new Vector2(0, 0)] A vector marking the end of the line. + * @param {string} [elementFrom=null] A one-letter representation of the element associated with the vector marking the beginning of the line. + * @param {string} [elementTo=null] A one-letter representation of the element associated with the vector marking the end of the line. + * @param {Boolean} [chiralFrom=false] Whether or not the from atom is a chiral center. + * @param {Boolean} [chiralTo=false] Whether or not the to atom is a chiral center. + */ + constructor(e = new Tr(0, 0), t = new Tr(0, 0), r = null, i = null, s = !1, a = !1) { + this.from = e, this.to = t, this.elementFrom = r, this.elementTo = i, this.chiralFrom = s, this.chiralTo = a; + } + /** + * Clones this line and returns the clone. + * + * @returns {Line} A clone of this line. + */ + clone() { + return new gl(this.from.clone(), this.to.clone(), this.elementFrom, this.elementTo); + } + /** + * Returns the length of this line. + * + * @returns {Number} The length of this line. + */ + getLength() { + return Math.sqrt(Math.pow(this.to.x - this.from.x, 2) + Math.pow(this.to.y - this.from.y, 2)); + } + /** + * Returns the angle of the line in relation to the coordinate system (the x-axis). + * + * @returns {Number} The angle in radians. + */ + getAngle() { + return Tr.subtract(this.getRightVector(), this.getLeftVector()).angle(); + } + /** + * Returns the right vector (the vector with the larger x value). + * + * @returns {Vector2} The right vector. + */ + getRightVector() { + return this.from.x < this.to.x ? this.to : this.from; + } + /** + * Returns the left vector (the vector with the smaller x value). + * + * @returns {Vector2} The left vector. + */ + getLeftVector() { + return this.from.x < this.to.x ? this.from : this.to; + } + /** + * Returns the element associated with the right vector (the vector with the larger x value). + * + * @returns {String} The element associated with the right vector. + */ + getRightElement() { + return this.from.x < this.to.x ? this.elementTo : this.elementFrom; + } + /** + * Returns the element associated with the left vector (the vector with the smaller x value). + * + * @returns {String} The element associated with the left vector. + */ + getLeftElement() { + return this.from.x < this.to.x ? this.elementFrom : this.elementTo; + } + /** + * Returns whether or not the atom associated with the right vector (the vector with the larger x value) is a chiral center. + * + * @returns {Boolean} Whether or not the atom associated with the right vector is a chiral center. + */ + getRightChiral() { + return this.from.x < this.to.x ? this.chiralTo : this.chiralFrom; + } + /** + * Returns whether or not the atom associated with the left vector (the vector with the smaller x value) is a chiral center. + * + * @returns {Boolean} Whether or not the atom associated with the left vector is a chiral center. + */ + getLeftChiral() { + return this.from.x < this.to.x ? this.chiralFrom : this.chiralTo; + } + /** + * Set the value of the right vector. + * + * @param {Number} x The x value. + * @param {Number} y The y value. + * @returns {Line} This line. + */ + setRightVector(e, t) { + return this.from.x < this.to.x ? (this.to.x = e, this.to.y = t) : (this.from.x = e, this.from.y = t), this; + } + /** + * Set the value of the left vector. + * + * @param {Number} x The x value. + * @param {Number} y The y value. + * @returns {Line} This line. + */ + setLeftVector(e, t) { + return this.from.x < this.to.x ? (this.from.x = e, this.from.y = t) : (this.to.x = e, this.to.y = t), this; + } + /** + * Rotates this line to be aligned with the x-axis. The center of rotation is the left vector. + * + * @returns {Line} This line. + */ + rotateToXAxis() { + let e = this.getLeftVector(); + return this.setRightVector(e.x + this.getLength(), e.y), this; + } + /** + * Rotate the line by a given value (in radians). The center of rotation is the left vector. + * + * @param {Number} theta The angle (in radians) to rotate the line. + * @returns {Line} This line. + */ + rotate(e) { + let t = this.getLeftVector(), r = this.getRightVector(), i = Math.sin(e), s = Math.cos(e), a = s * (r.x - t.x) - i * (r.y - t.y) + t.x, n = i * (r.x - t.x) - s * (r.y - t.y) + t.y; + return this.setRightVector(a, n), this; + } + /** + * Shortens this line from the "from" direction by a given value (in pixels). + * + * @param {Number} by The length in pixels to shorten the vector by. + * @returns {Line} This line. + */ + shortenFrom(e) { + let t = Tr.subtract(this.to, this.from); + return t.normalize(), t.multiplyScalar(e), this.from.add(t), this; + } + /** + * Shortens this line from the "to" direction by a given value (in pixels). + * + * @param {Number} by The length in pixels to shorten the vector by. + * @returns {Line} This line. + */ + shortenTo(e) { + let t = Tr.subtract(this.from, this.to); + return t.normalize(), t.multiplyScalar(e), this.to.add(t), this; + } + /** + * Shorten the right side. + * + * @param {Number} by The length in pixels to shorten the vector by. + * @returns {Line} Returns itself. + */ + shortenRight(e) { + return this.from.x < this.to.x ? this.shortenTo(e) : this.shortenFrom(e), this; + } + /** + * Shorten the left side. + * + * @param {Number} by The length in pixels to shorten the vector by. + * @returns {Line} Returns itself. + */ + shortenLeft(e) { + return this.from.x < this.to.x ? this.shortenFrom(e) : this.shortenTo(e), this; + } + /** + * Shortens this line from both directions by a given value (in pixels). + * + * @param {Number} by The length in pixels to shorten the vector by. + * @returns {Line} This line. + */ + shorten(e) { + let t = Tr.subtract(this.from, this.to); + return t.normalize(), t.multiplyScalar(e / 2), this.to.add(t), this.from.subtract(t), this; + } +}; +var Xn = sg; +let ag = class dl { + /** + * The constructor for the class Edge. + * + * @param {Number} sourceId A vertex id. + * @param {Number} targetId A vertex id. + * @param {Number} [weight=1] The weight of the edge. + */ + constructor(e, t, r = 1) { + this.id = null, this.sourceId = e, this.targetId = t, this.weight = r, this.bondType = "-", this.isPartOfAromaticRing = !1, this.center = !1, this.wedge = ""; + } + /** + * Set the bond type of this edge. This also sets the edge weight. + * @param {String} bondType + */ + setBondType(e) { + this.bondType = e, this.weight = dl.bonds[e]; + } + /** + * An object mapping the bond type to the number of bonds. + * + * @returns {Object} The object containing the map. + */ + static get bonds() { + return { + "-": 1, + "/": 1, + "\\": 1, + "=": 2, + "#": 3, + $: 4 + }; + } +}; +var pl = ag; +function lg(d) { + return d === 1 ? "+" : d === 2 ? "2+" : d === -1 ? "-" : d === -2 ? "2-" : ""; +} +var og = { + getChargeText: lg +}; +const Er = Kr, Ke = ar; +Or(); +jr(); +const { getChargeText: Ma } = og; +let hg = class { + /** + * The constructor for the class CanvasWrapper. + * + * @param {(String|HTMLElement)} target The canvas id or the canvas HTMLElement. + * @param {ThemeManager} themeManager Theme manager for setting proper colors. + * @param {Object} options The smiles drawer options object. + */ + constructor(e, t, r) { + typeof e == "string" || e instanceof String ? this.canvas = document.getElementById(e) : this.canvas = e, this.ctx = this.canvas.getContext("2d"), this.themeManager = t, this.opts = r, this.drawingWidth = 0, this.drawingHeight = 0, this.offsetX = 0, this.offsetY = 0, this.fontLarge = this.opts.fontSizeLarge + "pt Helvetica, Arial, sans-serif", this.fontSmall = this.opts.fontSizeSmall + "pt Helvetica, Arial, sans-serif", this.updateSize(this.opts.width, this.opts.height), this.ctx.font = this.fontLarge, this.hydrogenWidth = this.ctx.measureText("H").width, this.halfHydrogenWidth = this.hydrogenWidth / 2, this.halfBondThickness = this.opts.bondThickness / 2; + } + /** + * Update the width and height of the canvas + * + * @param {Number} width + * @param {Number} height + */ + updateSize(e, t) { + this.devicePixelRatio = window.devicePixelRatio || 1, this.backingStoreRatio = this.ctx.webkitBackingStorePixelRatio || this.ctx.mozBackingStorePixelRatio || this.ctx.msBackingStorePixelRatio || this.ctx.oBackingStorePixelRatio || this.ctx.backingStorePixelRatio || 1, this.ratio = this.devicePixelRatio / this.backingStoreRatio, this.ratio !== 1 ? (this.canvas.width = e * this.ratio, this.canvas.height = t * this.ratio, this.canvas.style.width = e + "px", this.canvas.style.height = t + "px", this.ctx.setTransform(this.ratio, 0, 0, this.ratio, 0, 0)) : (this.canvas.width = e * this.ratio, this.canvas.height = t * this.ratio); + } + /** + * Sets a provided theme. + * + * @param {Object} theme A theme from the smiles drawer options. + */ + setTheme(e) { + this.colors = e; + } + /** + * Scale the canvas based on vertex positions. + * + * @param {Vertex[]} vertices An array of vertices containing the vertices associated with the current molecule. + */ + scale(e) { + let t = -Number.MAX_VALUE, r = -Number.MAX_VALUE, i = Number.MAX_VALUE, s = Number.MAX_VALUE; + for (var a = 0; a < e.length; a++) { + if (!e[a].value.isDrawn) + continue; + let u = e[a].position; + t < u.x && (t = u.x), r < u.y && (r = u.y), i > u.x && (i = u.x), s > u.y && (s = u.y); + } + var n = this.opts.padding; + t += n, r += n, i -= n, s -= n, this.drawingWidth = t - i, this.drawingHeight = r - s; + var h = this.canvas.offsetWidth / this.drawingWidth, l = this.canvas.offsetHeight / this.drawingHeight, c = h < l ? h : l; + this.ctx.scale(c, c), this.offsetX = -i, this.offsetY = -s, h < l ? this.offsetY += this.canvas.offsetHeight / (2 * c) - this.drawingHeight / 2 : this.offsetX += this.canvas.offsetWidth / (2 * c) - this.drawingWidth / 2; + } + /** + * Resets the transform of the canvas. + */ + reset() { + this.ctx.setTransform(1, 0, 0, 1, 0, 0); + } + /** + * Returns the hex code of a color associated with a key from the current theme. + * + * @param {String} key The color key in the theme (e.g. C, N, BACKGROUND, ...). + * @returns {String} A color hex value. + */ + getColor(e) { + return e = e.toUpperCase(), e in this.colors ? this.colors[e] : this.colors.C; + } + /** + * Draws a circle to a canvas context. + * @param {Number} x The x coordinate of the circles center. + * @param {Number} y The y coordinate of the circles center. + * @param {Number} radius The radius of the circle + * @param {String} color A hex encoded color. + * @param {Boolean} [fill=true] Whether to fill or stroke the circle. + * @param {Boolean} [debug=false] Draw in debug mode. + * @param {String} [debugText=''] A debug message. + */ + drawCircle(e, t, r, i, s = !0, a = !1, n = "") { + let h = this.ctx, l = this.offsetX, c = this.offsetY; + h.save(), h.lineWidth = 1.5, h.beginPath(), h.arc(e + l, t + c, r, 0, Er.twoPI, !0), h.closePath(), a ? (s ? (h.fillStyle = "#f00", h.fill()) : (h.strokeStyle = "#f00", h.stroke()), this.drawDebugText(e, t, n)) : s ? (h.fillStyle = i, h.fill()) : (h.strokeStyle = i, h.stroke()), h.restore(); + } + /** + * Draw a line to a canvas. + * + * @param {Line} line A line. + * @param {Boolean} [dashed=false] Whether or not the line is dashed. + * @param {Number} [alpha=1.0] The alpha value of the color. + */ + drawLine(e, t = !1, r = 1) { + let i = this.ctx, s = this.offsetX, a = this.offsetY, n = e.clone().shorten(4), h = n.getLeftVector().clone(), l = n.getRightVector().clone(); + h.x += s, h.y += a, l.x += s, l.y += a, t || (i.save(), i.globalCompositeOperation = "destination-out", i.beginPath(), i.moveTo(h.x, h.y), i.lineTo(l.x, l.y), i.lineCap = "round", i.lineWidth = this.opts.bondThickness + 1.2, i.strokeStyle = this.themeManager.getColor("BACKGROUND"), i.stroke(), i.globalCompositeOperation = "source-over", i.restore()), h = e.getLeftVector().clone(), l = e.getRightVector().clone(), h.x += s, h.y += a, l.x += s, l.y += a, i.save(), i.beginPath(), i.moveTo(h.x, h.y), i.lineTo(l.x, l.y), i.lineCap = "round", i.lineWidth = this.opts.bondThickness; + let c = this.ctx.createLinearGradient(h.x, h.y, l.x, l.y); + c.addColorStop(0.4, this.themeManager.getColor(e.getLeftElement()) || this.themeManager.getColor("C")), c.addColorStop(0.6, this.themeManager.getColor(e.getRightElement()) || this.themeManager.getColor("C")), t && (i.setLineDash([1, 1.5]), i.lineWidth = this.opts.bondThickness / 1.5), r < 1 && (i.globalAlpha = r), i.strokeStyle = c, i.stroke(), i.restore(); + } + /** + * Draw a wedge on the canvas. + * + * @param {Line} line A line. + * @param {Number} width The wedge width. + */ + drawWedge(e, t = 1) { + if (isNaN(e.from.x) || isNaN(e.from.y) || isNaN(e.to.x) || isNaN(e.to.y)) + return; + let r = this.ctx, i = this.offsetX, s = this.offsetY, a = e.clone().shorten(5), n = a.getLeftVector().clone(), h = a.getRightVector().clone(); + n.x += i, n.y += s, h.x += i, h.y += s, n = e.getLeftVector().clone(), h = e.getRightVector().clone(), n.x += i, n.y += s, h.x += i, h.y += s, r.save(); + let l = Ke.normals(n, h); + l[0].normalize(), l[1].normalize(); + let c = e.getRightChiral(), u = n, g = h; + c && (u = h, g = n); + let m = Ke.add(u, Ke.multiplyScalar(l[0], this.halfBondThickness)), _ = Ke.add(g, Ke.multiplyScalar(l[0], 1.5 + this.halfBondThickness)), v = Ke.add(g, Ke.multiplyScalar(l[1], 1.5 + this.halfBondThickness)), N = Ke.add(u, Ke.multiplyScalar(l[1], this.halfBondThickness)); + r.beginPath(), r.moveTo(m.x, m.y), r.lineTo(_.x, _.y), r.lineTo(v.x, v.y), r.lineTo(N.x, N.y); + let B = this.ctx.createRadialGradient(h.x, h.y, this.opts.bondLength, h.x, h.y, 0); + B.addColorStop(0.4, this.themeManager.getColor(e.getLeftElement()) || this.themeManager.getColor("C")), B.addColorStop(0.6, this.themeManager.getColor(e.getRightElement()) || this.themeManager.getColor("C")), r.fillStyle = B, r.fill(), r.restore(); + } + /** + * Draw a dashed wedge on the canvas. + * + * @param {Line} line A line. + */ + drawDashedWedge(e) { + if (isNaN(e.from.x) || isNaN(e.from.y) || isNaN(e.to.x) || isNaN(e.to.y)) + return; + let t = this.ctx, r = this.offsetX, i = this.offsetY, s = e.getLeftVector().clone(), a = e.getRightVector().clone(); + s.x += r, s.y += i, a.x += r, a.y += i, t.save(); + let n = Ke.normals(s, a); + n[0].normalize(), n[1].normalize(); + let h = e.getRightChiral(), l, c, u, g, m = e.clone(); + h ? (l = a, c = s, m.shortenRight(1), u = m.getRightVector().clone(), g = m.getLeftVector().clone()) : (l = s, c = a, m.shortenLeft(1), u = m.getLeftVector().clone(), g = m.getRightVector().clone()), u.x += r, u.y += i, g.x += r, g.y += i; + let _ = Ke.subtract(c, l).normalize(); + t.strokeStyle = this.themeManager.getColor("C"), t.lineCap = "round", t.lineWidth = this.opts.bondThickness, t.beginPath(); + let v = e.getLength(), N = 1.25 / (v / (this.opts.bondThickness * 3)), B = !1; + for (var x = 0; x < 1; x += N) { + let L = Ke.multiplyScalar(_, x * v), k = Ke.add(l, L), z = 1.5 * x, D = Ke.multiplyScalar(n[0], z); + !B && x > 0.5 && (t.stroke(), t.beginPath(), t.strokeStyle = this.themeManager.getColor(e.getRightElement()) || this.themeManager.getColor("C"), B = !0), k.subtract(D), t.moveTo(k.x, k.y), k.add(Ke.multiplyScalar(D, 2)), t.lineTo(k.x, k.y); + } + t.stroke(), t.restore(); + } + /** + * Draws a debug text message at a given position + * + * @param {Number} x The x coordinate. + * @param {Number} y The y coordinate. + * @param {String} text The debug text. + */ + drawDebugText(e, t, r) { + let i = this.ctx; + i.save(), i.font = "5px Droid Sans, sans-serif", i.textAlign = "start", i.textBaseline = "top", i.fillStyle = "#ff0000", i.fillText(r, e + this.offsetX, t + this.offsetY), i.restore(); + } + /** + * Draw a ball to the canvas. + * + * @param {Number} x The x position of the text. + * @param {Number} y The y position of the text. + * @param {String} elementName The name of the element (single-letter). + */ + drawBall(e, t, r) { + let i = this.ctx; + i.save(), i.beginPath(), i.arc(e + this.offsetX, t + this.offsetY, this.opts.bondLength / 4.5, 0, Er.twoPI, !1), i.fillStyle = this.themeManager.getColor(r), i.fill(), i.restore(); + } + /** + * Draw a point to the canvas. + * + * @param {Number} x The x position of the point. + * @param {Number} y The y position of the point. + * @param {String} elementName The name of the element (single-letter). + */ + drawPoint(e, t, r) { + let i = this.ctx, s = this.offsetX, a = this.offsetY; + i.save(), i.globalCompositeOperation = "destination-out", i.beginPath(), i.arc(e + s, t + a, 1.5, 0, Er.twoPI, !0), i.closePath(), i.fill(), i.globalCompositeOperation = "source-over", i.beginPath(), i.arc(e + this.offsetX, t + this.offsetY, 0.75, 0, Er.twoPI, !1), i.fillStyle = this.themeManager.getColor(r), i.fill(), i.restore(); + } + /** + * Draw a text to the canvas. + * + * @param {Number} x The x position of the text. + * @param {Number} y The y position of the text. + * @param {String} elementName The name of the element (single-letter). + * @param {Number} hydrogens The number of hydrogen atoms. + * @param {String} direction The direction of the text in relation to the associated vertex. + * @param {Boolean} isTerminal A boolean indicating whether or not the vertex is terminal. + * @param {Number} charge The charge of the atom. + * @param {Number} isotope The isotope number. + * @param {Number} vertexCount The number of vertices in the molecular graph. + * @param {Object} attachedPseudoElement A map with containing information for pseudo elements or concatinated elements. The key is comprised of the element symbol and the hydrogen count. + * @param {String} attachedPseudoElement.element The element symbol. + * @param {Number} attachedPseudoElement.count The number of occurences that match the key. + * @param {Number} attachedPseudoElement.hyrogenCount The number of hydrogens attached to each atom matching the key. + */ + drawText(e, t, r, i, s, a, n, h, l, c = {}) { + let u = this.ctx, g = this.offsetX, m = this.offsetY; + u.save(), u.textAlign = "start", u.textBaseline = "alphabetic"; + let _ = "", v = 0; + n && (_ = Ma(n), u.font = this.fontSmall, v = u.measureText(_).width); + let N = "0", B = 0; + h > 0 && (N = h.toString(), u.font = this.fontSmall, B = u.measureText(N).width), n === 1 && r === "N" && c.hasOwnProperty("0O") && c.hasOwnProperty("0O-1") && (c = { "0O": { element: "O", count: 2, hydrogenCount: 0, previousElement: "C", charge: "" } }, n = 0), u.font = this.fontLarge, u.fillStyle = this.themeManager.getColor("BACKGROUND"); + let x = u.measureText(r); + x.totalWidth = x.width + v, x.height = parseInt(this.fontLarge, 10); + let L = x.width > this.opts.fontSizeLarge ? x.width : this.opts.fontSizeLarge; + L /= 1.5, u.globalCompositeOperation = "destination-out", u.beginPath(), u.arc(e + g, t + m, L, 0, Er.twoPI, !0), u.closePath(), u.fill(), u.globalCompositeOperation = "source-over"; + let k = -x.width / 2, z = -x.width / 2; + u.fillStyle = this.themeManager.getColor(r), u.fillText(r, e + g + k, t + this.opts.halfFontSizeLarge + m), k += x.width, n && (u.font = this.fontSmall, u.fillText(_, e + g + k, t - this.opts.fifthFontSizeSmall + m), k += v), h > 0 && (u.font = this.fontSmall, u.fillText(N, e + g + z - B, t - this.opts.fifthFontSizeSmall + m), z -= B), u.font = this.fontLarge; + let D = 0, Y = 0; + if (i === 1) { + let O = e + g, Z = t + m + this.opts.halfFontSizeLarge; + D = this.hydrogenWidth, z -= D, s === "left" ? O += z : s === "right" || s === "up" && a || s === "down" && a ? O += k : s === "up" && !a ? (Z -= this.opts.fontSizeLarge + this.opts.quarterFontSizeLarge, O -= this.halfHydrogenWidth) : s === "down" && !a && (Z += this.opts.fontSizeLarge + this.opts.quarterFontSizeLarge, O -= this.halfHydrogenWidth), u.fillText("H", O, Z), k += D; + } else if (i > 1) { + let O = e + g, Z = t + m + this.opts.halfFontSizeLarge; + D = this.hydrogenWidth, u.font = this.fontSmall, Y = u.measureText(i).width, z -= D + Y, s === "left" ? O += z : s === "right" || s === "up" && a || s === "down" && a ? O += k : s === "up" && !a ? (Z -= this.opts.fontSizeLarge + this.opts.quarterFontSizeLarge, O -= this.halfHydrogenWidth) : s === "down" && !a && (Z += this.opts.fontSizeLarge + this.opts.quarterFontSizeLarge, O -= this.halfHydrogenWidth), u.font = this.fontLarge, u.fillText("H", O, Z), u.font = this.fontSmall, u.fillText(i, O + this.halfHydrogenWidth + Y, Z + this.opts.fifthFontSizeSmall), k += D + this.halfHydrogenWidth + Y; + } + for (let O in c) { + if (!c.hasOwnProperty(O)) + continue; + let Z = 0, j = 0, q = c[O].element, se = c[O].count, ye = c[O].hydrogenCount, ke = c[O].charge; + u.font = this.fontLarge, se > 1 && ye > 0 && (Z = u.measureText("(").width, j = u.measureText(")").width); + let xe = u.measureText(q).width, we = 0, Ee = "", Qe = 0; + D = 0, ye > 0 && (D = this.hydrogenWidth), u.font = this.fontSmall, se > 1 && (we = u.measureText(se).width), ke !== 0 && (Ee = Ma(ke), Qe = u.measureText(Ee).width), Y = 0, ye > 1 && (Y = u.measureText(ye).width), u.font = this.fontLarge; + let Ce = e + g, Ae = t + m + this.opts.halfFontSizeLarge; + u.fillStyle = this.themeManager.getColor(q), se > 0 && (z -= we), se > 1 && ye > 0 && (s === "left" ? (z -= j, u.fillText(")", Ce + z, Ae)) : (u.fillText("(", Ce + k, Ae), k += Z)), s === "left" ? (z -= xe, u.fillText(q, Ce + z, Ae)) : (u.fillText(q, Ce + k, Ae), k += xe), ye > 0 && (s === "left" ? (z -= D + Y, u.fillText("H", Ce + z, Ae), ye > 1 && (u.font = this.fontSmall, u.fillText(ye, Ce + z + D, Ae + this.opts.fifthFontSizeSmall))) : (u.fillText("H", Ce + k, Ae), k += D, ye > 1 && (u.font = this.fontSmall, u.fillText(ye, Ce + k, Ae + this.opts.fifthFontSizeSmall), k += Y))), u.font = this.fontLarge, se > 1 && ye > 0 && (s === "left" ? (z -= Z, u.fillText("(", Ce + z, Ae)) : (u.fillText(")", Ce + k, Ae), k += j)), u.font = this.fontSmall, se > 1 && (s === "left" ? u.fillText(se, Ce + z + Z + j + D + Y + xe, Ae + this.opts.fifthFontSizeSmall) : (u.fillText(se, Ce + k, Ae + this.opts.fifthFontSizeSmall), k += we)), ke !== 0 && (s === "left" ? u.fillText(Ee, Ce + z + Z + j + D + Y + xe, t - this.opts.fifthFontSizeSmall + m) : (u.fillText(Ee, Ce + k, t - this.opts.fifthFontSizeSmall + m), k += Qe)); + } + u.restore(); + } + /** + * Translate the integer indicating the charge to the appropriate text. + * @param {Number} charge The integer indicating the charge. + * @returns {String} A string representing a charge. + */ + getChargeText(e) { + return e === 1 ? "+" : e === 2 ? "2+" : e === -1 ? "-" : e === -2 ? "2-" : ""; + } + /** + * Draws a dubug dot at a given coordinate and adds text. + * + * @param {Number} x The x coordinate. + * @param {Number} y The y coordindate. + * @param {String} [debugText=''] A string. + * @param {String} [color='#f00'] A color in hex form. + */ + drawDebugPoint(e, t, r = "", i = "#f00") { + this.drawCircle(e, t, 2, i, !0, !0, r); + } + /** + * Draws a ring inside a provided ring, indicating aromaticity. + * + * @param {Ring} ring A ring. + */ + drawAromaticityRing(e) { + let t = this.ctx, r = Er.apothemFromSideLength(this.opts.bondLength, e.getSize()); + t.save(), t.strokeStyle = this.themeManager.getColor("C"), t.lineWidth = this.opts.bondThickness, t.beginPath(), t.arc( + e.center.x + this.offsetX, + e.center.y + this.offsetY, + r - this.opts.bondSpacing, + 0, + Math.PI * 2, + !0 + ), t.closePath(), t.stroke(), t.restore(); + } + /** + * Clear the canvas. + * + */ + clear() { + this.ctx.clearRect(0, 0, this.canvas.offsetWidth, this.canvas.offsetHeight); + } +}; +var fg = hg; +const Ba = Kr, ug = Or(), cg = pl; +jr(); +const gg = Li(); +let dg = class Ur { + /** + * The constructor of the class Graph. + * + * @param {Object} parseTree A SMILES parse tree. + * @param {Boolean} [isomeric=false] A boolean specifying whether or not the SMILES is isomeric. + */ + constructor(e, t = !1) { + this.vertices = Array(), this.edges = Array(), this.atomIdxToVertexId = Array(), this.vertexIdsToEdgeId = {}, this.isomeric = t, this._atomIdx = 0, this._time = 0, this._init(e); + } + /** + * PRIVATE FUNCTION. Initializing the graph from the parse tree. + * + * @param {Object} node The current node in the parse tree. + * @param {?Number} parentVertexId=null The id of the previous vertex. + * @param {Boolean} isBranch=false Whether or not the bond leading to this vertex is a branch bond. Branches are represented by parentheses in smiles (e.g. CC(O)C). + */ + _init(e, t = 0, r = null, i = !1) { + const s = e.atom.element ? e.atom.element : e.atom; + let a = new gg(s, e.bond); + (s !== "H" || !e.hasNext && r === null) && (a.idx = this._atomIdx, this._atomIdx++), a.branchBond = e.branchBond, a.ringbonds = e.ringbonds, a.bracket = e.atom.element ? e.atom : null, a.class = e.atom.class; + let n = new ug(a), h = this.vertices[r]; + if (this.addVertex(n), a.idx !== null && this.atomIdxToVertexId.push(n.id), r !== null) { + n.setParentVertexId(r), n.value.addNeighbouringElement(h.value.element), h.addChild(n.id), h.value.addNeighbouringElement(a.element), h.spanningTreeChildren.push(n.id); + let g = new cg(r, n.id, 1); + i ? (g.setBondType(n.value.branchBond || "-"), n.id, g.setBondType(n.value.branchBond || "-"), n.id) : (g.setBondType(h.value.bondType || "-"), h.id), this.addEdge(g); + } + let l = e.ringbondCount + 1; + a.bracket && (l += a.bracket.hcount); + let c = 0; + if (a.bracket && a.bracket.chirality) { + a.isStereoCenter = !0, c = a.bracket.hcount; + for (var u = 0; u < c; u++) + this._init({ + atom: "H", + isBracket: "false", + branches: Array(), + branchCount: 0, + ringbonds: Array(), + ringbondCount: !1, + next: null, + hasNext: !1, + bond: "-" + }, u, n.id, !0); + } + for (var u = 0; u < e.branchCount; u++) + this._init(e.branches[u], u + l, n.id, !0); + e.hasNext && this._init(e.next, e.branchCount + l, n.id); + } + /** + * Clears all the elements in this graph (edges and vertices). + */ + clear() { + this.vertices = Array(), this.edges = Array(), this.vertexIdsToEdgeId = {}; + } + /** + * Add a vertex to the graph. + * + * @param {Vertex} vertex A new vertex. + * @returns {Number} The vertex id of the new vertex. + */ + addVertex(e) { + return e.id = this.vertices.length, this.vertices.push(e), e.id; + } + /** + * Add an edge to the graph. + * + * @param {Edge} edge A new edge. + * @returns {Number} The edge id of the new edge. + */ + addEdge(e) { + let t = this.vertices[e.sourceId], r = this.vertices[e.targetId]; + return e.id = this.edges.length, this.edges.push(e), this.vertexIdsToEdgeId[e.sourceId + "_" + e.targetId] = e.id, this.vertexIdsToEdgeId[e.targetId + "_" + e.sourceId] = e.id, e.isPartOfAromaticRing = t.value.isPartOfAromaticRing && r.value.isPartOfAromaticRing, t.value.bondCount += e.weight, r.value.bondCount += e.weight, t.edges.push(e.id), r.edges.push(e.id), e.id; + } + /** + * Returns the edge between two given vertices. + * + * @param {Number} vertexIdA A vertex id. + * @param {Number} vertexIdB A vertex id. + * @returns {(Edge|null)} The edge or, if no edge can be found, null. + */ + getEdge(e, t) { + let r = this.vertexIdsToEdgeId[e + "_" + t]; + return r === void 0 ? null : this.edges[r]; + } + /** + * Returns the ids of edges connected to a vertex. + * + * @param {Number} vertexId A vertex id. + * @returns {Number[]} An array containing the ids of edges connected to the vertex. + */ + getEdges(e) { + let t = Array(), r = this.vertices[e]; + for (var i = 0; i < r.neighbours.length; i++) + t.push(this.vertexIdsToEdgeId[e + "_" + r.neighbours[i]]); + return t; + } + /** + * Check whether or not two vertices are connected by an edge. + * + * @param {Number} vertexIdA A vertex id. + * @param {Number} vertexIdB A vertex id. + * @returns {Boolean} A boolean indicating whether or not two vertices are connected by an edge. + */ + hasEdge(e, t) { + return this.vertexIdsToEdgeId[e + "_" + t] !== void 0; + } + /** + * Returns an array containing the vertex ids of this graph. + * + * @returns {Number[]} An array containing all vertex ids of this graph. + */ + getVertexList() { + let e = [this.vertices.length]; + for (var t = 0; t < this.vertices.length; t++) + e[t] = this.vertices[t].id; + return e; + } + /** + * Returns an array containing source, target arrays of this graphs edges. + * + * @returns {Array[]} An array containing source, target arrays of this graphs edges. Example: [ [ 2, 5 ], [ 6, 9 ] ]. + */ + getEdgeList() { + let e = Array(this.edges.length); + for (var t = 0; t < this.edges.length; t++) + e[t] = [this.edges[t].sourceId, this.edges[t].targetId]; + return e; + } + /** + * Get the adjacency matrix of the graph. + * + * @returns {Array[]} The adjancency matrix of the molecular graph. + */ + getAdjacencyMatrix() { + let e = this.vertices.length, t = Array(e); + for (var r = 0; r < e; r++) + t[r] = new Array(e), t[r].fill(0); + for (var r = 0; r < this.edges.length; r++) { + let s = this.edges[r]; + t[s.sourceId][s.targetId] = 1, t[s.targetId][s.sourceId] = 1; + } + return t; + } + /** + * Get the adjacency matrix of the graph with all bridges removed (thus the components). Thus the remaining vertices are all part of ring systems. + * + * @returns {Array[]} The adjancency matrix of the molecular graph with all bridges removed. + */ + getComponentsAdjacencyMatrix() { + let e = this.vertices.length, t = Array(e), r = this.getBridges(); + for (var i = 0; i < e; i++) + t[i] = new Array(e), t[i].fill(0); + for (var i = 0; i < this.edges.length; i++) { + let a = this.edges[i]; + t[a.sourceId][a.targetId] = 1, t[a.targetId][a.sourceId] = 1; + } + for (var i = 0; i < r.length; i++) + t[r[i][0]][r[i][1]] = 0, t[r[i][1]][r[i][0]] = 0; + return t; + } + /** + * Get the adjacency matrix of a subgraph. + * + * @param {Number[]} vertexIds An array containing the vertex ids contained within the subgraph. + * @returns {Array[]} The adjancency matrix of the subgraph. + */ + getSubgraphAdjacencyMatrix(e) { + let t = e.length, r = Array(t); + for (var i = 0; i < t; i++) { + r[i] = new Array(t), r[i].fill(0); + for (var s = 0; s < t; s++) + i !== s && this.hasEdge(e[i], e[s]) && (r[i][s] = 1); + } + return r; + } + /** + * Get the distance matrix of the graph. + * + * @returns {Array[]} The distance matrix of the graph. + */ + getDistanceMatrix() { + let e = this.vertices.length, t = this.getAdjacencyMatrix(), r = Array(e); + for (var i = 0; i < e; i++) + r[i] = Array(e), r[i].fill(1 / 0); + for (var i = 0; i < e; i++) + for (var s = 0; s < e; s++) + t[i][s] === 1 && (r[i][s] = 1); + for (var a = 0; a < e; a++) + for (var i = 0; i < e; i++) + for (var s = 0; s < e; s++) + r[i][s] > r[i][a] + r[a][s] && (r[i][s] = r[i][a] + r[a][s]); + return r; + } + /** + * Get the distance matrix of a subgraph. + * + * @param {Number[]} vertexIds An array containing the vertex ids contained within the subgraph. + * @returns {Array[]} The distance matrix of the subgraph. + */ + getSubgraphDistanceMatrix(e) { + let t = e.length, r = this.getSubgraphAdjacencyMatrix(e), i = Array(t); + for (var s = 0; s < t; s++) + i[s] = Array(t), i[s].fill(1 / 0); + for (var s = 0; s < t; s++) + for (var a = 0; a < t; a++) + r[s][a] === 1 && (i[s][a] = 1); + for (var n = 0; n < t; n++) + for (var s = 0; s < t; s++) + for (var a = 0; a < t; a++) + i[s][a] > i[s][n] + i[n][a] && (i[s][a] = i[s][n] + i[n][a]); + return i; + } + /** + * Get the adjacency list of the graph. + * + * @returns {Array[]} The adjancency list of the graph. + */ + getAdjacencyList() { + let e = this.vertices.length, t = Array(e); + for (var r = 0; r < e; r++) { + t[r] = []; + for (var i = 0; i < e; i++) + r !== i && this.hasEdge(this.vertices[r].id, this.vertices[i].id) && t[r].push(i); + } + return t; + } + /** + * Get the adjacency list of a subgraph. + * + * @param {Number[]} vertexIds An array containing the vertex ids contained within the subgraph. + * @returns {Array[]} The adjancency list of the subgraph. + */ + getSubgraphAdjacencyList(e) { + let t = e.length, r = Array(t); + for (var i = 0; i < t; i++) { + r[i] = Array(); + for (var s = 0; s < t; s++) + i !== s && this.hasEdge(e[i], e[s]) && r[i].push(s); + } + return r; + } + /** + * Returns an array containing the edge ids of bridges. A bridge splits the graph into multiple components when removed. + * + * @returns {Number[]} An array containing the edge ids of the bridges. + */ + getBridges() { + let e = this.vertices.length, t = new Array(e), r = new Array(e), i = new Array(e), s = new Array(e), a = this.getAdjacencyList(), n = Array(); + t.fill(!1), s.fill(null), this._time = 0; + for (var h = 0; h < e; h++) + t[h] || this._bridgeDfs(h, t, r, i, s, a, n); + return n; + } + /** + * Traverses the graph in breadth-first order. + * + * @param {Number} startVertexId The id of the starting vertex. + * @param {Function} callback The callback function to be called on every vertex. + */ + traverseBF(e, t) { + let r = this.vertices.length, i = new Array(r); + i.fill(!1); + for (var s = [e]; s.length > 0; ) { + let n = s.shift(), h = this.vertices[n]; + t(h); + for (var a = 0; a < h.neighbours.length; a++) { + let l = h.neighbours[a]; + i[l] || (i[l] = !0, s.push(l)); + } + } + } + /** + * Get the depth of a subtree in the direction opposite to the vertex specified as the parent vertex. + * + * @param {Number} vertexId A vertex id. + * @param {Number} parentVertexId The id of a neighbouring vertex. + * @returns {Number} The depth of the sub-tree. + */ + getTreeDepth(e, t) { + if (e === null || t === null) + return 0; + let r = this.vertices[e].getSpanningTreeNeighbours(t), i = 0; + for (var s = 0; s < r.length; s++) { + let a = r[s], n = this.getTreeDepth(a, e); + n > i && (i = n); + } + return i + 1; + } + /** + * Traverse a sub-tree in the graph. + * + * @param {Number} vertexId A vertex id. + * @param {Number} parentVertexId A neighbouring vertex. + * @param {Function} callback The callback function that is called with each visited as an argument. + * @param {Number} [maxDepth=999999] The maximum depth of the recursion. + * @param {Boolean} [ignoreFirst=false] Whether or not to ignore the starting vertex supplied as vertexId in the callback. + * @param {Number} [depth=1] The current depth in the tree. + * @param {Uint8Array} [visited=null] An array holding a flag on whether or not a node has been visited. + */ + traverseTree(e, t, r, i = 999999, s = !1, a = 1, n = null) { + if (n === null && (n = new Uint8Array(this.vertices.length)), a > i + 1 || n[e] === 1) + return; + n[e] = 1; + let h = this.vertices[e], l = h.getNeighbours(t); + (!s || a > 1) && r(h); + for (var c = 0; c < l.length; c++) + this.traverseTree(l[c], e, r, i, s, a + 1, n); + } + /** + * Positiones the (sub)graph using Kamada and Kawais algorithm for drawing general undirected graphs. https://pdfs.semanticscholar.org/b8d3/bca50ccc573c5cb99f7d201e8acce6618f04.pdf + * There are undocumented layout parameters. They are undocumented for a reason, so be very careful. + * + * @param {Number[]} vertexIds An array containing vertexIds to be placed using the force based layout. + * @param {Vector2} center The center of the layout. + * @param {Number} startVertexId A vertex id. Should be the starting vertex - e.g. the first to be positioned and connected to a previously place vertex. + * @param {Ring} ring The bridged ring associated with this force-based layout. + */ + kkLayout(e, t, r, i, s, a = 0.1, n = 0.1, h = 2e3, l = 50, c = 1e9) { + let u = s; + for (var g = e.length; g--; ) + var m = this.vertices[e[g]].neighbours.length; + let _ = this.getSubgraphDistanceMatrix(e), v = e.length, N = Ba.polyCircumradius(500, v), B = Ba.centralAngle(v), x = 0, L = new Float32Array(v), k = new Float32Array(v), z = Array(v); + for (g = v; g--; ) { + let J = this.vertices[e[g]]; + J.positioned ? (L[g] = J.position.x, k[g] = J.position.y) : (L[g] = t.x + Math.cos(x) * N, k[g] = t.y + Math.sin(x) * N), z[g] = J.positioned, x += B; + } + let D = Array(v); + for (g = v; g--; ) { + D[g] = new Array(v); + for (var m = v; m--; ) + D[g][m] = s * _[g][m]; + } + let Y = Array(v); + for (g = v; g--; ) { + Y[g] = Array(v); + for (var m = v; m--; ) + Y[g][m] = u * Math.pow(_[g][m], -2); + } + let O = Array(v), Z = new Float32Array(v), j = new Float32Array(v); + for (g = v; g--; ) + O[g] = Array(v); + g = v; + let q, se, ye, ke, xe, we, Ee; + for (; g--; ) { + q = L[g], se = k[g], ye = 0, ke = 0; + let J = v; + for (; J--; ) + g !== J && (xe = L[J], we = k[J], Ee = 1 / Math.sqrt((q - xe) * (q - xe) + (se - we) * (se - we)), O[g][J] = [ + Y[g][J] * (q - xe - D[g][J] * (q - xe) * Ee), + Y[g][J] * (se - we - D[g][J] * (se - we) * Ee) + ], O[J][g] = O[g][J], ye += O[g][J][0], ke += O[g][J][1]); + Z[g] = ye, j[g] = ke; + } + let Qe = function(J) { + return [Z[J] * Z[J] + j[J] * j[J], Z[J], j[J]]; + }, Ce = function() { + let J = 0, Te = 0, et = 0, Ie = 0; + for (g = v; g--; ) { + let [Ye, Ue, Ge] = Qe(g); + Ye > J && z[g] === !1 && (J = Ye, Te = g, et = Ue, Ie = Ge); + } + return [Te, J, et, Ie]; + }, Ae = function(J, Te, et) { + let Ie = 0, Ye = 0, Ue = 0, Ge = L[J], De = k[J], Ze = D[J], He = Y[J]; + for (g = v; g--; ) { + if (g === J) + continue; + let Ft = L[g], _t = k[g], zt = Ze[g], Gt = He[g], Ut = (Ge - Ft) * (Ge - Ft), Zt = 1 / Math.pow(Ut + (De - _t) * (De - _t), 1.5); + Ie += Gt * (1 - zt * (De - _t) * (De - _t) * Zt), Ye += Gt * (1 - zt * Ut * Zt), Ue += Gt * (zt * (Ge - Ft) * (De - _t) * Zt); + } + Ie === 0 && (Ie = 0.1), Ye === 0 && (Ye = 0.1), Ue === 0 && (Ue = 0.1); + let We = Te / Ie + et / Ue; + We /= Ue / Ie - Ye / Ue; + let Le = -(Ue * We + Te) / Ie; + L[J] += Le, k[J] += We; + let qe = O[J]; + Te = 0, et = 0, Ge = L[J], De = k[J]; + let Lt, yt, Vt, Xt, Yt; + for (g = v; g--; ) + J !== g && (Lt = L[g], yt = k[g], Vt = qe[g][0], Xt = qe[g][1], Yt = 1 / Math.sqrt((Ge - Lt) * (Ge - Lt) + (De - yt) * (De - yt)), Le = He[g] * (Ge - Lt - Ze[g] * (Ge - Lt) * Yt), We = He[g] * (De - yt - Ze[g] * (De - yt) * Yt), qe[g] = [Le, We], Te += Le, et += We, Z[g] += Le - Vt, j[g] += We - Xt); + Z[J] = Te, j[J] = et; + }, Be = 0, st = 0, It = 0, wt = 0, K = 0, Ot = 0; + for (; c > a && h > K; ) + for (K++, [Be, c, st, It] = Ce(), wt = c, Ot = 0; wt > n && l > Ot; ) + Ot++, Ae(Be, st, It), [wt, st, It] = Qe(Be); + for (g = v; g--; ) { + let J = e[g], Te = this.vertices[J]; + Te.position.x = L[g], Te.position.y = k[g], Te.positioned = !0, Te.forcePositioned = !0; + } + } + /** + * PRIVATE FUNCTION used by getBridges(). + */ + _bridgeDfs(e, t, r, i, s, a, n) { + t[e] = !0, r[e] = i[e] = ++this._time; + for (var h = 0; h < a[e].length; h++) { + let l = a[e][h]; + t[l] ? l !== s[e] && (i[e] = Math.min(i[e], r[l])) : (s[l] = e, this._bridgeDfs(l, t, r, i, s, a, n), i[e] = Math.min(i[e], i[l]), i[l] > r[e] && n.push([e, l])); + } + } + /** + * Returns the connected components of the graph. + * + * @param {Array[]} adjacencyMatrix An adjacency matrix. + * @returns {Set[]} Connected components as sets. + */ + static getConnectedComponents(e) { + let t = e.length, r = new Array(t), i = new Array(); + r.fill(!1); + for (var s = 0; s < t; s++) + if (!r[s]) { + let a = Array(); + r[s] = !0, a.push(s), Ur._ccGetDfs(s, r, e, a), a.length > 1 && i.push(a); + } + return i; + } + /** + * Returns the number of connected components for the graph. + * + * @param {Array[]} adjacencyMatrix An adjacency matrix. + * @returns {Number} The number of connected components of the supplied graph. + */ + static getConnectedComponentCount(e) { + let t = e.length, r = new Array(t), i = 0; + r.fill(!1); + for (var s = 0; s < t; s++) + r[s] || (r[s] = !0, i++, Ur._ccCountDfs(s, r, e)); + return i; + } + /** + * PRIVATE FUNCTION used by getConnectedComponentCount(). + */ + static _ccCountDfs(e, t, r) { + for (var i = 0; i < r[e].length; i++) + !r[e][i] || t[i] || e === i || (t[i] = !0, Ur._ccCountDfs(i, t, r)); + } + /** + * PRIVATE FUNCTION used by getConnectedComponents(). + */ + static _ccGetDfs(e, t, r, i) { + for (var s = 0; s < r[e].length; s++) + !r[e][s] || t[s] || e === s || (t[s] = !0, i.push(s), Ur._ccGetDfs(s, t, r, i)); + } +}; +var vl = dg; +const pg = vl; +let vg = class gt { + /** + * Returns an array containing arrays, each representing a ring from the smallest set of smallest rings in the graph. + * + * @param {Graph} graph A Graph object. + * @param {Boolean} [experimental=false] Whether or not to use experimental SSSR. + * @returns {Array[]} An array containing arrays, each representing a ring from the smallest set of smallest rings in the group. + */ + static getRings(e, t = !1) { + let r = e.getComponentsAdjacencyMatrix(); + if (r.length === 0) + return null; + let i = pg.getConnectedComponents(r), s = Array(); + for (var a = 0; a < i.length; a++) { + let l = i[a], c = e.getSubgraphAdjacencyMatrix([...l]), u = new Uint16Array(c.length), g = new Uint16Array(c.length); + for (var n = 0; n < c.length; n++) { + g[n] = 0, u[n] = 0; + for (var h = 0; h < c[n].length; h++) + u[n] += c[n][h]; + } + let m = 0; + for (var n = 0; n < c.length; n++) + for (var h = n + 1; h < c.length; h++) + m += c[n][h]; + let _ = m - c.length + 1, v = !0; + for (var n = 0; n < u.length; n++) + u[n] !== 3 && (v = !1); + if (v && (_ = 2 + m - c.length), _ === 1) { + s.push([...l]); + continue; + } + t && (_ = 999); + let { d: N, pe: B, pe_prime: x } = gt.getPathIncludedDistanceMatrices(c), L = gt.getRingCandidates(N, B, x), k = gt.getSSSR(L, N, c, B, x, u, g, _); + for (var n = 0; n < k.length; n++) { + let D = Array(k[n].size), Y = 0; + for (let O of k[n]) + D[Y++] = l[O]; + s.push(D); + } + } + return s; + } + /** + * Creates a printable string from a matrix (2D array). + * + * @param {Array[]} matrix A 2D array. + * @returns {String} A string representing the matrix. + */ + static matrixToString(e) { + let t = ""; + for (var r = 0; r < e.length; r++) { + for (var i = 0; i < e[r].length; i++) + t += e[r][i] + " "; + t += ` +`; + } + return t; + } + /** + * Returnes the two path-included distance matrices used to find the sssr. + * + * @param {Array[]} adjacencyMatrix An adjacency matrix. + * @returns {Object} The path-included distance matrices. { p1, p2 } + */ + static getPathIncludedDistanceMatrices(e) { + let t = e.length, r = Array(t), i = Array(t), s = Array(t); + for (var a = 0, n = 0, h = 0, l = t; l--; ) { + r[l] = Array(t), i[l] = Array(t), s[l] = Array(t); + for (var u = t; u--; ) + r[l][u] = l === u || e[l][u] === 1 ? e[l][u] : Number.POSITIVE_INFINITY, r[l][u] === 1 ? i[l][u] = [[[l, u]]] : i[l][u] = Array(), s[l][u] = Array(); + } + for (var c = t, u; c--; ) + for (l = t; l--; ) + for (u = t; u--; ) { + const g = r[l][u], m = r[l][c] + r[c][u]; + if (g > m) { + var a, n, h; + if (g === m + 1) + for (s[l][u] = [i[l][u].length], a = i[l][u].length; a--; ) + for (s[l][u][a] = [i[l][u][a].length], n = i[l][u][a].length; n--; ) + for (s[l][u][a][n] = [i[l][u][a][n].length], h = i[l][u][a][n].length; h--; ) + s[l][u][a][n][h] = [i[l][u][a][n][0], i[l][u][a][n][1]]; + else + s[l][u] = Array(); + for (r[l][u] = m, i[l][u] = [[]], a = i[l][c][0].length; a--; ) + i[l][u][0].push(i[l][c][0][a]); + for (a = i[c][u][0].length; a--; ) + i[l][u][0].push(i[c][u][0][a]); + } else if (g === m) { + if (i[l][c].length && i[c][u].length) { + var a; + if (i[l][u].length) { + let v = Array(); + for (a = i[l][c][0].length; a--; ) + v.push(i[l][c][0][a]); + for (a = i[c][u][0].length; a--; ) + v.push(i[c][u][0][a]); + i[l][u].push(v); + } else { + let v = Array(); + for (a = i[l][c][0].length; a--; ) + v.push(i[l][c][0][a]); + for (a = i[c][u][0].length; a--; ) + v.push(i[c][u][0][a]); + i[l][u][0] = v; + } + } + } else if (g === m - 1) { + var a; + if (s[l][u].length) { + let v = Array(); + for (a = i[l][c][0].length; a--; ) + v.push(i[l][c][0][a]); + for (a = i[c][u][0].length; a--; ) + v.push(i[c][u][0][a]); + s[l][u].push(v); + } else { + let v = Array(); + for (a = i[l][c][0].length; a--; ) + v.push(i[l][c][0][a]); + for (a = i[c][u][0].length; a--; ) + v.push(i[c][u][0][a]); + s[l][u][0] = v; + } + } + } + return { + d: r, + pe: i, + pe_prime: s + }; + } + /** + * Get the ring candidates from the path-included distance matrices. + * + * @param {Array[]} d The distance matrix. + * @param {Array[]} pe A matrix containing the shortest paths. + * @param {Array[]} pe_prime A matrix containing the shortest paths + one vertex. + * @returns {Array[]} The ring candidates. + */ + static getRingCandidates(e, t, r) { + let i = e.length, s = Array(), a = 0; + for (let n = 0; n < i; n++) + for (let h = 0; h < i; h++) + e[n][h] === 0 || t[n][h].length === 1 && r[n][h] === 0 || (r[n][h].length !== 0 ? a = 2 * (e[n][h] + 0.5) : a = 2 * e[n][h], a !== 1 / 0 && s.push([a, t[n][h], r[n][h]])); + return s.sort(function(n, h) { + return n[0] - h[0]; + }), s; + } + /** + * Searches the candidates for the smallest set of smallest rings. + * + * @param {Array[]} c The candidates. + * @param {Array[]} d The distance matrix. + * @param {Array[]} adjacencyMatrix An adjacency matrix. + * @param {Array[]} pe A matrix containing the shortest paths. + * @param {Array[]} pe_prime A matrix containing the shortest paths + one vertex. + * @param {Uint16Array} arrBondCount A matrix containing the bond count of each vertex. + * @param {Uint16Array} arrRingCount A matrix containing the number of rings associated with each vertex. + * @param {Number} nsssr The theoretical number of rings in the graph. + * @returns {Set[]} The smallest set of smallest rings. + */ + static getSSSR(e, t, r, i, s, a, n, h) { + let l = Array(), c = Array(); + for (let g = 0; g < e.length; g++) + if (e[g][0] % 2 !== 0) + for (let m = 0; m < e[g][2].length; m++) { + let _ = e[g][1][0].concat(e[g][2][m]); + for (var u = 0; u < _.length; u++) + _[u][0].constructor === Array && (_[u] = _[u][0]); + let v = gt.bondsToAtoms(_); + if (gt.getBondCount(v, r) === v.size && !gt.pathSetsContain(l, v, _, c, a, n) && (l.push(v), c = c.concat(_)), l.length > h) + return l; + } + else + for (let m = 0; m < e[g][1].length - 1; m++) { + let _ = e[g][1][m].concat(e[g][1][m + 1]); + for (var u = 0; u < _.length; u++) + _[u][0].constructor === Array && (_[u] = _[u][0]); + let v = gt.bondsToAtoms(_); + if (gt.getBondCount(v, r) === v.size && !gt.pathSetsContain(l, v, _, c, a, n) && (l.push(v), c = c.concat(_)), l.length > h) + return l; + } + return l; + } + /** + * Returns the number of edges in a graph defined by an adjacency matrix. + * + * @param {Array[]} adjacencyMatrix An adjacency matrix. + * @returns {Number} The number of edges in the graph defined by the adjacency matrix. + */ + static getEdgeCount(e) { + let t = 0, r = e.length; + for (var i = r - 1; i--; ) + for (var s = r; s--; ) + e[i][s] === 1 && t++; + return t; + } + /** + * Returns an edge list constructed form an adjacency matrix. + * + * @param {Array[]} adjacencyMatrix An adjacency matrix. + * @returns {Array[]} An edge list. E.g. [ [ 0, 1 ], ..., [ 16, 2 ] ] + */ + static getEdgeList(e) { + let t = e.length, r = Array(); + for (var i = t - 1; i--; ) + for (var s = t; s--; ) + e[i][s] === 1 && r.push([i, s]); + return r; + } + /** + * Return a set of vertex indices contained in an array of bonds. + * + * @param {Array} bonds An array of bonds. A bond is defined as [ sourceVertexId, targetVertexId ]. + * @returns {Set} An array of vertices. + */ + static bondsToAtoms(e) { + let t = /* @__PURE__ */ new Set(); + for (var r = e.length; r--; ) + t.add(e[r][0]), t.add(e[r][1]); + return t; + } + /** + * Returns the number of bonds within a set of atoms. + * + * @param {Set} atoms An array of atom ids. + * @param {Array[]} adjacencyMatrix An adjacency matrix. + * @returns {Number} The number of bonds in a set of atoms. + */ + static getBondCount(e, t) { + let r = 0; + for (let i of e) + for (let s of e) + i !== s && (r += t[i][s]); + return r / 2; + } + /** + * Checks whether or not a given path already exists in an array of paths. + * + * @param {Set[]} pathSets An array of sets each representing a path. + * @param {Set} pathSet A set representing a path. + * @param {Array[]} bonds The bonds associated with the current path. + * @param {Array[]} allBonds All bonds currently associated with rings in the SSSR set. + * @param {Uint16Array} arrBondCount A matrix containing the bond count of each vertex. + * @param {Uint16Array} arrRingCount A matrix containing the number of rings associated with each vertex. + * @returns {Boolean} A boolean indicating whether or not a give path is contained within a set. + */ + static pathSetsContain(e, t, r, i, s, a) { + for (var n = e.length; n--; ) { + if (gt.isSupersetOf(t, e[n])) + return !0; + if (e[n].size === t.size && gt.areSetsEqual(e[n], t)) + return !0; + } + let h = 0, l = !1; + for (n = r.length; n--; ) + for (var c = i.length; c--; ) + (r[n][0] === i[c][0] && r[n][1] === i[c][1] || r[n][1] === i[c][0] && r[n][0] === i[c][1]) && h++, h === r.length && (l = !0); + let u = !1; + if (l) { + for (let g of t) + if (a[g] < s[g]) { + u = !0; + break; + } + } + if (l && !u) + return !0; + for (let g of t) + a[g]++; + return !1; + } + /** + * Checks whether or not two sets are equal (contain the same elements). + * + * @param {Set} setA A set. + * @param {Set} setB A set. + * @returns {Boolean} A boolean indicating whether or not the two sets are equal. + */ + static areSetsEqual(e, t) { + if (e.size !== t.size) + return !1; + for (let r of e) + if (!t.has(r)) + return !1; + return !0; + } + /** + * Checks whether or not a set (setA) is a superset of another set (setB). + * + * @param {Set} setA A set. + * @param {Set} setB A set. + * @returns {Boolean} A boolean indicating whether or not setB is a superset of setA. + */ + static isSupersetOf(e, t) { + for (var r of t) + if (!e.has(r)) + return !1; + return !0; + } +}; +var mg = vg; +let bg = class { + constructor(e, t) { + this.colors = e, this.theme = this.colors[t]; + } + /** + * Returns the hex code of a color associated with a key from the current theme. + * + * @param {String} key The color key in the theme (e.g. C, N, BACKGROUND, ...). + * @returns {String} A color hex value. + */ + getColor(e) { + return e && (e = e.toUpperCase(), e in this.theme) ? this.theme[e] : this.theme.C; + } + /** + * Sets the theme to the specified string if it exists. If it does not, this + * does nothing. + * + * @param {String} theme the name of the theme to switch to + */ + setTheme(e) { + this.colors.hasOwnProperty(e) && (this.theme = this.colors[e]); + } +}; +var Yn = bg; +let wg = class { + /** + * A helper method to extend the default options with user supplied ones. + */ + static extend() { + let e = this, t = {}, r = !1, i = 0, s = arguments.length; + Object.prototype.toString.call(arguments[0]) === "[object Boolean]" && (r = arguments[0], i++); + let a = function(n) { + for (var h in n) + Object.prototype.hasOwnProperty.call(n, h) && (r && Object.prototype.toString.call(n[h]) === "[object Object]" ? t[h] = e.extend(!0, t[h], n[h]) : t[h] = n[h]); + }; + for (; i < s; i++) { + let n = arguments[i]; + a(n); + } + return t; + } +}; +var Gn = wg; +const Se = Kr, Dt = Zr, re = ar, Me = Xn; +Or(); +const yg = pl, Ci = Li(), Da = jr(), Ai = cl(), _g = fg, Pa = vl, Sg = mg, Cg = Yn, Ag = Gn; +let Ng = class { + /** + * The constructor for the class SmilesDrawer. + * + * @param {Object} options An object containing custom values for different options. It is merged with the default options. + */ + constructor(e) { + this.graph = null, this.doubleBondConfigCount = 0, this.doubleBondConfig = null, this.ringIdCounter = 0, this.ringConnectionIdCounter = 0, this.canvasWrapper = null, this.totalOverlapScore = 0, this.defaultOptions = { + width: 500, + height: 500, + scale: 0, + bondThickness: 1, + bondLength: 30, + shortBondLength: 0.8, + bondSpacing: 0.17 * 30, + atomVisualization: "default", + isomeric: !0, + debug: !1, + terminalCarbons: !1, + explicitHydrogens: !0, + overlapSensitivity: 0.42, + overlapResolutionIterations: 1, + compactDrawing: !0, + fontFamily: "Arial, Helvetica, sans-serif", + fontSizeLarge: 11, + fontSizeSmall: 3, + padding: 10, + experimentalSSSR: !1, + kkThreshold: 0.1, + kkInnerThreshold: 0.1, + kkMaxIteration: 2e4, + kkMaxInnerIteration: 50, + kkMaxEnergy: 1e9, + weights: { + colormap: null, + additionalPadding: 20, + sigma: 10, + interval: 0, + opacity: 1 + }, + themes: { + dark: { + C: "#fff", + O: "#e74c3c", + N: "#3498db", + F: "#27ae60", + CL: "#16a085", + BR: "#d35400", + I: "#8e44ad", + P: "#d35400", + S: "#f1c40f", + B: "#e67e22", + SI: "#e67e22", + H: "#aaa", + BACKGROUND: "#141414" + }, + light: { + C: "#222", + O: "#e74c3c", + N: "#3498db", + F: "#27ae60", + CL: "#16a085", + BR: "#d35400", + I: "#8e44ad", + P: "#d35400", + S: "#f1c40f", + B: "#e67e22", + SI: "#e67e22", + H: "#666", + BACKGROUND: "#fff" + }, + oldschool: { + C: "#000", + O: "#000", + N: "#000", + F: "#000", + CL: "#000", + BR: "#000", + I: "#000", + P: "#000", + S: "#000", + B: "#000", + SI: "#000", + H: "#000", + BACKGROUND: "#fff" + }, + solarized: { + C: "#586e75", + O: "#dc322f", + N: "#268bd2", + F: "#859900", + CL: "#16a085", + BR: "#cb4b16", + I: "#6c71c4", + P: "#d33682", + S: "#b58900", + B: "#2aa198", + SI: "#2aa198", + H: "#657b83", + BACKGROUND: "#fff" + }, + "solarized-dark": { + C: "#93a1a1", + O: "#dc322f", + N: "#268bd2", + F: "#859900", + CL: "#16a085", + BR: "#cb4b16", + I: "#6c71c4", + P: "#d33682", + S: "#b58900", + B: "#2aa198", + SI: "#2aa198", + H: "#839496", + BACKGROUND: "#fff" + }, + matrix: { + C: "#678c61", + O: "#2fc079", + N: "#4f7e7e", + F: "#90d762", + CL: "#82d967", + BR: "#23755a", + I: "#409931", + P: "#c1ff8a", + S: "#faff00", + B: "#50b45a", + SI: "#409931", + H: "#426644", + BACKGROUND: "#fff" + }, + github: { + C: "#24292f", + O: "#cf222e", + N: "#0969da", + F: "#2da44e", + CL: "#6fdd8b", + BR: "#bc4c00", + I: "#8250df", + P: "#bf3989", + S: "#d4a72c", + B: "#fb8f44", + SI: "#bc4c00", + H: "#57606a", + BACKGROUND: "#fff" + }, + carbon: { + C: "#161616", + O: "#da1e28", + N: "#0f62fe", + F: "#198038", + CL: "#007d79", + BR: "#fa4d56", + I: "#8a3ffc", + P: "#ff832b", + S: "#f1c21b", + B: "#8a3800", + SI: "#e67e22", + H: "#525252", + BACKGROUND: "#fff" + }, + cyberpunk: { + C: "#ea00d9", + O: "#ff3131", + N: "#0abdc6", + F: "#00ff9f", + CL: "#00fe00", + BR: "#fe9f20", + I: "#ff00ff", + P: "#fe7f00", + S: "#fcee0c", + B: "#ff00ff", + SI: "#ffffff", + H: "#913cb1", + BACKGROUND: "#fff" + }, + gruvbox: { + C: "#665c54", + O: "#cc241d", + N: "#458588", + F: "#98971a", + CL: "#79740e", + BR: "#d65d0e", + I: "#b16286", + P: "#af3a03", + S: "#d79921", + B: "#689d6a", + SI: "#427b58", + H: "#7c6f64", + BACKGROUND: "#fbf1c7" + }, + "gruvbox-dark": { + C: "#ebdbb2", + O: "#cc241d", + N: "#458588", + F: "#98971a", + CL: "#b8bb26", + BR: "#d65d0e", + I: "#b16286", + P: "#fe8019", + S: "#d79921", + B: "#8ec07c", + SI: "#83a598", + H: "#bdae93", + BACKGROUND: "#282828" + }, + custom: { + C: "#222", + O: "#e74c3c", + N: "#3498db", + F: "#27ae60", + CL: "#16a085", + BR: "#d35400", + I: "#8e44ad", + P: "#d35400", + S: "#f1c40f", + B: "#e67e22", + SI: "#e67e22", + H: "#666", + BACKGROUND: "#fff" + } + } + }, this.opts = Ag.extend(!0, this.defaultOptions, e), this.opts.halfBondSpacing = this.opts.bondSpacing / 2, this.opts.bondLengthSq = this.opts.bondLength * this.opts.bondLength, this.opts.halfFontSizeLarge = this.opts.fontSizeLarge / 2, this.opts.quarterFontSizeLarge = this.opts.fontSizeLarge / 4, this.opts.fifthFontSizeSmall = this.opts.fontSizeSmall / 5, this.theme = this.opts.themes.dark; + } + /** + * Draws the parsed smiles data to a canvas element. + * + * @param {Object} data The tree returned by the smiles parser. + * @param {(String|HTMLCanvasElement)} target The id of the HTML canvas element the structure is drawn to - or the element itself. + * @param {String} themeName='dark' The name of the theme to use. Built-in themes are 'light' and 'dark'. + * @param {Boolean} infoOnly=false Only output info on the molecule without drawing anything to the canvas. + */ + draw(e, t, r = "light", i = !1) { + this.initDraw(e, r, i), this.infoOnly || (this.themeManager = new Cg(this.opts.themes, r), this.canvasWrapper = new _g(t, this.themeManager, this.opts)), i || (this.processGraph(), this.canvasWrapper.scale(this.graph.vertices), this.drawEdges(this.opts.debug), this.drawVertices(this.opts.debug), this.canvasWrapper.reset(), this.opts.debug && (console.log(this.graph), console.log(this.rings), console.log(this.ringConnections))); + } + /** + * Returns the number of rings this edge is a part of. + * + * @param {Number} edgeId The id of an edge. + * @returns {Number} The number of rings the provided edge is part of. + */ + edgeRingCount(e) { + let t = this.graph.edges[e], r = this.graph.vertices[t.sourceId], i = this.graph.vertices[t.targetId]; + return Math.min(r.value.rings.length, i.value.rings.length); + } + /** + * Returns an array containing the bridged rings associated with this molecule. + * + * @returns {Ring[]} An array containing all bridged rings associated with this molecule. + */ + getBridgedRings() { + let e = Array(); + for (var t = 0; t < this.rings.length; t++) + this.rings[t].isBridged && e.push(this.rings[t]); + return e; + } + /** + * Returns an array containing all fused rings associated with this molecule. + * + * @returns {Ring[]} An array containing all fused rings associated with this molecule. + */ + getFusedRings() { + let e = Array(); + for (var t = 0; t < this.rings.length; t++) + this.rings[t].isFused && e.push(this.rings[t]); + return e; + } + /** + * Returns an array containing all spiros associated with this molecule. + * + * @returns {Ring[]} An array containing all spiros associated with this molecule. + */ + getSpiros() { + let e = Array(); + for (var t = 0; t < this.rings.length; t++) + this.rings[t].isSpiro && e.push(this.rings[t]); + return e; + } + /** + * Returns a string containing a semicolon and new-line separated list of ring properties: Id; Members Count; Neighbours Count; IsSpiro; IsFused; IsBridged; Ring Count (subrings of bridged rings) + * + * @returns {String} A string as described in the method description. + */ + printRingInfo() { + let e = ""; + for (var t = 0; t < this.rings.length; t++) { + const r = this.rings[t]; + e += r.id + ";", e += r.members.length + ";", e += r.neighbours.length + ";", e += r.isSpiro ? "true;" : "false;", e += r.isFused ? "true;" : "false;", e += r.isBridged ? "true;" : "false;", e += r.rings.length + ";", e += ` +`; + } + return e; + } + /** + * Rotates the drawing to make the widest dimension horizontal. + */ + rotateDrawing() { + let e = 0, t = 0, r = 0; + for (var i = 0; i < this.graph.vertices.length; i++) { + let n = this.graph.vertices[i]; + if (n.value.isDrawn) + for (var s = i + 1; s < this.graph.vertices.length; s++) { + let h = this.graph.vertices[s]; + if (!h.value.isDrawn) + continue; + let l = n.position.distanceSq(h.position); + l > r && (r = l, e = i, t = s); + } + } + let a = -re.subtract(this.graph.vertices[e].position, this.graph.vertices[t].position).angle(); + if (!isNaN(a)) { + let n = a % 0.523599; + n < 0.2617995 ? a = a - n : a += 0.523599 - n; + for (var i = 0; i < this.graph.vertices.length; i++) + i !== t && this.graph.vertices[i].position.rotateAround(a, this.graph.vertices[t].position); + for (var i = 0; i < this.rings.length; i++) + this.rings[i].center.rotateAround(a, this.graph.vertices[t].position); + } + } + /** + * Returns the total overlap score of the current molecule. + * + * @returns {Number} The overlap score. + */ + getTotalOverlapScore() { + return this.totalOverlapScore; + } + /** + * Returns the ring count of the current molecule. + * + * @returns {Number} The ring count. + */ + getRingCount() { + return this.rings.length; + } + /** + * Checks whether or not the current molecule a bridged ring. + * + * @returns {Boolean} A boolean indicating whether or not the current molecule a bridged ring. + */ + hasBridgedRing() { + return this.bridgedRing; + } + /** + * Returns the number of heavy atoms (non-hydrogen) in the current molecule. + * + * @returns {Number} The heavy atom count. + */ + getHeavyAtomCount() { + let e = 0; + for (var t = 0; t < this.graph.vertices.length; t++) + this.graph.vertices[t].value.element !== "H" && e++; + return e; + } + /** + * Returns the molecular formula of the loaded molecule as a string. + * + * @returns {String} The molecular formula. + */ + getMolecularFormula(e = null) { + let t = "", r = /* @__PURE__ */ new Map(), i = e === null ? this.graph : new Pa(e, this.opts.isomeric); + for (var s = 0; s < i.vertices.length; s++) { + let n = i.vertices[s].value; + if (r.has(n.element) ? r.set(n.element, r.get(n.element) + 1) : r.set(n.element, 1), n.bracket && !n.bracket.chirality && (r.has("H") ? r.set("H", r.get("H") + n.bracket.hcount) : r.set("H", n.bracket.hcount)), !n.bracket) { + let h = Ci.maxBonds[n.element] - n.bondCount; + n.isPartOfAromaticRing && h--, r.has("H") ? r.set("H", r.get("H") + h) : r.set("H", h); + } + } + if (r.has("C")) { + let n = r.get("C"); + t += "C" + (n > 1 ? n : ""), r.delete("C"); + } + if (r.has("H")) { + let n = r.get("H"); + t += "H" + (n > 1 ? n : ""), r.delete("H"); + } + return Object.keys(Ci.atomicNumbers).sort().map((n) => { + if (r.has(n)) { + let h = r.get(n); + t += n + (h > 1 ? h : ""); + } + }), t; + } + /** + * Returns the type of the ringbond (e.g. '=' for a double bond). The ringbond represents the break in a ring introduced when creating the MST. If the two vertices supplied as arguments are not part of a common ringbond, the method returns null. + * + * @param {Vertex} vertexA A vertex. + * @param {Vertex} vertexB A vertex. + * @returns {(String|null)} Returns the ringbond type or null, if the two supplied vertices are not connected by a ringbond. + */ + getRingbondType(e, t) { + if (e.value.getRingbondCount() < 1 || t.value.getRingbondCount() < 1) + return null; + for (var r = 0; r < e.value.ringbonds.length; r++) + for (var i = 0; i < t.value.ringbonds.length; i++) + if (e.value.ringbonds[r].id === t.value.ringbonds[i].id) + return e.value.ringbonds[r].bondType === "-" ? t.value.ringbonds[i].bond : e.value.ringbonds[r].bond; + return null; + } + initDraw(e, t, r, i) { + this.data = e, this.infoOnly = r, this.ringIdCounter = 0, this.ringConnectionIdCounter = 0, this.graph = new Pa(e, this.opts.isomeric), this.rings = Array(), this.ringConnections = Array(), this.originalRings = Array(), this.originalRingConnections = Array(), this.bridgedRing = !1, this.doubleBondConfigCount = null, this.doubleBondConfig = null, this.highlight_atoms = i, this.initRings(), this.initHydrogens(); + } + processGraph() { + this.position(), this.restoreRingInformation(), this.resolvePrimaryOverlaps(); + let e = this.getOverlapScore(); + this.totalOverlapScore = this.getOverlapScore().total; + for (var t = 0; t < this.opts.overlapResolutionIterations; t++) + for (var r = 0; r < this.graph.edges.length; r++) { + let i = this.graph.edges[r]; + if (this.isEdgeRotatable(i)) { + let s = this.graph.getTreeDepth(i.sourceId, i.targetId), a = this.graph.getTreeDepth(i.targetId, i.sourceId), n = i.targetId, h = i.sourceId; + if (s > a && (n = i.sourceId, h = i.targetId), this.getSubtreeOverlapScore(h, n, e.vertexScores).value > this.opts.overlapSensitivity) { + let c = this.graph.vertices[n], u = this.graph.vertices[h], g = u.getNeighbours(n); + if (g.length === 1) { + let m = this.graph.vertices[g[0]], _ = m.position.getRotateAwayFromAngle(c.position, u.position, Se.toRad(120)); + this.rotateSubtree(m.id, u.id, _, u.position); + let v = this.getOverlapScore().total; + v > this.totalOverlapScore ? this.rotateSubtree(m.id, u.id, -_, u.position) : this.totalOverlapScore = v; + } else if (g.length === 2) { + if (u.value.rings.length !== 0 && c.value.rings.length !== 0) + continue; + let m = this.graph.vertices[g[0]], _ = this.graph.vertices[g[1]]; + if (m.value.rings.length === 1 && _.value.rings.length === 1) { + if (m.value.rings[0] !== _.value.rings[0]) + continue; + } else { + if (m.value.rings.length !== 0 || _.value.rings.length !== 0) + continue; + { + let v = m.position.getRotateAwayFromAngle(c.position, u.position, Se.toRad(120)), N = _.position.getRotateAwayFromAngle(c.position, u.position, Se.toRad(120)); + this.rotateSubtree(m.id, u.id, v, u.position), this.rotateSubtree(_.id, u.id, N, u.position); + let B = this.getOverlapScore().total; + B > this.totalOverlapScore ? (this.rotateSubtree(m.id, u.id, -v, u.position), this.rotateSubtree(_.id, u.id, -N, u.position)) : this.totalOverlapScore = B; + } + } + } + e = this.getOverlapScore(); + } + } + } + this.resolveSecondaryOverlaps(e.scores), this.opts.isomeric && this.annotateStereochemistry(), this.opts.compactDrawing && this.opts.atomVisualization === "default" && this.initPseudoElements(), this.rotateDrawing(); + } + /** + * Initializes rings and ringbonds for the current molecule. + */ + initRings() { + let e = /* @__PURE__ */ new Map(); + for (var t = this.graph.vertices.length - 1; t >= 0; t--) { + let s = this.graph.vertices[t]; + if (s.value.ringbonds.length !== 0) + for (var r = 0; r < s.value.ringbonds.length; r++) { + let a = s.value.ringbonds[r].id, n = s.value.ringbonds[r].bond; + if (!e.has(a)) + e.set(a, [s.id, n]); + else { + let h = s.id, l = e.get(a)[0], c = e.get(a)[1], u = new yg(h, l, 1); + u.setBondType(c || n || "-"); + let g = this.graph.addEdge(u), m = this.graph.vertices[l]; + s.addRingbondChild(l, r), s.value.addNeighbouringElement(m.value.element), m.addRingbondChild(h, r), m.value.addNeighbouringElement(s.value.element), s.edges.push(g), m.edges.push(g), e.delete(a); + } + } + } + let i = Sg.getRings(this.graph, this.opts.experimentalSSSR); + if (i !== null) { + for (var t = 0; t < i.length; t++) { + let a = [...i[t]], n = this.addRing(new Da(a)); + for (var r = 0; r < a.length; r++) + this.graph.vertices[a[r]].value.rings.push(n); + } + for (var t = 0; t < this.rings.length - 1; t++) + for (var r = t + 1; r < this.rings.length; r++) { + let n = this.rings[t], h = this.rings[r], l = new Ai(n, h); + l.vertices.size > 0 && this.addRingConnection(l); + } + for (var t = 0; t < this.rings.length; t++) { + let a = this.rings[t]; + a.neighbours = Ai.getNeighbours(this.ringConnections, a.id); + } + for (var t = 0; t < this.rings.length; t++) { + let a = this.rings[t]; + this.graph.vertices[a.members[0]].value.addAnchoredRing(a.id); + } + for (this.backupRingInformation(); this.rings.length > 0; ) { + let s = -1; + for (var t = 0; t < this.rings.length; t++) { + let l = this.rings[t]; + this.isPartOfBridgedRing(l.id) && !l.isBridged && (s = l.id); + } + if (s === -1) + break; + let a = this.getRing(s), n = this.getBridgedRingRings(a.id); + this.bridgedRing = !0, this.createBridgedRing(n, a.members[0]); + for (var t = 0; t < n.length; t++) + this.removeRing(n[t]); + } + } + } + initHydrogens() { + if (!this.opts.explicitHydrogens) + for (var e = 0; e < this.graph.vertices.length; e++) { + let t = this.graph.vertices[e]; + if (t.value.element !== "H") + continue; + let r = this.graph.vertices[t.neighbours[0]]; + r.value.hasHydrogen = !0, (!r.value.isStereoCenter || r.value.rings.length < 2 && !r.value.bridgedRing || r.value.bridgedRing && r.value.originalRings.length < 2) && (t.value.isDrawn = !1); + } + } + /** + * Returns all rings connected by bridged bonds starting from the ring with the supplied ring id. + * + * @param {Number} ringId A ring id. + * @returns {Number[]} An array containing all ring ids of rings part of a bridged ring system. + */ + getBridgedRingRings(e) { + let t = Array(), r = this, i = function(s) { + let a = r.getRing(s); + t.push(s); + for (var n = 0; n < a.neighbours.length; n++) { + let h = a.neighbours[n]; + t.indexOf(h) === -1 && h !== s && Ai.isBridge(r.ringConnections, r.graph.vertices, s, h) && i(h); + } + }; + return i(e), Dt.unique(t); + } + /** + * Checks whether or not a ring is part of a bridged ring. + * + * @param {Number} ringId A ring id. + * @returns {Boolean} A boolean indicating whether or not the supplied ring (by id) is part of a bridged ring system. + */ + isPartOfBridgedRing(e) { + for (var t = 0; t < this.ringConnections.length; t++) + if (this.ringConnections[t].containsRing(e) && this.ringConnections[t].isBridge(this.graph.vertices)) + return !0; + return !1; + } + /** + * Creates a bridged ring. + * + * @param {Number[]} ringIds An array of ids of rings involved in the bridged ring. + * @param {Number} sourceVertexId The vertex id to start the bridged ring discovery from. + * @returns {Ring} The bridged ring. + */ + createBridgedRing(e, t) { + let r = /* @__PURE__ */ new Set(), i = /* @__PURE__ */ new Set(), s = /* @__PURE__ */ new Set(); + for (var a = 0; a < e.length; a++) { + let u = this.getRing(e[a]); + u.isPartOfBridged = !0; + for (var n = 0; n < u.members.length; n++) + i.add(u.members[n]); + for (var n = 0; n < u.neighbours.length; n++) { + let m = u.neighbours[n]; + e.indexOf(m) === -1 && s.add(u.neighbours[n]); + } + } + let h = /* @__PURE__ */ new Set(); + for (let u of i) { + let g = this.graph.vertices[u], m = Dt.intersection(e, g.value.rings); + g.value.rings.length === 1 || m.length === 1 ? r.add(g.id) : h.add(g.id); + } + Array(); + let l = Array(); + for (let u of h) { + let g = this.graph.vertices[u], m = !1; + for (let _ = 0; _ < g.edges.length; _++) + this.edgeRingCount(g.edges[_]) === 1 && (m = !0); + m ? (g.value.isBridgeNode = !0, r.add(g.id)) : (g.value.isBridge = !0, r.add(g.id)); + } + let c = new Da([...r]); + this.addRing(c), c.isBridged = !0, c.neighbours = [...s]; + for (var a = 0; a < e.length; a++) + c.rings.push(this.getRing(e[a]).clone()); + for (var a = 0; a < c.members.length; a++) + this.graph.vertices[c.members[a]].value.bridgedRing = c.id; + for (var a = 0; a < l.length; a++) { + let g = this.graph.vertices[l[a]]; + g.value.rings = Array(); + } + for (let u of r) { + let g = this.graph.vertices[u]; + g.value.rings = Dt.removeAll(g.value.rings, e), g.value.rings.push(c.id); + } + for (var a = 0; a < e.length; a++) + for (var n = a + 1; n < e.length; n++) + this.removeRingConnectionsBetween(e[a], e[n]); + for (let u of s) { + let g = this.getRingConnections(u, e); + for (var n = 0; n < g.length; n++) + this.getRingConnection(g[n]).updateOther(c.id, u); + this.getRing(u).neighbours.push(c.id); + } + return c; + } + /** + * Checks whether or not two vertices are in the same ring. + * + * @param {Vertex} vertexA A vertex. + * @param {Vertex} vertexB A vertex. + * @returns {Boolean} A boolean indicating whether or not the two vertices are in the same ring. + */ + areVerticesInSameRing(e, t) { + for (var r = 0; r < e.value.rings.length; r++) + for (var i = 0; i < t.value.rings.length; i++) + if (e.value.rings[r] === t.value.rings[i]) + return !0; + return !1; + } + /** + * Returns an array of ring ids shared by both vertices. + * + * @param {Vertex} vertexA A vertex. + * @param {Vertex} vertexB A vertex. + * @returns {Number[]} An array of ids of rings shared by the two vertices. + */ + getCommonRings(e, t) { + let r = Array(); + for (var i = 0; i < e.value.rings.length; i++) + for (var s = 0; s < t.value.rings.length; s++) + e.value.rings[i] == t.value.rings[s] && r.push(e.value.rings[i]); + return r; + } + /** + * Returns the aromatic or largest ring shared by the two vertices. + * + * @param {Vertex} vertexA A vertex. + * @param {Vertex} vertexB A vertex. + * @returns {(Ring|null)} If an aromatic common ring exists, that ring, else the largest (non-aromatic) ring, else null. + */ + getLargestOrAromaticCommonRing(e, t) { + let r = this.getCommonRings(e, t), i = 0, s = null; + for (var a = 0; a < r.length; a++) { + let n = this.getRing(r[a]), h = n.getSize(); + if (n.isBenzeneLike(this.graph.vertices)) + return n; + h > i && (i = h, s = n); + } + return s; + } + /** + * Returns an array of vertices positioned at a specified location. + * + * @param {Vector2} position The position to search for vertices. + * @param {Number} radius The radius within to search. + * @param {Number} excludeVertexId A vertex id to be excluded from the search results. + * @returns {Number[]} An array containing vertex ids in a given location. + */ + getVerticesAt(e, t, r) { + let i = Array(); + for (var s = 0; s < this.graph.vertices.length; s++) { + let a = this.graph.vertices[s]; + if (a.id === r || !a.positioned) + continue; + e.distanceSq(a.position) <= t * t && i.push(a.id); + } + return i; + } + /** + * Returns the closest vertex (connected as well as unconnected). + * + * @param {Vertex} vertex The vertex of which to find the closest other vertex. + * @returns {Vertex} The closest vertex. + */ + getClosestVertex(e) { + let t = 99999, r = null; + for (var i = 0; i < this.graph.vertices.length; i++) { + let s = this.graph.vertices[i]; + if (s.id === e.id) + continue; + let a = e.position.distanceSq(s.position); + a < t && (t = a, r = s); + } + return r; + } + /** + * Add a ring to this representation of a molecule. + * + * @param {Ring} ring A new ring. + * @returns {Number} The ring id of the new ring. + */ + addRing(e) { + return e.id = this.ringIdCounter++, this.rings.push(e), e.id; + } + /** + * Removes a ring from the array of rings associated with the current molecule. + * + * @param {Number} ringId A ring id. + */ + removeRing(e) { + this.rings = this.rings.filter(function(r) { + return r.id !== e; + }), this.ringConnections = this.ringConnections.filter(function(r) { + return r.firstRingId !== e && r.secondRingId !== e; + }); + for (var t = 0; t < this.rings.length; t++) { + let r = this.rings[t]; + r.neighbours = r.neighbours.filter(function(i) { + return i !== e; + }); + } + } + /** + * Gets a ring object from the array of rings associated with the current molecule by its id. The ring id is not equal to the index, since rings can be added and removed when processing bridged rings. + * + * @param {Number} ringId A ring id. + * @returns {Ring} A ring associated with the current molecule. + */ + getRing(e) { + for (var t = 0; t < this.rings.length; t++) + if (this.rings[t].id == e) + return this.rings[t]; + } + /** + * Add a ring connection to this representation of a molecule. + * + * @param {RingConnection} ringConnection A new ringConnection. + * @returns {Number} The ring connection id of the new ring connection. + */ + addRingConnection(e) { + return e.id = this.ringConnectionIdCounter++, this.ringConnections.push(e), e.id; + } + /** + * Removes a ring connection from the array of rings connections associated with the current molecule. + * + * @param {Number} ringConnectionId A ring connection id. + */ + removeRingConnection(e) { + this.ringConnections = this.ringConnections.filter(function(t) { + return t.id !== e; + }); + } + /** + * Removes all ring connections between two vertices. + * + * @param {Number} vertexIdA A vertex id. + * @param {Number} vertexIdB A vertex id. + */ + removeRingConnectionsBetween(e, t) { + let r = Array(); + for (var i = 0; i < this.ringConnections.length; i++) { + let s = this.ringConnections[i]; + (s.firstRingId === e && s.secondRingId === t || s.firstRingId === t && s.secondRingId === e) && r.push(s.id); + } + for (var i = 0; i < r.length; i++) + this.removeRingConnection(r[i]); + } + /** + * Get a ring connection with a given id. + * + * @param {Number} id + * @returns {RingConnection} The ring connection with the specified id. + */ + getRingConnection(e) { + for (var t = 0; t < this.ringConnections.length; t++) + if (this.ringConnections[t].id == e) + return this.ringConnections[t]; + } + /** + * Get the ring connections between a ring and a set of rings. + * + * @param {Number} ringId A ring id. + * @param {Number[]} ringIds An array of ring ids. + * @returns {Number[]} An array of ring connection ids. + */ + getRingConnections(e, t) { + let r = Array(); + for (var i = 0; i < this.ringConnections.length; i++) { + let a = this.ringConnections[i]; + for (var s = 0; s < t.length; s++) { + let n = t[s]; + (a.firstRingId === e && a.secondRingId === n || a.firstRingId === n && a.secondRingId === e) && r.push(a.id); + } + } + return r; + } + /** + * Returns the overlap score of the current molecule based on its positioned vertices. The higher the score, the more overlaps occur in the structure drawing. + * + * @returns {Object} Returns the total overlap score and the overlap score of each vertex sorted by score (higher to lower). Example: { total: 99, scores: [ { id: 0, score: 22 }, ... ] } + */ + getOverlapScore() { + let e = 0, t = new Float32Array(this.graph.vertices.length); + for (var r = 0; r < this.graph.vertices.length; r++) + t[r] = 0; + for (var r = 0; r < this.graph.vertices.length; r++) + for (var i = this.graph.vertices.length; --i > r; ) { + let n = this.graph.vertices[r], h = this.graph.vertices[i]; + if (!n.value.isDrawn || !h.value.isDrawn) + continue; + let l = re.subtract(n.position, h.position).lengthSq(); + if (l < this.opts.bondLengthSq) { + let c = (this.opts.bondLength - Math.sqrt(l)) / this.opts.bondLength; + e += c, t[r] += c, t[i] += c; + } + } + let s = Array(); + for (var r = 0; r < this.graph.vertices.length; r++) + s.push({ + id: r, + score: t[r] + }); + return s.sort(function(a, n) { + return n.score - a.score; + }), { + total: e, + scores: s, + vertexScores: t + }; + } + /** + * When drawing a double bond, choose the side to place the double bond. E.g. a double bond should always been drawn inside a ring. + * + * @param {Vertex} vertexA A vertex. + * @param {Vertex} vertexB A vertex. + * @param {Vector2[]} sides An array containing the two normals of the line spanned by the two provided vertices. + * @returns {Object} Returns an object containing the following information: { + totalSideCount: Counts the sides of each vertex in the molecule, is an array [ a, b ], + totalPosition: Same as position, but based on entire molecule, + sideCount: Counts the sides of each neighbour, is an array [ a, b ], + position: which side to position the second bond, is 0 or 1, represents the index in the normal array. This is based on only the neighbours + anCount: the number of neighbours of vertexA, + bnCount: the number of neighbours of vertexB + } + */ + chooseSide(e, t, r) { + let i = e.getNeighbours(t.id), s = t.getNeighbours(e.id), a = i.length, n = s.length, h = Dt.merge(i, s), l = [0, 0]; + for (var c = 0; c < h.length; c++) + this.graph.vertices[h[c]].position.sameSideAs(e.position, t.position, r[0]) ? l[0]++ : l[1]++; + let u = [0, 0]; + for (var c = 0; c < this.graph.vertices.length; c++) + this.graph.vertices[c].position.sameSideAs(e.position, t.position, r[0]) ? u[0]++ : u[1]++; + return { + totalSideCount: u, + totalPosition: u[0] > u[1] ? 0 : 1, + sideCount: l, + position: l[0] > l[1] ? 0 : 1, + anCount: a, + bnCount: n + }; + } + /** + * Sets the center for a ring. + * + * @param {Ring} ring A ring. + */ + setRingCenter(e) { + let t = e.getSize(), r = new re(0, 0); + for (var i = 0; i < t; i++) + r.add(this.graph.vertices[e.members[i]].position); + e.center = r.divide(t); + } + /** + * Gets the center of a ring contained within a bridged ring and containing a given vertex. + * + * @param {Ring} ring A bridged ring. + * @param {Vertex} vertex A vertex. + * @returns {Vector2} The center of the subring that containing the vertex. + */ + getSubringCenter(e, t) { + let r = t.value.originalRings, i = e.center, s = Number.MAX_VALUE; + for (var a = 0; a < r.length; a++) + for (var n = 0; n < e.rings.length; n++) + r[a] === e.rings[n].id && e.rings[n].getSize() < s && (i = e.rings[n].center, s = e.rings[n].getSize()); + return i; + } + /** + * Draw the actual edges as bonds to the canvas. + * + * @param {Boolean} debug A boolean indicating whether or not to draw debug helpers. + */ + drawEdges(e) { + let t = this, r = Array(this.graph.edges.length); + if (r.fill(!1), this.graph.traverseBF(0, function(s) { + let a = t.graph.getEdges(s.id); + for (var n = 0; n < a.length; n++) { + let h = a[n]; + r[h] || (r[h] = !0, t.drawEdge(h, e)); + } + }), !this.bridgedRing) + for (var i = 0; i < this.rings.length; i++) { + let s = this.rings[i]; + this.isRingAromatic(s) && this.canvasWrapper.drawAromaticityRing(s); + } + } + /** + * Draw the an edge as a bonds to the canvas. + * + * @param {Number} edgeId An edge id. + * @param {Boolean} debug A boolean indicating whether or not to draw debug helpers. + */ + drawEdge(e, t) { + let r = this, i = this.graph.edges[e], s = this.graph.vertices[i.sourceId], a = this.graph.vertices[i.targetId], n = s.value.element, h = a.value.element; + if ((!s.value.isDrawn || !a.value.isDrawn) && this.opts.atomVisualization === "default") + return; + let l = s.position, c = a.position, u = this.getEdgeNormals(i), g = Dt.clone(u); + if (g[0].multiplyScalar(10).add(l), g[1].multiplyScalar(10).add(l), i.bondType === "=" || this.getRingbondType(s, a) === "=" || i.isPartOfAromaticRing && this.bridgedRing) { + let m = this.areVerticesInSameRing(s, a), _ = this.chooseSide(s, a, g); + if (m) { + let N = this.getLargestOrAromaticCommonRing(s, a).center; + u[0].multiplyScalar(r.opts.bondSpacing), u[1].multiplyScalar(r.opts.bondSpacing); + let B = null; + N.sameSideAs(s.position, a.position, re.add(l, u[0])) ? B = new Me(re.add(l, u[0]), re.add(c, u[0]), n, h) : B = new Me(re.add(l, u[1]), re.add(c, u[1]), n, h), B.shorten(this.opts.bondLength - this.opts.shortBondLength * this.opts.bondLength), i.isPartOfAromaticRing ? this.canvasWrapper.drawLine(B, !0) : this.canvasWrapper.drawLine(B), this.canvasWrapper.drawLine(new Me(l, c, n, h)); + } else if (i.center || s.isTerminal() && a.isTerminal()) { + u[0].multiplyScalar(r.opts.halfBondSpacing), u[1].multiplyScalar(r.opts.halfBondSpacing); + let v = new Me(re.add(l, u[0]), re.add(c, u[0]), n, h), N = new Me(re.add(l, u[1]), re.add(c, u[1]), n, h); + this.canvasWrapper.drawLine(v), this.canvasWrapper.drawLine(N); + } else if (_.anCount == 0 && _.bnCount > 1 || _.bnCount == 0 && _.anCount > 1) { + u[0].multiplyScalar(r.opts.halfBondSpacing), u[1].multiplyScalar(r.opts.halfBondSpacing); + let v = new Me(re.add(l, u[0]), re.add(c, u[0]), n, h), N = new Me(re.add(l, u[1]), re.add(c, u[1]), n, h); + this.canvasWrapper.drawLine(v), this.canvasWrapper.drawLine(N); + } else if (_.sideCount[0] > _.sideCount[1]) { + u[0].multiplyScalar(r.opts.bondSpacing), u[1].multiplyScalar(r.opts.bondSpacing); + let v = new Me(re.add(l, u[0]), re.add(c, u[0]), n, h); + v.shorten(this.opts.bondLength - this.opts.shortBondLength * this.opts.bondLength), this.canvasWrapper.drawLine(v), this.canvasWrapper.drawLine(new Me(l, c, n, h)); + } else if (_.sideCount[0] < _.sideCount[1]) { + u[0].multiplyScalar(r.opts.bondSpacing), u[1].multiplyScalar(r.opts.bondSpacing); + let v = new Me(re.add(l, u[1]), re.add(c, u[1]), n, h); + v.shorten(this.opts.bondLength - this.opts.shortBondLength * this.opts.bondLength), this.canvasWrapper.drawLine(v), this.canvasWrapper.drawLine(new Me(l, c, n, h)); + } else if (_.totalSideCount[0] > _.totalSideCount[1]) { + u[0].multiplyScalar(r.opts.bondSpacing), u[1].multiplyScalar(r.opts.bondSpacing); + let v = new Me(re.add(l, u[0]), re.add(c, u[0]), n, h); + v.shorten(this.opts.bondLength - this.opts.shortBondLength * this.opts.bondLength), this.canvasWrapper.drawLine(v), this.canvasWrapper.drawLine(new Me(l, c, n, h)); + } else if (_.totalSideCount[0] <= _.totalSideCount[1]) { + u[0].multiplyScalar(r.opts.bondSpacing), u[1].multiplyScalar(r.opts.bondSpacing); + let v = new Me(re.add(l, u[1]), re.add(c, u[1]), n, h); + v.shorten(this.opts.bondLength - this.opts.shortBondLength * this.opts.bondLength), this.canvasWrapper.drawLine(v), this.canvasWrapper.drawLine(new Me(l, c, n, h)); + } + } else if (i.bondType === "#") { + u[0].multiplyScalar(r.opts.bondSpacing / 1.5), u[1].multiplyScalar(r.opts.bondSpacing / 1.5); + let m = new Me(re.add(l, u[0]), re.add(c, u[0]), n, h), _ = new Me(re.add(l, u[1]), re.add(c, u[1]), n, h); + this.canvasWrapper.drawLine(m), this.canvasWrapper.drawLine(_), this.canvasWrapper.drawLine(new Me(l, c, n, h)); + } else if (i.bondType !== ".") { + let m = s.value.isStereoCenter, _ = a.value.isStereoCenter; + i.wedge === "up" ? this.canvasWrapper.drawWedge(new Me(l, c, n, h, m, _)) : i.wedge === "down" ? this.canvasWrapper.drawDashedWedge(new Me(l, c, n, h, m, _)) : this.canvasWrapper.drawLine(new Me(l, c, n, h, m, _)); + } + if (t) { + let m = re.midpoint(l, c); + this.canvasWrapper.drawDebugText(m.x, m.y, "e: " + e); + } + } + /** + * Draws the vertices representing atoms to the canvas. + * + * @param {Boolean} debug A boolean indicating whether or not to draw debug messages to the canvas. + */ + drawVertices(e) { + for (var t = this.graph.vertices.length, t = 0; t < this.graph.vertices.length; t++) { + let i = this.graph.vertices[t], s = i.value, a = 0, n = 0, h = i.value.bondCount, l = s.element, c = Ci.maxBonds[l] - h, u = i.getTextDirection(this.graph.vertices), g = this.opts.terminalCarbons || l !== "C" || s.hasAttachedPseudoElements ? i.isTerminal() : !1, m = s.element === "C"; + if (s.element === "N" && s.isPartOfAromaticRing && (c = 0), s.bracket && (c = s.bracket.hcount, a = s.bracket.charge, n = s.bracket.isotope), this.opts.atomVisualization === "allballs") + this.canvasWrapper.drawBall(i.position.x, i.position.y, l); + else if (s.isDrawn && (!m || s.drawExplicit || g || s.hasAttachedPseudoElements) || this.graph.vertices.length === 1) + this.opts.atomVisualization === "default" ? this.canvasWrapper.drawText( + i.position.x, + i.position.y, + l, + c, + u, + g, + a, + n, + this.graph.vertices.length, + s.getAttachedPseudoElements() + ) : this.opts.atomVisualization === "balls" && this.canvasWrapper.drawBall(i.position.x, i.position.y, l); + else if (i.getNeighbourCount() === 2 && i.forcePositioned == !0) { + let _ = this.graph.vertices[i.neighbours[0]].position, v = this.graph.vertices[i.neighbours[1]].position, N = re.threePointangle(i.position, _, v); + Math.abs(Math.PI - N) < 0.1 && this.canvasWrapper.drawPoint(i.position.x, i.position.y, l); + } + if (e) { + let _ = "v: " + i.id + " " + Dt.print(s.ringbonds); + this.canvasWrapper.drawDebugText(i.position.x, i.position.y, _); + } + } + if (this.opts.debug) + for (var t = 0; t < this.rings.length; t++) { + let i = this.rings[t].center; + this.canvasWrapper.drawDebugPoint(i.x, i.y, "r: " + this.rings[t].id); + } + } + /** + * Position the vertices according to their bonds and properties. + */ + position() { + let e = null; + for (var t = 0; t < this.graph.vertices.length; t++) + if (this.graph.vertices[t].value.bridgedRing !== null) { + e = this.graph.vertices[t]; + break; + } + for (var t = 0; t < this.rings.length; t++) + this.rings[t].isBridged && (e = this.graph.vertices[this.rings[t].members[0]]); + this.rings.length > 0 && e === null && (e = this.graph.vertices[this.rings[0].members[0]]), e === null && (e = this.graph.vertices[0]), this.createNextBond(e, null, 0); + } + /** + * Stores the current information associated with rings. + */ + backupRingInformation() { + this.originalRings = Array(), this.originalRingConnections = Array(); + for (var e = 0; e < this.rings.length; e++) + this.originalRings.push(this.rings[e]); + for (var e = 0; e < this.ringConnections.length; e++) + this.originalRingConnections.push(this.ringConnections[e]); + for (var e = 0; e < this.graph.vertices.length; e++) + this.graph.vertices[e].value.backupRings(); + } + /** + * Restores the most recently backed up information associated with rings. + */ + restoreRingInformation() { + let e = this.getBridgedRings(); + this.rings = Array(), this.ringConnections = Array(); + for (var t = 0; t < e.length; t++) { + let i = e[t]; + for (var r = 0; r < i.rings.length; r++) { + let s = i.rings[r]; + this.originalRings[s.id].center = s.center; + } + } + for (var t = 0; t < this.originalRings.length; t++) + this.rings.push(this.originalRings[t]); + for (var t = 0; t < this.originalRingConnections.length; t++) + this.ringConnections.push(this.originalRingConnections[t]); + for (var t = 0; t < this.graph.vertices.length; t++) + this.graph.vertices[t].value.restoreRings(); + } + // TODO: This needs some cleaning up + /** + * Creates a new ring, that is, positiones all the vertices inside a ring. + * + * @param {Ring} ring The ring to position. + * @param {(Vector2|null)} [center=null] The center of the ring to be created. + * @param {(Vertex|null)} [startVertex=null] The first vertex to be positioned inside the ring. + * @param {(Vertex|null)} [previousVertex=null] The last vertex that was positioned. + * @param {Boolean} [previousVertex=false] A boolean indicating whether or not this ring was force positioned already - this is needed after force layouting a ring, in order to draw rings connected to it. + */ + createRing(e, t = null, r = null, i = null) { + if (e.positioned) + return; + t = t || new re(0, 0); + let s = e.getOrderedNeighbours(this.ringConnections), a = r ? re.subtract(r.position, t).angle() : 0, n = Se.polyCircumradius(this.opts.bondLength, e.getSize()), h = Se.centralAngle(e.getSize()); + e.centralAngle = h; + let l = a, c = this, u = r ? r.id : null; + if (e.members.indexOf(u) === -1 && (r && (r.positioned = !1), u = e.members[0]), e.isBridged) { + this.graph.kkLayout( + e.members.slice(), + t, + r.id, + e, + this.opts.bondLength, + this.opts.kkThreshold, + this.opts.kkInnerThreshold, + this.opts.kkMaxIteration, + this.opts.kkMaxInnerIteration, + this.opts.kkMaxEnergy + ), e.positioned = !0, this.setRingCenter(e), t = e.center; + for (var g = 0; g < e.rings.length; g++) + this.setRingCenter(e.rings[g]); + } else + e.eachMember(this.graph.vertices, function(_) { + let v = c.graph.vertices[_]; + v.positioned || v.setPosition(t.x + Math.cos(l) * n, t.y + Math.sin(l) * n), l += h, (!e.isBridged || e.rings.length < 3) && (v.angle = l, v.positioned = !0); + }, u, i ? i.id : null); + e.positioned = !0, e.center = t; + for (var g = 0; g < s.length; g++) { + let v = this.getRing(s[g].neighbour); + if (v.positioned) + continue; + let N = Ai.getVertices(this.ringConnections, e.id, v.id); + if (N.length === 2) { + e.isFused = !0, v.isFused = !0; + let B = this.graph.vertices[N[0]], x = this.graph.vertices[N[1]], L = re.midpoint(B.position, x.position), k = re.normals(B.position, x.position); + k[0].normalize(), k[1].normalize(); + let z = Se.polyCircumradius(this.opts.bondLength, v.getSize()), D = Se.apothem(z, v.getSize()); + k[0].multiplyScalar(D).add(L), k[1].multiplyScalar(D).add(L); + let Y = k[0]; + re.subtract(t, k[1]).lengthSq() > re.subtract(t, k[0]).lengthSq() && (Y = k[1]); + let O = re.subtract(B.position, Y), Z = re.subtract(x.position, Y); + O.clockwise(Z) === -1 ? v.positioned || this.createRing(v, Y, B, x) : v.positioned || this.createRing(v, Y, x, B); + } else if (N.length === 1) { + e.isSpiro = !0, v.isSpiro = !0; + let B = this.graph.vertices[N[0]], x = re.subtract(t, B.position); + x.invert(), x.normalize(); + let L = Se.polyCircumradius(this.opts.bondLength, v.getSize()); + x.multiplyScalar(L), x.add(B.position), v.positioned || this.createRing(v, x, B); + } + } + for (var g = 0; g < e.members.length; g++) { + let v = this.graph.vertices[e.members[g]], N = v.neighbours; + for (var m = 0; m < N.length; m++) { + let B = this.graph.vertices[N[m]]; + B.positioned || (B.value.isConnectedToRing = !0, this.createNextBond(B, v, 0)); + } + } + } + /** + * Rotate an entire subtree by an angle around a center. + * + * @param {Number} vertexId A vertex id (the root of the sub-tree). + * @param {Number} parentVertexId A vertex id in the previous direction of the subtree that is to rotate. + * @param {Number} angle An angle in randians. + * @param {Vector2} center The rotational center. + */ + rotateSubtree(e, t, r, i) { + let s = this; + this.graph.traverseTree(e, t, function(a) { + a.position.rotateAround(r, i); + for (var n = 0; n < a.value.anchoredRings.length; n++) { + let h = s.rings[a.value.anchoredRings[n]]; + h && h.center.rotateAround(r, i); + } + }); + } + /** + * Gets the overlap score of a subtree. + * + * @param {Number} vertexId A vertex id (the root of the sub-tree). + * @param {Number} parentVertexId A vertex id in the previous direction of the subtree. + * @param {Number[]} vertexOverlapScores An array containing the vertex overlap scores indexed by vertex id. + * @returns {Object} An object containing the total overlap score and the center of mass of the subtree weighted by overlap score { value: 0.2, center: new Vector2() }. + */ + getSubtreeOverlapScore(e, t, r) { + let i = this, s = 0, a = new re(0, 0), n = 0; + return this.graph.traverseTree(e, t, function(h) { + if (!h.value.isDrawn) + return; + let l = r[h.id]; + l > i.opts.overlapSensitivity && (s += l, n++); + let c = i.graph.vertices[h.id].position.clone(); + c.multiplyScalar(l), a.add(c); + }), a.divide(s), { + value: s / n, + center: a + }; + } + /** + * Returns the current (positioned vertices so far) center of mass. + * + * @returns {Vector2} The current center of mass. + */ + getCurrentCenterOfMass() { + let e = new re(0, 0), t = 0; + for (var r = 0; r < this.graph.vertices.length; r++) { + let i = this.graph.vertices[r]; + i.positioned && (e.add(i.position), t++); + } + return e.divide(t); + } + /** + * Returns the current (positioned vertices so far) center of mass in the neighbourhood of a given position. + * + * @param {Vector2} vec The point at which to look for neighbours. + * @param {Number} [r=currentBondLength*2.0] The radius of vertices to include. + * @returns {Vector2} The current center of mass. + */ + getCurrentCenterOfMassInNeigbourhood(e, t = this.opts.bondLength * 2) { + let r = new re(0, 0), i = 0, s = t * t; + for (var a = 0; a < this.graph.vertices.length; a++) { + let n = this.graph.vertices[a]; + n.positioned && e.distanceSq(n.position) < s && (r.add(n.position), i++); + } + return r.divide(i); + } + /** + * Resolve primary (exact) overlaps, such as two vertices that are connected to the same ring vertex. + */ + resolvePrimaryOverlaps() { + let e = Array(), t = Array(this.graph.vertices.length); + for (var r = 0; r < this.rings.length; r++) { + let a = this.rings[r]; + for (var i = 0; i < a.members.length; i++) { + let n = this.graph.vertices[a.members[i]]; + if (t[n.id]) + continue; + t[n.id] = !0; + let h = this.getNonRingNeighbours(n.id); + if (h.length > 1) { + let l = Array(); + for (var s = 0; s < n.value.rings.length; s++) + l.push(n.value.rings[s]); + e.push({ + common: n, + rings: l, + vertices: h + }); + } else if (h.length === 1 && n.value.rings.length === 2) { + let l = Array(); + for (var s = 0; s < n.value.rings.length; s++) + l.push(n.value.rings[s]); + e.push({ + common: n, + rings: l, + vertices: h + }); + } + } + } + for (var r = 0; r < e.length; r++) { + let n = e[r]; + if (n.vertices.length === 2) { + let h = n.vertices[0], l = n.vertices[1]; + if (!h.value.isDrawn || !l.value.isDrawn) + continue; + let c = (2 * Math.PI - this.getRing(n.rings[0]).getAngle()) / 6; + this.rotateSubtree(h.id, n.common.id, c, n.common.position), this.rotateSubtree(l.id, n.common.id, -c, n.common.position); + let u = this.getOverlapScore(), g = this.getSubtreeOverlapScore(h.id, n.common.id, u.vertexScores), m = this.getSubtreeOverlapScore(l.id, n.common.id, u.vertexScores), _ = g.value + m.value; + this.rotateSubtree(h.id, n.common.id, -2 * c, n.common.position), this.rotateSubtree(l.id, n.common.id, 2 * c, n.common.position), u = this.getOverlapScore(), g = this.getSubtreeOverlapScore(h.id, n.common.id, u.vertexScores), m = this.getSubtreeOverlapScore(l.id, n.common.id, u.vertexScores), g.value + m.value > _ && (this.rotateSubtree(h.id, n.common.id, 2 * c, n.common.position), this.rotateSubtree(l.id, n.common.id, -2 * c, n.common.position)); + } else + n.vertices.length === 1 && n.rings.length; + } + } + /** + * Resolve secondary overlaps. Those overlaps are due to the structure turning back on itself. + * + * @param {Object[]} scores An array of objects sorted descending by score. + * @param {Number} scores[].id A vertex id. + * @param {Number} scores[].score The overlap score associated with the vertex id. + */ + resolveSecondaryOverlaps(e) { + for (var t = 0; t < e.length; t++) + if (e[t].score > this.opts.overlapSensitivity) { + let r = this.graph.vertices[e[t].id]; + if (r.isTerminal()) { + let i = this.getClosestVertex(r); + if (i) { + let s = null; + i.isTerminal() ? s = i.id === 0 ? this.graph.vertices[1].position : i.previousPosition : s = i.id === 0 ? this.graph.vertices[1].position : i.position; + let a = r.id === 0 ? this.graph.vertices[1].position : r.previousPosition; + r.position.rotateAwayFrom(s, a, Se.toRad(20)); + } + } + } + } + /** + * Get the last non-null or 0 angle vertex. + * @param {Number} vertexId A vertex id. + * @returns {Vertex} The last vertex with an angle that was not 0 or null. + */ + getLastVertexWithAngle(e) { + let t = 0, r = null; + for (; !t && e; ) + r = this.graph.vertices[e], t = r.angle, e = r.parentVertexId; + return r; + } + /** + * Positiones the next vertex thus creating a bond. + * + * @param {Vertex} vertex A vertex. + * @param {Vertex} [previousVertex=null] The previous vertex which has been positioned. + * @param {Number} [angle=0.0] The (global) angle of the vertex. + * @param {Boolean} [originShortest=false] Whether the origin is the shortest subtree in the branch. + * @param {Boolean} [skipPositioning=false] Whether or not to skip positioning and just check the neighbours. + */ + createNextBond(e, t = null, r = 0, i = !1, s = !1) { + if (e.positioned && !s) + return; + let a = !1; + if (t) { + let h = this.graph.getEdge(e.id, t.id); + (h.bondType === "/" || h.bondType === "\\") && ++this.doubleBondConfigCount % 2 === 1 && this.doubleBondConfig === null && (this.doubleBondConfig = h.bondType, a = !0, t.parentVertexId === null && e.value.branchBond && (this.doubleBondConfig === "/" ? this.doubleBondConfig = "\\" : this.doubleBondConfig === "\\" && (this.doubleBondConfig = "/"))); + } + if (!s) + if (t) + if (t.value.rings.length > 0) { + let h = t.neighbours, l = null, c = new re(0, 0); + if (t.value.bridgedRing === null && t.value.rings.length > 1) + for (var n = 0; n < h.length; n++) { + let u = this.graph.vertices[h[n]]; + if (Dt.containsAll(u.value.rings, t.value.rings)) { + l = u; + break; + } + } + if (l === null) { + for (var n = 0; n < h.length; n++) { + let g = this.graph.vertices[h[n]]; + g.positioned && this.areVerticesInSameRing(g, t) && c.add(re.subtract(g.position, t.position)); + } + c.invert().normalize().multiplyScalar(this.opts.bondLength).add(t.position); + } else + c = l.position.clone().rotateAround(Math.PI, t.position); + e.previousPosition = t.position, e.setPositionFromVector(c), e.positioned = !0; + } else { + let h = new re(this.opts.bondLength, 0); + h.rotate(r), h.add(t.position), e.setPositionFromVector(h), e.previousPosition = t.position, e.positioned = !0; + } + else { + let h = new re(this.opts.bondLength, 0); + h.rotate(Se.toRad(-60)), e.previousPosition = h, e.setPosition(this.opts.bondLength, 0), e.angle = Se.toRad(-60), e.value.bridgedRing === null && (e.positioned = !0); + } + if (e.value.bridgedRing !== null) { + let h = this.getRing(e.value.bridgedRing); + if (!h.positioned) { + let l = re.subtract(e.previousPosition, e.position); + l.invert(), l.normalize(); + let c = Se.polyCircumradius(this.opts.bondLength, h.members.length); + l.multiplyScalar(c), l.add(e.position), this.createRing(h, l, e); + } + } else if (e.value.rings.length > 0) { + let h = this.getRing(e.value.rings[0]); + if (!h.positioned) { + let l = re.subtract(e.previousPosition, e.position); + l.invert(), l.normalize(); + let c = Se.polyCircumradius(this.opts.bondLength, h.getSize()); + l.multiplyScalar(c), l.add(e.position), this.createRing(h, l, e); + } + } else { + e.value.isStereoCenter; + let h = e.getNeighbours(), l = Array(); + for (var n = 0; n < h.length; n++) + this.graph.vertices[h[n]].value.isDrawn && l.push(h[n]); + t && (l = Dt.remove(l, t.id)); + let c = e.getAngle(); + if (l.length === 1) { + let u = this.graph.vertices[l[0]]; + if (e.value.bondType === "#" || t && t.value.bondType === "#" || e.value.bondType === "=" && t && t.value.rings.length === 0 && t.value.bondType === "=" && e.value.branchBond !== "-") { + if (e.value.drawExplicit = !1, t) { + let m = this.graph.getEdge(e.id, t.id); + m.center = !0; + } + let g = this.graph.getEdge(e.id, u.id); + g.center = !0, (e.value.bondType === "#" || t && t.value.bondType === "#") && (u.angle = 0), u.drawExplicit = !0, this.createNextBond(u, e, c + u.angle); + } else if (t && t.value.rings.length > 0) { + let g = Se.toRad(60), m = -g, _ = new re(this.opts.bondLength, 0), v = new re(this.opts.bondLength, 0); + _.rotate(g).add(e.position), v.rotate(m).add(e.position); + let N = this.getCurrentCenterOfMass(), B = _.distanceSq(N), x = v.distanceSq(N); + u.angle = B < x ? m : g, this.createNextBond(u, e, c + u.angle); + } else { + let g = e.angle; + if (t && t.neighbours.length > 3 ? g > 0 ? g = Math.min(1.0472, g) : g < 0 ? g = Math.max(-1.0472, g) : g = 1.0472 : g || (g = this.getLastVertexWithAngle(e.id).angle, g || (g = 1.0472)), t && !a) { + let m = this.graph.getEdge(e.id, u.id).bondType; + m === "/" ? (this.doubleBondConfig === "/" || this.doubleBondConfig === "\\" && (g = -g), this.doubleBondConfig = null) : m === "\\" && (this.doubleBondConfig === "/" ? g = -g : this.doubleBondConfig, this.doubleBondConfig = null); + } + i ? u.angle = g : u.angle = -g, this.createNextBond(u, e, c + u.angle); + } + } else if (l.length === 2) { + let u = e.angle; + u || (u = 1.0472); + let g = this.graph.getTreeDepth(l[0], e.id), m = this.graph.getTreeDepth(l[1], e.id), _ = this.graph.vertices[l[0]], v = this.graph.vertices[l[1]]; + _.value.subtreeDepth = g, v.value.subtreeDepth = m; + let N = this.graph.getTreeDepth(t ? t.id : null, e.id); + t && (t.value.subtreeDepth = N); + let B = 0, x = 1; + v.value.element === "C" && _.value.element !== "C" && m > 1 && g < 5 ? (B = 1, x = 0) : v.value.element !== "C" && _.value.element === "C" && g > 1 && m < 5 ? (B = 0, x = 1) : m > g && (B = 1, x = 0); + let L = this.graph.vertices[l[B]], k = this.graph.vertices[l[x]]; + this.graph.getEdge(e.id, L.id), this.graph.getEdge(e.id, k.id); + let z = !1; + N < g && N < m && (z = !0), k.angle = u, L.angle = -u, this.doubleBondConfig === "\\" ? k.value.branchBond === "\\" && (k.angle = -u, L.angle = u) : this.doubleBondConfig === "/" && k.value.branchBond === "/" && (k.angle = -u, L.angle = u), this.createNextBond(k, e, c + k.angle, z), this.createNextBond(L, e, c + L.angle, z); + } else if (l.length === 3) { + let u = this.graph.getTreeDepth(l[0], e.id), g = this.graph.getTreeDepth(l[1], e.id), m = this.graph.getTreeDepth(l[2], e.id), _ = this.graph.vertices[l[0]], v = this.graph.vertices[l[1]], N = this.graph.vertices[l[2]]; + _.value.subtreeDepth = u, v.value.subtreeDepth = g, N.value.subtreeDepth = m, g > u && g > m ? (_ = this.graph.vertices[l[1]], v = this.graph.vertices[l[0]], N = this.graph.vertices[l[2]]) : m > u && m > g && (_ = this.graph.vertices[l[2]], v = this.graph.vertices[l[0]], N = this.graph.vertices[l[1]]), t && t.value.rings.length < 1 && _.value.rings.length < 1 && v.value.rings.length < 1 && N.value.rings.length < 1 && this.graph.getTreeDepth(v.id, e.id) === 1 && this.graph.getTreeDepth(N.id, e.id) === 1 && this.graph.getTreeDepth(_.id, e.id) > 1 ? (_.angle = -e.angle, e.angle >= 0 ? (v.angle = Se.toRad(30), N.angle = Se.toRad(90)) : (v.angle = -Se.toRad(30), N.angle = -Se.toRad(90)), this.createNextBond(_, e, c + _.angle), this.createNextBond(v, e, c + v.angle), this.createNextBond(N, e, c + N.angle)) : (_.angle = 0, v.angle = Se.toRad(90), N.angle = -Se.toRad(90), this.createNextBond(_, e, c + _.angle), this.createNextBond(v, e, c + v.angle), this.createNextBond(N, e, c + N.angle)); + } else if (l.length === 4) { + let u = this.graph.getTreeDepth(l[0], e.id), g = this.graph.getTreeDepth(l[1], e.id), m = this.graph.getTreeDepth(l[2], e.id), _ = this.graph.getTreeDepth(l[3], e.id), v = this.graph.vertices[l[0]], N = this.graph.vertices[l[1]], B = this.graph.vertices[l[2]], x = this.graph.vertices[l[3]]; + v.value.subtreeDepth = u, N.value.subtreeDepth = g, B.value.subtreeDepth = m, x.value.subtreeDepth = _, g > u && g > m && g > _ ? (v = this.graph.vertices[l[1]], N = this.graph.vertices[l[0]], B = this.graph.vertices[l[2]], x = this.graph.vertices[l[3]]) : m > u && m > g && m > _ ? (v = this.graph.vertices[l[2]], N = this.graph.vertices[l[0]], B = this.graph.vertices[l[1]], x = this.graph.vertices[l[3]]) : _ > u && _ > g && _ > m && (v = this.graph.vertices[l[3]], N = this.graph.vertices[l[0]], B = this.graph.vertices[l[1]], x = this.graph.vertices[l[2]]), v.angle = -Se.toRad(36), N.angle = Se.toRad(36), B.angle = -Se.toRad(108), x.angle = Se.toRad(108), this.createNextBond(v, e, c + v.angle), this.createNextBond(N, e, c + N.angle), this.createNextBond(B, e, c + B.angle), this.createNextBond(x, e, c + x.angle); + } + } + } + /** + * Gets the vetex sharing the edge that is the common bond of two rings. + * + * @param {Vertex} vertex A vertex. + * @returns {(Number|null)} The id of a vertex sharing the edge that is the common bond of two rings with the vertex provided or null, if none. + */ + getCommonRingbondNeighbour(e) { + let t = e.neighbours; + for (var r = 0; r < t.length; r++) { + let i = this.graph.vertices[t[r]]; + if (Dt.containsAll(i.value.rings, e.value.rings)) + return i; + } + return null; + } + /** + * Check if a vector is inside any ring. + * + * @param {Vector2} vec A vector. + * @returns {Boolean} A boolean indicating whether or not the point (vector) is inside any of the rings associated with the current molecule. + */ + isPointInRing(e) { + for (var t = 0; t < this.rings.length; t++) { + let r = this.rings[t]; + if (!r.positioned) + continue; + let i = Se.polyCircumradius(this.opts.bondLength, r.getSize()), s = i * i; + if (e.distanceSq(r.center) < s) + return !0; + } + return !1; + } + /** + * Check whether or not an edge is part of a ring. + * + * @param {Edge} edge An edge. + * @returns {Boolean} A boolean indicating whether or not the edge is part of a ring. + */ + isEdgeInRing(e) { + let t = this.graph.vertices[e.sourceId], r = this.graph.vertices[e.targetId]; + return this.areVerticesInSameRing(t, r); + } + /** + * Check whether or not an edge is rotatable. + * + * @param {Edge} edge An edge. + * @returns {Boolean} A boolean indicating whether or not the edge is rotatable. + */ + isEdgeRotatable(e) { + let t = this.graph.vertices[e.sourceId], r = this.graph.vertices[e.targetId]; + return !(e.bondType !== "-" || t.isTerminal() || r.isTerminal() || t.value.rings.length > 0 && r.value.rings.length > 0 && this.areVerticesInSameRing(t, r)); + } + /** + * Check whether or not a ring is an implicitly defined aromatic ring (lower case smiles). + * + * @param {Ring} ring A ring. + * @returns {Boolean} A boolean indicating whether or not a ring is implicitly defined as aromatic. + */ + isRingAromatic(e) { + for (var t = 0; t < e.members.length; t++) + if (!this.graph.vertices[e.members[t]].value.isPartOfAromaticRing) + return !1; + return !0; + } + /** + * Get the normals of an edge. + * + * @param {Edge} edge An edge. + * @returns {Vector2[]} An array containing two vectors, representing the normals. + */ + getEdgeNormals(e) { + let t = this.graph.vertices[e.sourceId].position, r = this.graph.vertices[e.targetId].position; + return re.units(t, r); + } + /** + * Returns an array of vertices that are neighbouring a vertix but are not members of a ring (including bridges). + * + * @param {Number} vertexId A vertex id. + * @returns {Vertex[]} An array of vertices. + */ + getNonRingNeighbours(e) { + let t = Array(), r = this.graph.vertices[e], i = r.neighbours; + for (var s = 0; s < i.length; s++) { + let a = this.graph.vertices[i[s]]; + Dt.intersection(r.value.rings, a.value.rings).length === 0 && a.value.isBridge == !1 && t.push(a); + } + return t; + } + /** + * Annotaed stereochemistry information for visualization. + */ + annotateStereochemistry() { + let e = 10; + for (var t = 0; t < this.graph.vertices.length; t++) { + let a = this.graph.vertices[t]; + if (!a.value.isStereoCenter) + continue; + let n = a.getNeighbours(), h = n.length, l = Array(h); + for (var r = 0; r < h; r++) { + let Z = new Uint8Array(this.graph.vertices.length), j = Array(Array()); + Z[a.id] = 1, this.visitStereochemistry(n[r], a.id, Z, j, e, 0); + for (var i = 0; i < j.length; i++) + j[i].sort(function(q, se) { + return se - q; + }); + l[r] = [r, j]; + } + let c = 0, u = 0; + for (var r = 0; r < l.length; r++) { + l[r][1].length > c && (c = l[r][1].length); + for (var i = 0; i < l[r][1].length; i++) + l[r][1][i].length > u && (u = l[r][1][i].length); + } + for (var r = 0; r < l.length; r++) { + let j = c - l[r][1].length; + for (var i = 0; i < j; i++) + l[r][1].push([]); + l[r][1].push([n[r]]); + for (var i = 0; i < l[r][1].length; i++) { + let se = u - l[r][1][i].length; + for (var s = 0; s < se; s++) + l[r][1][i].push(0); + } + } + l.sort(function(Z, j) { + for (var q = 0; q < Z[1].length; q++) + for (var se = 0; se < Z[1][q].length; se++) { + if (Z[1][q][se] > j[1][q][se]) + return -1; + if (Z[1][q][se] < j[1][q][se]) + return 1; + } + return 0; + }); + let g = new Uint8Array(h); + for (var r = 0; r < h; r++) + g[r] = l[r][0], a.value.priority = r; + let m = this.graph.vertices[n[g[0]]].position, _ = this.graph.vertices[n[g[1]]].position, v = this.graph.vertices[n[g[2]]].position, N = m.relativeClockwise(_, a.position); + m.relativeClockwise(v, a.position); + let B = N === -1, x = a.value.bracket.chirality === "@" ? -1 : 1, L = Se.parityOfPermutation(g) * x === 1 ? "R" : "S", k = "down", z = "up"; + (B && L !== "R" || !B && L !== "S") && (a.value.hydrogenDirection = "up", k = "up", z = "down"), a.value.hasHydrogen && (this.graph.getEdge(a.id, n[g[g.length - 1]]).wedge = k); + let D = new Array(n.length - 1), Y = a.value.rings.length > 1 && a.value.hasHydrogen, O = a.value.hasHydrogen ? 1 : 0; + for (var r = 0; r < g.length - O; r++) { + D[r] = new Uint32Array(2); + let j = this.graph.vertices[n[g[r]]]; + D[r][0] += j.value.isStereoCenter ? 0 : 1e5, D[r][0] += this.areVerticesInSameRing(j, a) ? 0 : 1e4, D[r][0] += j.value.isHeteroAtom() ? 1e3 : 0, D[r][0] -= j.value.subtreeDepth === 0 ? 1e3 : 0, D[r][0] += 1e3 - j.value.subtreeDepth, D[r][1] = n[g[r]]; + } + if (D.sort(function(Z, j) { + return Z[0] > j[0] ? -1 : Z[0] < j[0] ? 1 : 0; + }), !Y) { + let Z = D[0][1]; + if (a.value.hasHydrogen) + this.graph.getEdge(a.id, Z).wedge = z; + else { + let j = z; + for (var r = g.length - 1; r >= 0 && (j === k ? j = z : j = k, n[g[r]] !== Z); r--) + ; + this.graph.getEdge(a.id, Z).wedge = j; + } + } + a.value.chirality = L; + } + } + /** + * + * + * @param {Number} vertexId The id of a vertex. + * @param {(Number|null)} previousVertexId The id of the parent vertex of the vertex. + * @param {Uint8Array} visited An array containing the visited flag for all vertices in the graph. + * @param {Array} priority An array of arrays storing the atomic numbers for each level. + * @param {Number} maxDepth The maximum depth. + * @param {Number} depth The current depth. + */ + visitStereochemistry(e, t, r, i, s, a, n = 0) { + r[e] = 1; + let h = this.graph.vertices[e], l = h.value.getAtomicNumber(); + i.length <= a && i.push(Array()); + for (var c = 0; c < this.graph.getEdge(e, t).weight; c++) + i[a].push(n * 1e3 + l); + let u = this.graph.vertices[e].neighbours; + for (var c = 0; c < u.length; c++) + r[u[c]] !== 1 && a < s - 1 && this.visitStereochemistry(u[c], e, r.slice(), i, s, a + 1, l); + if (a < s - 1) { + let g = 0; + for (var c = 0; c < u.length; c++) + g += this.graph.getEdge(e, u[c]).weight; + for (var c = 0; c < h.value.getMaxBonds() - g; c++) + i.length <= a + 1 && i.push(Array()), i[a + 1].push(l * 1e3 + 1); + } + } + /** + * Creates pseudo-elements (such as Et, Me, Ac, Bz, ...) at the position of the carbon sets + * the involved atoms not to be displayed. + */ + initPseudoElements() { + for (var e = 0; e < this.graph.vertices.length; e++) { + const r = this.graph.vertices[e], i = r.neighbours; + let s = Array(i.length); + for (var t = 0; t < i.length; t++) + s[t] = this.graph.vertices[i[t]]; + if (r.getNeighbourCount() < 3 || r.value.rings.length > 0 || r.value.element === "P" || r.value.element === "C" && s.length === 3 && s[0].value.element === "N" && s[1].value.element === "N" && s[2].value.element === "N") + continue; + let a = 0, n = 0; + for (var t = 0; t < s.length; t++) { + let c = s[t], u = c.value.element, g = c.getNeighbourCount(); + u !== "C" && u !== "H" && g === 1 && a++, g > 1 && n++; + } + if (n > 1 || a < 2) + continue; + let h = null; + for (var t = 0; t < s.length; t++) { + let c = s[t]; + c.getNeighbourCount() > 1 && (h = c); + } + for (var t = 0; t < s.length; t++) { + let c = s[t]; + if (c.getNeighbourCount() > 1) + continue; + c.value.isDrawn = !1; + let u = Ci.maxBonds[c.value.element] - c.value.bondCount, g = ""; + c.value.bracket && (u = c.value.bracket.hcount, g = c.value.bracket.charge || 0), r.value.attachPseudoElement(c.value.element, h ? h.value.element : null, u, g); + } + } + for (var e = 0; e < this.graph.vertices.length; e++) { + const i = this.graph.vertices[e], s = i.value, a = s.element; + if (a === "C" || a === "H" || !s.isDrawn) + continue; + const n = i.neighbours; + let h = Array(n.length); + for (var t = 0; t < n.length; t++) + h[t] = this.graph.vertices[n[t]]; + for (var t = 0; t < h.length; t++) { + let c = h[t].value; + if (!c.hasAttachedPseudoElements || c.getAttachedPseudoElementsCount() !== 2) + continue; + const u = c.getAttachedPseudoElements(); + u.hasOwnProperty("0O") && u.hasOwnProperty("3C") && (c.isDrawn = !1, i.value.attachPseudoElement("Ac", "", 0)); + } + } + } +}; +var kg = Ng; +const Rg = Xn, je = ar, xg = Kr; +function Tg(d) { + for (var e = "", t = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", r = t.length, i = 0; i < d; i++) + e += t.charAt(Math.floor(Math.random() * r)); + return e; +} +let Eg = class dt { + constructor(e, t, r, i = !0) { + if (typeof t == "string" || t instanceof String ? this.svg = document.getElementById(t) : this.svg = t, this.container = null, this.opts = r, this.uid = Tg(5), this.gradientId = 0, this.backgroundItems = [], this.paths = [], this.vertices = [], this.gradients = [], this.highlights = [], this.drawingWidth = 0, this.drawingHeight = 0, this.halfBondThickness = this.opts.bondThickness / 2, this.themeManager = e, this.maskElements = [], this.maxX = -Number.MAX_VALUE, this.maxY = -Number.MAX_VALUE, this.minX = Number.MAX_VALUE, this.minY = Number.MAX_VALUE, i) + for (; this.svg.firstChild; ) + this.svg.removeChild(this.svg.firstChild); + this.style = document.createElementNS("http://www.w3.org/2000/svg", "style"), this.style.appendChild(document.createTextNode(` + .element { + font: ${this.opts.fontSizeLarge}pt ${this.opts.fontFamily}; + } + .sub { + font: ${this.opts.fontSizeSmall}pt ${this.opts.fontFamily}; + } + `)), this.svg ? this.svg.appendChild(this.style) : (this.container = document.createElementNS("http://www.w3.org/2000/svg", "g"), container.appendChild(this.style)); + } + constructSvg() { + let e = document.createElementNS("http://www.w3.org/2000/svg", "defs"), t = document.createElementNS("http://www.w3.org/2000/svg", "mask"), r = document.createElementNS("http://www.w3.org/2000/svg", "g"), i = document.createElementNS("http://www.w3.org/2000/svg", "g"), s = document.createElementNS("http://www.w3.org/2000/svg", "g"), a = document.createElementNS("http://www.w3.org/2000/svg", "g"), n = this.paths, h = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + h.setAttributeNS(null, "x", this.minX), h.setAttributeNS(null, "y", this.minY), h.setAttributeNS(null, "width", this.maxX - this.minX), h.setAttributeNS(null, "height", this.maxY - this.minY), h.setAttributeNS(null, "fill", "white"), t.appendChild(h), t.setAttributeNS(null, "id", this.uid + "-text-mask"); + for (let l of n) + s.appendChild(l); + for (let l of this.backgroundItems) + r.appendChild(l); + for (let l of this.highlights) + i.appendChild(l); + for (let l of this.vertices) + a.appendChild(l); + for (let l of this.maskElements) + t.appendChild(l); + for (let l of this.gradients) + e.appendChild(l); + if (s.setAttributeNS(null, "mask", "url(#" + this.uid + "-text-mask)"), this.updateViewbox(this.opts.scale), r.setAttributeNS(null, "style", `transform: translateX(${this.minX}px) translateY(${this.minY}px)`), this.svg) + this.svg.appendChild(e), this.svg.appendChild(t), this.svg.appendChild(r), this.svg.appendChild(i), this.svg.appendChild(s), this.svg.appendChild(a); + else + return this.container.appendChild(e), this.container.appendChild(t), this.container.appendChild(r), this.container.appendChild(s), this.container.appendChild(a), this.container; + } + /** + * Add a background to the svg. + */ + addLayer(e) { + this.backgroundItems.push(e.firstChild); + } + /** + * Create a linear gradient to apply to a line + * + * @param {Line} line the line to apply the gradiation to. + */ + createGradient(e) { + let t = document.createElementNS("http://www.w3.org/2000/svg", "linearGradient"), r = this.uid + `-line-${this.gradientId++}`, i = e.getLeftVector(), s = e.getRightVector(), a = i.x, n = i.y, h = s.x, l = s.y; + t.setAttributeNS(null, "id", r), t.setAttributeNS(null, "gradientUnits", "userSpaceOnUse"), t.setAttributeNS(null, "x1", a), t.setAttributeNS(null, "y1", n), t.setAttributeNS(null, "x2", h), t.setAttributeNS(null, "y2", l); + let c = document.createElementNS("http://www.w3.org/2000/svg", "stop"); + c.setAttributeNS(null, "stop-color", this.themeManager.getColor(e.getLeftElement()) || this.themeManager.getColor("C")), c.setAttributeNS(null, "offset", "20%"); + let u = document.createElementNS("http://www.w3.org/2000/svg", "stop"); + return u.setAttributeNS(null, "stop-color", this.themeManager.getColor(e.getRightElement() || this.themeManager.getColor("C"))), u.setAttributeNS(null, "offset", "100%"), t.appendChild(c), t.appendChild(u), this.gradients.push(t), r; + } + /** + * Create a tspan element for sub or super scripts that styles the text + * appropriately as one of those text types. + * + * @param {String} text the actual text + * @param {String} shift the type of text, either 'sub', or 'super' + */ + createSubSuperScripts(e, t) { + let r = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + return r.setAttributeNS(null, "baseline-shift", t), r.appendChild(document.createTextNode(e)), r.setAttributeNS(null, "class", "sub"), r; + } + static createUnicodeCharge(e) { + return e === 1 ? "⁺" : e === -1 ? "⁻" : e > 1 ? dt.createUnicodeSuperscript(e) + "⁺" : e < -1 ? dt.createUnicodeSuperscript(e) + "⁻" : ""; + } + /** + * Determine drawing dimensiosn based on vertex positions. + * + * @param {Vertex[]} vertices An array of vertices containing the vertices associated with the current molecule. + */ + determineDimensions(e) { + for (var t = 0; t < e.length; t++) { + if (!e[t].value.isDrawn) + continue; + let i = e[t].position; + this.maxX < i.x && (this.maxX = i.x), this.maxY < i.y && (this.maxY = i.y), this.minX > i.x && (this.minX = i.x), this.minY > i.y && (this.minY = i.y); + } + let r = this.opts.padding; + this.maxX += r, this.maxY += r, this.minX -= r, this.minY -= r, this.drawingWidth = this.maxX - this.minX, this.drawingHeight = this.maxY - this.minY; + } + updateViewbox(e) { + let t = this.minX, r = this.minY, i = this.maxX - this.minX, s = this.maxY - this.minY; + if (e <= 0) + if (i > s) { + let a = i - s; + s = i, r -= a / 2; + } else { + let a = s - i; + i = s, t -= a / 2; + } + else + this.svg && (this.svg.style.width = e * i + "px", this.svg.style.height = e * s + "px"); + this.svg.setAttributeNS(null, "viewBox", `${t} ${r} ${i} ${s}`); + } + /** + * Draw an svg ellipse as a ball. + * + * @param {Number} x The x position of the text. + * @param {Number} y The y position of the text. + * @param {String} elementName The name of the element (single-letter). + */ + drawBall(e, t, r) { + let i = this.opts.bondLength / 4.5; + e - i < this.minX && (this.minX = e - i), e + i > this.maxX && (this.maxX = e + i), t - i < this.minY && (this.minY = t - i), t + i > this.maxY && (this.maxY = t + i); + let s = document.createElementNS("http://www.w3.org/2000/svg", "circle"); + s.setAttributeNS(null, "cx", e), s.setAttributeNS(null, "cy", t), s.setAttributeNS(null, "r", i), s.setAttributeNS(null, "fill", this.themeManager.getColor(r)), this.vertices.push(s); + } + /** + * @param {Line} line the line object to create the wedge from + */ + drawWedge(e) { + let t = e.getLeftVector().clone(), r = e.getRightVector().clone(), i = je.normals(t, r); + i[0].normalize(), i[1].normalize(); + let s = e.getRightChiral(), a = t, n = r; + s && (a = r, n = t); + let h = je.add(a, je.multiplyScalar(i[0], this.halfBondThickness)), l = je.add(n, je.multiplyScalar(i[0], 3 + this.opts.fontSizeLarge / 4)), c = je.add(n, je.multiplyScalar(i[1], 3 + this.opts.fontSizeLarge / 4)), u = je.add(a, je.multiplyScalar(i[1], this.halfBondThickness)), g = document.createElementNS("http://www.w3.org/2000/svg", "polygon"), m = this.createGradient(e, t.x, t.y, r.x, r.y); + g.setAttributeNS(null, "points", `${h.x},${h.y} ${l.x},${l.y} ${c.x},${c.y} ${u.x},${u.y}`), g.setAttributeNS(null, "fill", `url('#${m}')`), this.paths.push(g); + } + /* Draw a highlight for an atom + * + * @param {Number} x The x position of the highlight + * @param {Number} y The y position of the highlight + * @param {string} color The color of the highlight, default #03fc9d + */ + drawAtomHighlight(e, t, r = "#03fc9d") { + let i = document.createElementNS("http://www.w3.org/2000/svg", "circle"); + i.setAttributeNS(null, "cx", e), i.setAttributeNS(null, "cy", t), i.setAttributeNS(null, "r", this.opts.bondLength / 3), i.setAttributeNS(null, "fill", r), this.highlights.push(i); + } + /** + * Draw a dashed wedge on the canvas. + * + * @param {Line} line A line. + */ + drawDashedWedge(e) { + if (isNaN(e.from.x) || isNaN(e.from.y) || isNaN(e.to.x) || isNaN(e.to.y)) + return; + let t = e.getLeftVector().clone(), r = e.getRightVector().clone(), i = je.normals(t, r); + i[0].normalize(), i[1].normalize(); + let s = e.getRightChiral(), a, n; + s ? (a = r, n = t) : (a = t, n = r); + let h = je.subtract(n, a).normalize(), l = e.getLength(), c = 1.25 / (l / (this.opts.bondLength / 10)), u = this.createGradient(e); + for (let g = 0; g < 1; g += c) { + let m = je.multiplyScalar(h, g * l), _ = je.add(a, m), v = this.opts.fontSizeLarge / 2 * g, N = je.multiplyScalar(i[0], v); + _.subtract(N); + let B = _.clone(); + B.add(je.multiplyScalar(N, 2)), this.drawLine(new Rg(_, B), null, u); + } + } + /** + * Draws a debug dot at a given coordinate and adds text. + * + * @param {Number} x The x coordinate. + * @param {Number} y The y coordindate. + * @param {String} [debugText=''] A string. + * @param {String} [color='#f00'] A color in hex form. + */ + drawDebugPoint(e, t, r = "", i = "#f00") { + let s = document.createElementNS("http://www.w3.org/2000/svg", "circle"); + s.setAttributeNS(null, "cx", e), s.setAttributeNS(null, "cy", t), s.setAttributeNS(null, "r", "2"), s.setAttributeNS(null, "fill", "#f00"), this.vertices.push(s), this.drawDebugText(e, t, r); + } + /** + * Draws a debug text message at a given position + * + * @param {Number} x The x coordinate. + * @param {Number} y The y coordinate. + * @param {String} text The debug text. + */ + drawDebugText(e, t, r) { + let i = document.createElementNS("http://www.w3.org/2000/svg", "text"); + i.setAttributeNS(null, "x", e), i.setAttributeNS(null, "y", t), i.setAttributeNS(null, "class", "debug"), i.setAttributeNS(null, "fill", "#ff0000"), i.setAttributeNS(null, "style", ` + font: 5px Droid Sans, sans-serif; + `), i.appendChild(document.createTextNode(r)), this.vertices.push(i); + } + /** + * Draws a ring. + * + * @param {x} x The x coordinate of the ring. + * @param {y} r The y coordinate of the ring. + * @param {s} s The size of the ring. + */ + drawRing(e, t, r) { + let i = document.createElementNS("http://www.w3.org/2000/svg", "circle"), s = xg.apothemFromSideLength(this.opts.bondLength, r); + i.setAttributeNS(null, "cx", e), i.setAttributeNS(null, "cy", t), i.setAttributeNS(null, "r", s - this.opts.bondSpacing), i.setAttributeNS(null, "stroke", this.themeManager.getColor("C")), i.setAttributeNS(null, "stroke-width", this.opts.bondThickness), i.setAttributeNS(null, "fill", "none"), this.paths.push(i); + } + /** + * Draws a line. + * + * @param {Line} line A line. + * @param {Boolean} dashed defaults to false. + * @param {String} gradient gradient url. Defaults to null. + */ + drawLine(e, t = !1, r = null, i = "round") { + this.opts; + let s = [ + ["stroke-width", this.opts.bondThickness], + ["stroke-linecap", i], + ["stroke-dasharray", t ? "5, 5" : "none"] + ], a = e.getLeftVector(), n = e.getRightVector(), h = a.x, l = a.y, c = n.x, u = n.y, g = s.map((_) => _.join(":")).join(";"), m = document.createElementNS("http://www.w3.org/2000/svg", "line"); + m.setAttributeNS(null, "x1", h), m.setAttributeNS(null, "y1", l), m.setAttributeNS(null, "x2", c), m.setAttributeNS(null, "y2", u), m.setAttributeNS(null, "style", g), this.paths.push(m), r == null && (r = this.createGradient(e, h, l, c, u)), m.setAttributeNS(null, "stroke", `url('#${r}')`); + } + /** + * Draw a point. + * + * @param {Number} x The x position of the point. + * @param {Number} y The y position of the point. + * @param {String} elementName The name of the element (single-letter). + */ + drawPoint(e, t, r) { + let i = 0.75; + e - i < this.minX && (this.minX = e - i), e + i > this.maxX && (this.maxX = e + i), t - i < this.minY && (this.minY = t - i), t + i > this.maxY && (this.maxY = t + i); + let s = document.createElementNS("http://www.w3.org/2000/svg", "circle"); + s.setAttributeNS(null, "cx", e), s.setAttributeNS(null, "cy", t), s.setAttributeNS(null, "r", "1.5"), s.setAttributeNS(null, "fill", "black"), this.maskElements.push(s); + let a = document.createElementNS("http://www.w3.org/2000/svg", "circle"); + a.setAttributeNS(null, "cx", e), a.setAttributeNS(null, "cy", t), a.setAttributeNS(null, "r", i), a.setAttributeNS(null, "fill", this.themeManager.getColor(r)), this.vertices.push(a); + } + /** + * Draw a text to the canvas. + * + * @param {Number} x The x position of the text. + * @param {Number} y The y position of the text. + * @param {String} elementName The name of the element (single-letter). + * @param {Number} hydrogens The number of hydrogen atoms. + * @param {String} direction The direction of the text in relation to the associated vertex. + * @param {Boolean} isTerminal A boolean indicating whether or not the vertex is terminal. + * @param {Number} charge The charge of the atom. + * @param {Number} isotope The isotope number. + * @param {Number} totalVertices The total number of vertices in the graph. + * @param {Object} attachedPseudoElement A map with containing information for pseudo elements or concatinated elements. The key is comprised of the element symbol and the hydrogen count. + * @param {String} attachedPseudoElement.element The element symbol. + * @param {Number} attachedPseudoElement.count The number of occurences that match the key. + * @param {Number} attachedPseudoElement.hyrogenCount The number of hydrogens attached to each atom matching the key. + */ + drawText(e, t, r, i, s, a, n, h, l, c = {}) { + let u = [], g = r; + n !== 0 && n !== null && (g += dt.createUnicodeCharge(n)), h !== 0 && h !== null && (g = dt.createUnicodeSuperscript(h) + g), u.push([g, r]), i === 1 ? u.push(["H", "H"]) : i > 1 && u.push(["H" + dt.createUnicodeSubscript(i), "H"]), n === 1 && r === "N" && c.hasOwnProperty("0O") && c.hasOwnProperty("0O-1") && (c = { "0O": { element: "O", count: 2, hydrogenCount: 0, previousElement: "C", charge: "" } }, n = 0); + for (let m in c) { + if (!c.hasOwnProperty(m)) + continue; + let _ = c[m], v = _.element; + _.count > 1 && (v += dt.createUnicodeSubscript(_.count)), _.charge !== "" && (v += dt.createUnicodeCharge(n)), u.push([v, _.element]), _.hydrogenCount === 1 ? u.push(["H", "H"]) : _.hydrogenCount > 1 && u.push(["H" + dt.createUnicodeSubscript(_.hydrogenCount), "H"]); + } + this.write(u, s, e, t, l === 1); + } + write(e, t, r, i, s) { + let a = dt.measureText(e[0][1], this.opts.fontSizeLarge, this.opts.fontFamily); + t === "left" && e[0][0] !== e[0][1] && (a.width *= 2), s ? (r + a.width * e.length > this.maxX && (this.maxX = r + a.width * e.length), r - a.width / 2 < this.minX && (this.minX = r - a.width / 2), i - a.height < this.minY && (this.minY = i - a.height), i + a.height > this.maxY && (this.maxY = i + a.height)) : (t !== "right" ? (r + a.width * e.length > this.maxX && (this.maxX = r + a.width * e.length), r - a.width * e.length < this.minX && (this.minX = r - a.width * e.length)) : t !== "left" && (r + a.width * e.length > this.maxX && (this.maxX = r + a.width * e.length), r - a.width / 2 < this.minX && (this.minX = r - a.width / 2)), i - a.height < this.minY && (this.minY = i - a.height), i + a.height > this.maxY && (this.maxY = i + a.height), t === "down" && i + 0.8 * a.height * e.length > this.maxY && (this.maxY = i + 0.8 * a.height * e.length), t === "up" && i - 0.8 * a.height * e.length < this.minY && (this.minY = i - 0.8 * a.height * e.length)); + let n = r, h = i, l = document.createElementNS("http://www.w3.org/2000/svg", "text"); + l.setAttributeNS(null, "class", "element"); + let c = document.createElementNS("http://www.w3.org/2000/svg", "g"); + l.setAttributeNS(null, "fill", "#ffffff"), t === "left" && (e = e.reverse()), (t === "right" || t === "down" || t === "up") && (r -= a.width / 2), t === "left" && (r += a.width / 2), e.forEach((m, _) => { + const v = m[0], N = m[1]; + let B = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + B.setAttributeNS(null, "fill", this.themeManager.getColor(N)), B.textContent = v, (t === "up" || t === "down") && (B.setAttributeNS(null, "x", "0px"), t === "up" ? B.setAttributeNS(null, "y", `-${0.9 * _}em`) : B.setAttributeNS(null, "y", `${0.9 * _}em`)), l.appendChild(B); + }), l.setAttributeNS(null, "data-direction", t), t === "left" || t === "right" ? (l.setAttributeNS(null, "dominant-baseline", "alphabetic"), l.setAttributeNS(null, "y", "0.36em")) : l.setAttributeNS(null, "dominant-baseline", "central"), t === "left" && l.setAttributeNS(null, "text-anchor", "end"), c.appendChild(l), c.setAttributeNS(null, "style", `transform: translateX(${r}px) translateY(${i}px)`); + let u = this.opts.fontSizeLarge * 0.75; + e[0][1].length > 1 && (u = this.opts.fontSizeLarge * 1.1); + let g = document.createElementNS("http://www.w3.org/2000/svg", "circle"); + g.setAttributeNS(null, "cx", n), g.setAttributeNS(null, "cy", h), g.setAttributeNS(null, "r", u), g.setAttributeNS(null, "fill", "black"), this.maskElements.push(g), this.vertices.push(c); + } + /** + * Draw the wrapped SVG to a canvas. + * @param {HTMLCanvasElement} canvas The canvas element to draw the svg to. + */ + toCanvas(e, t, r) { + (typeof e == "string" || e instanceof String) && (e = document.getElementById(e)); + let i = new Image(); + i.onload = function() { + e.width = t, e.height = r, e.getContext("2d").drawImage(i, 0, 0, t, r); + }, i.src = "data:image/svg+xml;charset-utf-8," + encodeURIComponent(this.svg.outerHTML); + } + static createUnicodeSubscript(e) { + let t = ""; + return e.toString().split("").forEach((r) => { + t += ["₀", "₁", "₂", "₃", "₄", "₅", "₆", "₇", "₈", "₉"][parseInt(r)]; + }), t; + } + static createUnicodeSuperscript(e) { + let t = ""; + return e.toString().split("").forEach((r) => { + parseInt(r) && (t += ["⁰", "¹", "²", "³", "⁴", "⁵", "⁶", "⁷", "⁸", "⁹"][parseInt(r)]); + }), t; + } + static replaceNumbersWithSubscript(e) { + let t = { + 0: "₀", + 1: "₁", + 2: "₂", + 3: "₃", + 4: "₄", + 5: "₅", + 6: "₆", + 7: "₇", + 8: "₈", + 9: "₉" + }; + for (const [r, i] of Object.entries(t)) + e = e.replaceAll(r, i); + return e; + } + static measureText(e, t, r, i = 0.9) { + const a = document.createElement("canvas").getContext("2d"); + a.font = `${t}pt ${r}`; + let n = a.measureText(e), h = Math.abs(n.actualBoundingBoxLeft) + Math.abs(n.actualBoundingBoxRight); + return { + width: n.width > h ? n.width : h, + height: (Math.abs(n.actualBoundingBoxAscent) + Math.abs(n.actualBoundingBoxAscent)) * i + }; + } + /** + * Convert an SVG to a canvas. Warning: This happens async! + * + * @param {SVGElement} svg + * @param {HTMLCanvasElement} canvas + * @param {Number} width + * @param {Number} height + * @param {CallableFunction} callback + * @returns {HTMLCanvasElement} The input html canvas element after drawing to. + */ + static svgToCanvas(e, t, r, i, s = null) { + e.setAttributeNS(null, "width", r), e.setAttributeNS(null, "height", i); + let a = new Image(); + return a.onload = function() { + t.width = r, t.height = i; + let n = t.getContext("2d"); + n.imageSmoothingEnabled = !1, n.drawImage(a, 0, 0, r, i), s && s(t); + }, a.onerror = function(n) { + console.log(n); + }, a.src = "data:image/svg+xml;charset-utf-8," + encodeURIComponent(e.outerHTML), t; + } + /** + * Convert an SVG to a canvas. Warning: This happens async! + * + * @param {SVGElement} svg + * @param {HTMLImageElement} canvas + * @param {Number} width + * @param {Number} height + */ + static svgToImg(e, t, r, i) { + let s = document.createElement("canvas"); + this.svgToCanvas(e, s, r, i, (a) => { + t.src = s.toDataURL("image/png"); + }); + } + /** + * Create an SVG element containing text. + * @param {String} text + * @param {*} themeManager + * @param {*} options + * @returns {{svg: SVGElement, width: Number, height: Number}} The SVG element containing the text and its dimensions. + */ + static writeText(e, t, r, i, s = Number.MAX_SAFE_INTEGER) { + let a = document.createElementNS("http://www.w3.org/2000/svg", "svg"), n = document.createElementNS("http://www.w3.org/2000/svg", "style"); + n.appendChild(document.createTextNode(` + .text { + font: ${r}pt ${i}; + dominant-baseline: ideographic; + } + `)), a.appendChild(n); + let h = document.createElementNS("http://www.w3.org/2000/svg", "text"); + h.setAttributeNS(null, "class", "text"); + let l = 0, c = 0, u = []; + return e.split(` +`).forEach((g) => { + let m = dt.measureText(g, r, i, 1); + if (m.width >= s) { + let _ = 0, v = 0, N = g.split(" "), B = 0; + for (let x = 0; x < N.length; x++) { + let L = dt.measureText(N[x], r, i, 1); + _ + L.width > s && (u.push({ + text: N.slice(B, x).join(" "), + width: _, + height: v + }), _ = 0, v = 0, B = x), L.height > v && (v = L.height), _ += L.width; + } + B < N.length && u.push({ + text: N.slice(B, N.length).join(" "), + width: _, + height: v + }); + } else + u.push({ + text: g, + width: m.width, + height: m.height + }); + }), u.forEach((g, m) => { + c += g.height; + let _ = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + _.setAttributeNS(null, "fill", t.getColor("C")), _.textContent = g.text, _.setAttributeNS(null, "x", "0px"), _.setAttributeNS(null, "y", `${c}px`), h.appendChild(_), g.width > l && (l = g.width); + }), a.appendChild(h), { svg: a, width: l, height: c }; + } +}; +var Un = Eg; +function Lg(d) { + function e(g, m) { + var _ = g.length, v = _ === 0 || _ > 0 && _ - 1 in g, N = 0; + if (v) + for (; N < _ && m.call(g[N], N, g[N]) !== !1; N++) + ; + else + for (N in g) + if (m.call(g[N], N, g[N]) === !1) + break; + } + function t(g) { + var m = parseInt(g).toString(16); + return m.length == 1 ? "0" + m : m; + } + function r(g, m, _, v) { + return v = parseInt(v), v === void 0 || v === 255 ? "#" + t(g) + t(m) + t(_) : v === 0 ? !1 : "rgba(" + g + "," + m + "," + _ + "," + v / 255 + ")"; + } + function i(g, m, _) { + return "M" + g + " " + m + "h" + _; + } + function s(g, m) { + return ' +`; + } + function a(g) { + var m = ""; + return e(g, function(_, v) { + if (_ = r.apply(null, _.split(",")), _ !== !1) { + var N = [], B, x = 1; + e(v, function() { + B && this[1] === B[1] && this[0] === B[0] + x ? x++ : (B && (N.push(i(B[0], B[1], x)), x = 1), B = this); + }), N.push(i(B[0], B[1], x)), m += s(_, N.join("")); + } + }), m; + } + var n = function(g) { + var m = {}, _ = g.data, v = _.length, N = g.width; + g.height; + for (var B = 0, x = 0, L = 0, k; L < v; L += 4) + _[L + 3] > 0 && (k = _[L] + "," + _[L + 1] + "," + _[L + 2] + "," + _[L + 3], m[k] = m[k] || [], B = L / 4 % N, x = Math.floor(L / 4 / N), m[k].push([B, x])); + return m; + }; + let h = n(d), l = a(h), c = '' + l + ""; + var u = document.createElement("div"); + return u.innerHTML = c, u.firstChild; +} +var Mg = Lg, ml = { exports: {} }; +/** + * chroma.js - JavaScript library for color conversions + * + * Copyright (c) 2011-2019, Gregor Aisch + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name Gregor Aisch may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL GREGOR AISCH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ------------------------------------------------------- + * + * chroma.js includes colors from colorbrewer2.org, which are released under + * the following license: + * + * Copyright (c) 2002 Cynthia Brewer, Mark Harrower, + * and The Pennsylvania State University. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the License. + * + * ------------------------------------------------------ + * + * Named colors are taken from X11 Color Names. + * http://www.w3.org/TR/css3-color/#svg-color + * + * @preserve + */ +(function(d, e) { + (function(t, r) { + d.exports = r(); + })(eg, function() { + for (var t = function(o, f, p) { + return f === void 0 && (f = 0), p === void 0 && (p = 1), o < f ? f : o > p ? p : o; + }, r = t, i = function(o) { + o._clipped = !1, o._unclipped = o.slice(0); + for (var f = 0; f <= 3; f++) + f < 3 ? ((o[f] < 0 || o[f] > 255) && (o._clipped = !0), o[f] = r(o[f], 0, 255)) : f === 3 && (o[f] = r(o[f], 0, 1)); + return o; + }, s = {}, a = 0, n = ["Boolean", "Number", "String", "Function", "Array", "Date", "RegExp", "Undefined", "Null"]; a < n.length; a += 1) { + var h = n[a]; + s["[object " + h + "]"] = h.toLowerCase(); + } + var l = function(o) { + return s[Object.prototype.toString.call(o)] || "object"; + }, c = l, u = function(o, f) { + return f === void 0 && (f = null), o.length >= 3 ? Array.prototype.slice.call(o) : c(o[0]) == "object" && f ? f.split("").filter(function(p) { + return o[0][p] !== void 0; + }).map(function(p) { + return o[0][p]; + }) : o[0]; + }, g = l, m = function(o) { + if (o.length < 2) + return null; + var f = o.length - 1; + return g(o[f]) == "string" ? o[f].toLowerCase() : null; + }, _ = Math.PI, v = { + clip_rgb: i, + limit: t, + type: l, + unpack: u, + last: m, + PI: _, + TWOPI: _ * 2, + PITHIRD: _ / 3, + DEG2RAD: _ / 180, + RAD2DEG: 180 / _ + }, N = { + format: {}, + autodetect: [] + }, B = v.last, x = v.clip_rgb, L = v.type, k = N, z = function() { + for (var f = [], p = arguments.length; p--; ) + f[p] = arguments[p]; + var b = this; + if (L(f[0]) === "object" && f[0].constructor && f[0].constructor === this.constructor) + return f[0]; + var C = B(f), A = !1; + if (!C) { + A = !0, k.sorted || (k.autodetect = k.autodetect.sort(function(I, V) { + return V.p - I.p; + }), k.sorted = !0); + for (var S = 0, R = k.autodetect; S < R.length; S += 1) { + var E = R[S]; + if (C = E.test.apply(E, f), C) + break; + } + } + if (k.format[C]) { + var P = k.format[C].apply(null, A ? f : f.slice(0, -1)); + b._rgb = x(P); + } else + throw new Error("unknown format: " + f); + b._rgb.length === 3 && b._rgb.push(1); + }; + z.prototype.toString = function() { + return L(this.hex) == "function" ? this.hex() : "[" + this._rgb.join(",") + "]"; + }; + var D = z, Y = function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + return new (Function.prototype.bind.apply(Y.Color, [null].concat(o)))(); + }; + Y.Color = D, Y.version = "2.4.2"; + var O = Y, Z = v.unpack, j = Math.max, q = function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + var p = Z(o, "rgb"), b = p[0], C = p[1], A = p[2]; + b = b / 255, C = C / 255, A = A / 255; + var S = 1 - j(b, j(C, A)), R = S < 1 ? 1 / (1 - S) : 0, E = (1 - b - S) * R, P = (1 - C - S) * R, I = (1 - A - S) * R; + return [E, P, I, S]; + }, se = q, ye = v.unpack, ke = function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + o = ye(o, "cmyk"); + var p = o[0], b = o[1], C = o[2], A = o[3], S = o.length > 4 ? o[4] : 1; + return A === 1 ? [0, 0, 0, S] : [ + p >= 1 ? 0 : 255 * (1 - p) * (1 - A), + // r + b >= 1 ? 0 : 255 * (1 - b) * (1 - A), + // g + C >= 1 ? 0 : 255 * (1 - C) * (1 - A), + // b + S + ]; + }, xe = ke, we = O, Ee = D, Qe = N, Ce = v.unpack, Ae = v.type, Be = se; + Ee.prototype.cmyk = function() { + return Be(this._rgb); + }, we.cmyk = function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + return new (Function.prototype.bind.apply(Ee, [null].concat(o, ["cmyk"])))(); + }, Qe.format.cmyk = xe, Qe.autodetect.push({ + p: 2, + test: function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + if (o = Ce(o, "cmyk"), Ae(o) === "array" && o.length === 4) + return "cmyk"; + } + }); + var st = v.unpack, It = v.last, wt = function(o) { + return Math.round(o * 100) / 100; + }, K = function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + var p = st(o, "hsla"), b = It(o) || "lsa"; + return p[0] = wt(p[0] || 0), p[1] = wt(p[1] * 100) + "%", p[2] = wt(p[2] * 100) + "%", b === "hsla" || p.length > 3 && p[3] < 1 ? (p[3] = p.length > 3 ? p[3] : 1, b = "hsla") : p.length = 3, b + "(" + p.join(",") + ")"; + }, Ot = K, J = v.unpack, Te = function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + o = J(o, "rgba"); + var p = o[0], b = o[1], C = o[2]; + p /= 255, b /= 255, C /= 255; + var A = Math.min(p, b, C), S = Math.max(p, b, C), R = (S + A) / 2, E, P; + return S === A ? (E = 0, P = Number.NaN) : E = R < 0.5 ? (S - A) / (S + A) : (S - A) / (2 - S - A), p == S ? P = (b - C) / (S - A) : b == S ? P = 2 + (C - p) / (S - A) : C == S && (P = 4 + (p - b) / (S - A)), P *= 60, P < 0 && (P += 360), o.length > 3 && o[3] !== void 0 ? [P, E, R, o[3]] : [P, E, R]; + }, et = Te, Ie = v.unpack, Ye = v.last, Ue = Ot, Ge = et, De = Math.round, Ze = function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + var p = Ie(o, "rgba"), b = Ye(o) || "rgb"; + return b.substr(0, 3) == "hsl" ? Ue(Ge(p), b) : (p[0] = De(p[0]), p[1] = De(p[1]), p[2] = De(p[2]), (b === "rgba" || p.length > 3 && p[3] < 1) && (p[3] = p.length > 3 ? p[3] : 1, b = "rgba"), b + "(" + p.slice(0, b === "rgb" ? 3 : 4).join(",") + ")"); + }, He = Ze, We = v.unpack, Le = Math.round, qe = function() { + for (var o, f = [], p = arguments.length; p--; ) + f[p] = arguments[p]; + f = We(f, "hsl"); + var b = f[0], C = f[1], A = f[2], S, R, E; + if (C === 0) + S = R = E = A * 255; + else { + var P = [0, 0, 0], I = [0, 0, 0], V = A < 0.5 ? A * (1 + C) : A + C - A * C, F = 2 * A - V, U = b / 360; + P[0] = U + 1 / 3, P[1] = U, P[2] = U - 1 / 3; + for (var G = 0; G < 3; G++) + P[G] < 0 && (P[G] += 1), P[G] > 1 && (P[G] -= 1), 6 * P[G] < 1 ? I[G] = F + (V - F) * 6 * P[G] : 2 * P[G] < 1 ? I[G] = V : 3 * P[G] < 2 ? I[G] = F + (V - F) * (2 / 3 - P[G]) * 6 : I[G] = F; + o = [Le(I[0] * 255), Le(I[1] * 255), Le(I[2] * 255)], S = o[0], R = o[1], E = o[2]; + } + return f.length > 3 ? [S, R, E, f[3]] : [S, R, E, 1]; + }, Lt = qe, yt = Lt, Vt = N, Xt = /^rgb\(\s*(-?\d+),\s*(-?\d+)\s*,\s*(-?\d+)\s*\)$/, Yt = /^rgba\(\s*(-?\d+),\s*(-?\d+)\s*,\s*(-?\d+)\s*,\s*([01]|[01]?\.\d+)\)$/, Ft = /^rgb\(\s*(-?\d+(?:\.\d+)?)%,\s*(-?\d+(?:\.\d+)?)%\s*,\s*(-?\d+(?:\.\d+)?)%\s*\)$/, _t = /^rgba\(\s*(-?\d+(?:\.\d+)?)%,\s*(-?\d+(?:\.\d+)?)%\s*,\s*(-?\d+(?:\.\d+)?)%\s*,\s*([01]|[01]?\.\d+)\)$/, zt = /^hsl\(\s*(-?\d+(?:\.\d+)?),\s*(-?\d+(?:\.\d+)?)%\s*,\s*(-?\d+(?:\.\d+)?)%\s*\)$/, Gt = /^hsla\(\s*(-?\d+(?:\.\d+)?),\s*(-?\d+(?:\.\d+)?)%\s*,\s*(-?\d+(?:\.\d+)?)%\s*,\s*([01]|[01]?\.\d+)\)$/, Ut = Math.round, Zt = function(o) { + o = o.toLowerCase().trim(); + var f; + if (Vt.format.named) + try { + return Vt.format.named(o); + } catch { + } + if (f = o.match(Xt)) { + for (var p = f.slice(1, 4), b = 0; b < 3; b++) + p[b] = +p[b]; + return p[3] = 1, p; + } + if (f = o.match(Yt)) { + for (var C = f.slice(1, 5), A = 0; A < 4; A++) + C[A] = +C[A]; + return C; + } + if (f = o.match(Ft)) { + for (var S = f.slice(1, 4), R = 0; R < 3; R++) + S[R] = Ut(S[R] * 2.55); + return S[3] = 1, S; + } + if (f = o.match(_t)) { + for (var E = f.slice(1, 5), P = 0; P < 3; P++) + E[P] = Ut(E[P] * 2.55); + return E[3] = +E[3], E; + } + if (f = o.match(zt)) { + var I = f.slice(1, 4); + I[1] *= 0.01, I[2] *= 0.01; + var V = yt(I); + return V[3] = 1, V; + } + if (f = o.match(Gt)) { + var F = f.slice(1, 4); + F[1] *= 0.01, F[2] *= 0.01; + var U = yt(F); + return U[3] = +f[4], U; + } + }; + Zt.test = function(o) { + return Xt.test(o) || Yt.test(o) || Ft.test(o) || _t.test(o) || zt.test(o) || Gt.test(o); + }; + var Bi = Zt, Di = O, Fr = D, Jr = N, Qr = v.type, Pi = He, ei = Bi; + Fr.prototype.css = function(o) { + return Pi(this._rgb, o); + }, Di.css = function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + return new (Function.prototype.bind.apply(Fr, [null].concat(o, ["css"])))(); + }, Jr.format.css = ei, Jr.autodetect.push({ + p: 5, + test: function(o) { + for (var f = [], p = arguments.length - 1; p-- > 0; ) + f[p] = arguments[p + 1]; + if (!f.length && Qr(o) === "string" && ei.test(o)) + return "css"; + } + }); + var ti = D, ri = O, ii = N, $i = v.unpack; + ii.format.gl = function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + var p = $i(o, "rgba"); + return p[0] *= 255, p[1] *= 255, p[2] *= 255, p; + }, ri.gl = function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + return new (Function.prototype.bind.apply(ti, [null].concat(o, ["gl"])))(); + }, ti.prototype.gl = function() { + var o = this._rgb; + return [o[0] / 255, o[1] / 255, o[2] / 255, o[3]]; + }; + var ni = v.unpack, si = function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + var p = ni(o, "rgb"), b = p[0], C = p[1], A = p[2], S = Math.min(b, C, A), R = Math.max(b, C, A), E = R - S, P = E * 100 / 255, I = S / (255 - E) * 100, V; + return E === 0 ? V = Number.NaN : (b === R && (V = (C - A) / E), C === R && (V = 2 + (A - b) / E), A === R && (V = 4 + (b - C) / E), V *= 60, V < 0 && (V += 360)), [V, P, I]; + }, Ii = si, Oi = v.unpack, Fi = Math.floor, zi = function() { + for (var o, f, p, b, C, A, S = [], R = arguments.length; R--; ) + S[R] = arguments[R]; + S = Oi(S, "hcg"); + var E = S[0], P = S[1], I = S[2], V, F, U; + I = I * 255; + var G = P * 255; + if (P === 0) + V = F = U = I; + else { + E === 360 && (E = 0), E > 360 && (E -= 360), E < 0 && (E += 360), E /= 60; + var ae = Fi(E), he = E - ae, ue = I * (1 - P), de = ue + G * (1 - he), Ve = ue + G * he, ze = ue + G; + switch (ae) { + case 0: + o = [ze, Ve, ue], V = o[0], F = o[1], U = o[2]; + break; + case 1: + f = [de, ze, ue], V = f[0], F = f[1], U = f[2]; + break; + case 2: + p = [ue, ze, Ve], V = p[0], F = p[1], U = p[2]; + break; + case 3: + b = [ue, de, ze], V = b[0], F = b[1], U = b[2]; + break; + case 4: + C = [Ve, ue, ze], V = C[0], F = C[1], U = C[2]; + break; + case 5: + A = [ze, ue, de], V = A[0], F = A[1], U = A[2]; + break; + } + } + return [V, F, U, S.length > 3 ? S[3] : 1]; + }, Hi = zi, Wi = v.unpack, qi = v.type, Vi = O, ai = D, li = N, y = Ii; + ai.prototype.hcg = function() { + return y(this._rgb); + }, Vi.hcg = function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + return new (Function.prototype.bind.apply(ai, [null].concat(o, ["hcg"])))(); + }, li.format.hcg = Hi, li.autodetect.push({ + p: 1, + test: function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + if (o = Wi(o, "hcg"), qi(o) === "array" && o.length === 3) + return "hcg"; + } + }); + var vr = v.unpack, ht = v.last, Kt = Math.round, mr = function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + var p = vr(o, "rgba"), b = p[0], C = p[1], A = p[2], S = p[3], R = ht(o) || "auto"; + S === void 0 && (S = 1), R === "auto" && (R = S < 1 ? "rgba" : "rgb"), b = Kt(b), C = Kt(C), A = Kt(A); + var E = b << 16 | C << 8 | A, P = "000000" + E.toString(16); + P = P.substr(P.length - 6); + var I = "0" + Kt(S * 255).toString(16); + switch (I = I.substr(I.length - 2), R.toLowerCase()) { + case "rgba": + return "#" + P + I; + case "argb": + return "#" + I + P; + default: + return "#" + P; + } + }, Ne = mr, ft = /^#?([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/, Xi = /^#?([A-Fa-f0-9]{8}|[A-Fa-f0-9]{4})$/, oi = function(o) { + if (o.match(ft)) { + (o.length === 4 || o.length === 7) && (o = o.substr(1)), o.length === 3 && (o = o.split(""), o = o[0] + o[0] + o[1] + o[1] + o[2] + o[2]); + var f = parseInt(o, 16), p = f >> 16, b = f >> 8 & 255, C = f & 255; + return [p, b, C, 1]; + } + if (o.match(Xi)) { + (o.length === 5 || o.length === 9) && (o = o.substr(1)), o.length === 4 && (o = o.split(""), o = o[0] + o[0] + o[1] + o[1] + o[2] + o[2] + o[3] + o[3]); + var A = parseInt(o, 16), S = A >> 24 & 255, R = A >> 16 & 255, E = A >> 8 & 255, P = Math.round((A & 255) / 255 * 100) / 100; + return [S, R, E, P]; + } + throw new Error("unknown hex color: " + o); + }, zr = oi, Q = O, Hr = D, Yi = v.type, lr = N, jt = Ne; + Hr.prototype.hex = function(o) { + return jt(this._rgb, o); + }, Q.hex = function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + return new (Function.prototype.bind.apply(Hr, [null].concat(o, ["hex"])))(); + }, lr.format.hex = zr, lr.autodetect.push({ + p: 4, + test: function(o) { + for (var f = [], p = arguments.length - 1; p-- > 0; ) + f[p] = arguments[p + 1]; + if (!f.length && Yi(o) === "string" && [3, 4, 5, 6, 7, 8, 9].indexOf(o.length) >= 0) + return "hex"; + } + }); + var Gi = v.unpack, or = v.TWOPI, Ui = Math.min, Zi = Math.sqrt, hi = Math.acos, fi = function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + var p = Gi(o, "rgb"), b = p[0], C = p[1], A = p[2]; + b /= 255, C /= 255, A /= 255; + var S, R = Ui(b, C, A), E = (b + C + A) / 3, P = E > 0 ? 1 - R / E : 0; + return P === 0 ? S = NaN : (S = (b - C + (b - A)) / 2, S /= Zi((b - C) * (b - C) + (b - A) * (C - A)), S = hi(S), A > C && (S = or - S), S /= or), [S * 360, P, E]; + }, Ki = fi, ui = v.unpack, Wr = v.limit, Jt = v.TWOPI, qr = v.PITHIRD, Qt = Math.cos, ji = function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + o = ui(o, "hsi"); + var p = o[0], b = o[1], C = o[2], A, S, R; + return isNaN(p) && (p = 0), isNaN(b) && (b = 0), p > 360 && (p -= 360), p < 0 && (p += 360), p /= 360, p < 1 / 3 ? (R = (1 - b) / 3, A = (1 + b * Qt(Jt * p) / Qt(qr - Jt * p)) / 3, S = 1 - (R + A)) : p < 2 / 3 ? (p -= 1 / 3, A = (1 - b) / 3, S = (1 + b * Qt(Jt * p) / Qt(qr - Jt * p)) / 3, R = 1 - (A + S)) : (p -= 2 / 3, S = (1 - b) / 3, R = (1 + b * Qt(Jt * p) / Qt(qr - Jt * p)) / 3, A = 1 - (S + R)), A = Wr(C * A * 3), S = Wr(C * S * 3), R = Wr(C * R * 3), [A * 255, S * 255, R * 255, o.length > 3 ? o[3] : 1]; + }, Ji = ji, Qi = v.unpack, M = v.type, w = O, $ = D, T = N, H = Ki; + $.prototype.hsi = function() { + return H(this._rgb); + }, w.hsi = function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + return new (Function.prototype.bind.apply($, [null].concat(o, ["hsi"])))(); + }, T.format.hsi = Ji, T.autodetect.push({ + p: 2, + test: function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + if (o = Qi(o, "hsi"), M(o) === "array" && o.length === 3) + return "hsi"; + } + }); + var X = v.unpack, ee = v.type, Oe = O, at = D, ut = N, Rl = et; + at.prototype.hsl = function() { + return Rl(this._rgb); + }, Oe.hsl = function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + return new (Function.prototype.bind.apply(at, [null].concat(o, ["hsl"])))(); + }, ut.format.hsl = Lt, ut.autodetect.push({ + p: 2, + test: function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + if (o = X(o, "hsl"), ee(o) === "array" && o.length === 3) + return "hsl"; + } + }); + var xl = v.unpack, Tl = Math.min, El = Math.max, Ll = function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + o = xl(o, "rgb"); + var p = o[0], b = o[1], C = o[2], A = Tl(p, b, C), S = El(p, b, C), R = S - A, E, P, I; + return I = S / 255, S === 0 ? (E = Number.NaN, P = 0) : (P = R / S, p === S && (E = (b - C) / R), b === S && (E = 2 + (C - p) / R), C === S && (E = 4 + (p - b) / R), E *= 60, E < 0 && (E += 360)), [E, P, I]; + }, Ml = Ll, Bl = v.unpack, Dl = Math.floor, Pl = function() { + for (var o, f, p, b, C, A, S = [], R = arguments.length; R--; ) + S[R] = arguments[R]; + S = Bl(S, "hsv"); + var E = S[0], P = S[1], I = S[2], V, F, U; + if (I *= 255, P === 0) + V = F = U = I; + else { + E === 360 && (E = 0), E > 360 && (E -= 360), E < 0 && (E += 360), E /= 60; + var G = Dl(E), ae = E - G, he = I * (1 - P), ue = I * (1 - P * ae), de = I * (1 - P * (1 - ae)); + switch (G) { + case 0: + o = [I, de, he], V = o[0], F = o[1], U = o[2]; + break; + case 1: + f = [ue, I, he], V = f[0], F = f[1], U = f[2]; + break; + case 2: + p = [he, I, de], V = p[0], F = p[1], U = p[2]; + break; + case 3: + b = [he, ue, I], V = b[0], F = b[1], U = b[2]; + break; + case 4: + C = [de, he, I], V = C[0], F = C[1], U = C[2]; + break; + case 5: + A = [I, he, ue], V = A[0], F = A[1], U = A[2]; + break; + } + } + return [V, F, U, S.length > 3 ? S[3] : 1]; + }, $l = Pl, Il = v.unpack, Ol = v.type, Fl = O, es = D, ts = N, zl = Ml; + es.prototype.hsv = function() { + return zl(this._rgb); + }, Fl.hsv = function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + return new (Function.prototype.bind.apply(es, [null].concat(o, ["hsv"])))(); + }, ts.format.hsv = $l, ts.autodetect.push({ + p: 2, + test: function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + if (o = Il(o, "hsv"), Ol(o) === "array" && o.length === 3) + return "hsv"; + } + }); + var ci = { + // Corresponds roughly to RGB brighter/darker + Kn: 18, + // D65 standard referent + Xn: 0.95047, + Yn: 1, + Zn: 1.08883, + t0: 0.137931034, + // 4 / 29 + t1: 0.206896552, + // 6 / 29 + t2: 0.12841855, + // 3 * t1 * t1 + t3: 8856452e-9 + // t1 * t1 * t1 + }, br = ci, Hl = v.unpack, rs = Math.pow, Wl = function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + var p = Hl(o, "rgb"), b = p[0], C = p[1], A = p[2], S = ql(b, C, A), R = S[0], E = S[1], P = S[2], I = 116 * E - 16; + return [I < 0 ? 0 : I, 500 * (R - E), 200 * (E - P)]; + }, en = function(o) { + return (o /= 255) <= 0.04045 ? o / 12.92 : rs((o + 0.055) / 1.055, 2.4); + }, tn = function(o) { + return o > br.t3 ? rs(o, 1 / 3) : o / br.t2 + br.t0; + }, ql = function(o, f, p) { + o = en(o), f = en(f), p = en(p); + var b = tn((0.4124564 * o + 0.3575761 * f + 0.1804375 * p) / br.Xn), C = tn((0.2126729 * o + 0.7151522 * f + 0.072175 * p) / br.Yn), A = tn((0.0193339 * o + 0.119192 * f + 0.9503041 * p) / br.Zn); + return [b, C, A]; + }, is = Wl, wr = ci, Vl = v.unpack, Xl = Math.pow, Yl = function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + o = Vl(o, "lab"); + var p = o[0], b = o[1], C = o[2], A, S, R, E, P, I; + return S = (p + 16) / 116, A = isNaN(b) ? S : S + b / 500, R = isNaN(C) ? S : S - C / 200, S = wr.Yn * nn(S), A = wr.Xn * nn(A), R = wr.Zn * nn(R), E = rn(3.2404542 * A - 1.5371385 * S - 0.4985314 * R), P = rn(-0.969266 * A + 1.8760108 * S + 0.041556 * R), I = rn(0.0556434 * A - 0.2040259 * S + 1.0572252 * R), [E, P, I, o.length > 3 ? o[3] : 1]; + }, rn = function(o) { + return 255 * (o <= 304e-5 ? 12.92 * o : 1.055 * Xl(o, 1 / 2.4) - 0.055); + }, nn = function(o) { + return o > wr.t1 ? o * o * o : wr.t2 * (o - wr.t0); + }, ns = Yl, Gl = v.unpack, Ul = v.type, Zl = O, ss = D, as = N, Kl = is; + ss.prototype.lab = function() { + return Kl(this._rgb); + }, Zl.lab = function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + return new (Function.prototype.bind.apply(ss, [null].concat(o, ["lab"])))(); + }, as.format.lab = ns, as.autodetect.push({ + p: 2, + test: function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + if (o = Gl(o, "lab"), Ul(o) === "array" && o.length === 3) + return "lab"; + } + }); + var jl = v.unpack, Jl = v.RAD2DEG, Ql = Math.sqrt, eo = Math.atan2, to = Math.round, ro = function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + var p = jl(o, "lab"), b = p[0], C = p[1], A = p[2], S = Ql(C * C + A * A), R = (eo(A, C) * Jl + 360) % 360; + return to(S * 1e4) === 0 && (R = Number.NaN), [b, S, R]; + }, ls = ro, io = v.unpack, no = is, so = ls, ao = function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + var p = io(o, "rgb"), b = p[0], C = p[1], A = p[2], S = no(b, C, A), R = S[0], E = S[1], P = S[2]; + return so(R, E, P); + }, lo = ao, oo = v.unpack, ho = v.DEG2RAD, fo = Math.sin, uo = Math.cos, co = function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + var p = oo(o, "lch"), b = p[0], C = p[1], A = p[2]; + return isNaN(A) && (A = 0), A = A * ho, [b, uo(A) * C, fo(A) * C]; + }, os = co, go = v.unpack, po = os, vo = ns, mo = function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + o = go(o, "lch"); + var p = o[0], b = o[1], C = o[2], A = po(p, b, C), S = A[0], R = A[1], E = A[2], P = vo(S, R, E), I = P[0], V = P[1], F = P[2]; + return [I, V, F, o.length > 3 ? o[3] : 1]; + }, hs = mo, bo = v.unpack, wo = hs, yo = function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + var p = bo(o, "hcl").reverse(); + return wo.apply(void 0, p); + }, _o = yo, So = v.unpack, Co = v.type, fs = O, gi = D, sn = N, us = lo; + gi.prototype.lch = function() { + return us(this._rgb); + }, gi.prototype.hcl = function() { + return us(this._rgb).reverse(); + }, fs.lch = function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + return new (Function.prototype.bind.apply(gi, [null].concat(o, ["lch"])))(); + }, fs.hcl = function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + return new (Function.prototype.bind.apply(gi, [null].concat(o, ["hcl"])))(); + }, sn.format.lch = hs, sn.format.hcl = _o, ["lch", "hcl"].forEach(function(o) { + return sn.autodetect.push({ + p: 2, + test: function() { + for (var f = [], p = arguments.length; p--; ) + f[p] = arguments[p]; + if (f = So(f, o), Co(f) === "array" && f.length === 3) + return o; + } + }); + }); + var Ao = { + aliceblue: "#f0f8ff", + antiquewhite: "#faebd7", + aqua: "#00ffff", + aquamarine: "#7fffd4", + azure: "#f0ffff", + beige: "#f5f5dc", + bisque: "#ffe4c4", + black: "#000000", + blanchedalmond: "#ffebcd", + blue: "#0000ff", + blueviolet: "#8a2be2", + brown: "#a52a2a", + burlywood: "#deb887", + cadetblue: "#5f9ea0", + chartreuse: "#7fff00", + chocolate: "#d2691e", + coral: "#ff7f50", + cornflower: "#6495ed", + cornflowerblue: "#6495ed", + cornsilk: "#fff8dc", + crimson: "#dc143c", + cyan: "#00ffff", + darkblue: "#00008b", + darkcyan: "#008b8b", + darkgoldenrod: "#b8860b", + darkgray: "#a9a9a9", + darkgreen: "#006400", + darkgrey: "#a9a9a9", + darkkhaki: "#bdb76b", + darkmagenta: "#8b008b", + darkolivegreen: "#556b2f", + darkorange: "#ff8c00", + darkorchid: "#9932cc", + darkred: "#8b0000", + darksalmon: "#e9967a", + darkseagreen: "#8fbc8f", + darkslateblue: "#483d8b", + darkslategray: "#2f4f4f", + darkslategrey: "#2f4f4f", + darkturquoise: "#00ced1", + darkviolet: "#9400d3", + deeppink: "#ff1493", + deepskyblue: "#00bfff", + dimgray: "#696969", + dimgrey: "#696969", + dodgerblue: "#1e90ff", + firebrick: "#b22222", + floralwhite: "#fffaf0", + forestgreen: "#228b22", + fuchsia: "#ff00ff", + gainsboro: "#dcdcdc", + ghostwhite: "#f8f8ff", + gold: "#ffd700", + goldenrod: "#daa520", + gray: "#808080", + green: "#008000", + greenyellow: "#adff2f", + grey: "#808080", + honeydew: "#f0fff0", + hotpink: "#ff69b4", + indianred: "#cd5c5c", + indigo: "#4b0082", + ivory: "#fffff0", + khaki: "#f0e68c", + laserlemon: "#ffff54", + lavender: "#e6e6fa", + lavenderblush: "#fff0f5", + lawngreen: "#7cfc00", + lemonchiffon: "#fffacd", + lightblue: "#add8e6", + lightcoral: "#f08080", + lightcyan: "#e0ffff", + lightgoldenrod: "#fafad2", + lightgoldenrodyellow: "#fafad2", + lightgray: "#d3d3d3", + lightgreen: "#90ee90", + lightgrey: "#d3d3d3", + lightpink: "#ffb6c1", + lightsalmon: "#ffa07a", + lightseagreen: "#20b2aa", + lightskyblue: "#87cefa", + lightslategray: "#778899", + lightslategrey: "#778899", + lightsteelblue: "#b0c4de", + lightyellow: "#ffffe0", + lime: "#00ff00", + limegreen: "#32cd32", + linen: "#faf0e6", + magenta: "#ff00ff", + maroon: "#800000", + maroon2: "#7f0000", + maroon3: "#b03060", + mediumaquamarine: "#66cdaa", + mediumblue: "#0000cd", + mediumorchid: "#ba55d3", + mediumpurple: "#9370db", + mediumseagreen: "#3cb371", + mediumslateblue: "#7b68ee", + mediumspringgreen: "#00fa9a", + mediumturquoise: "#48d1cc", + mediumvioletred: "#c71585", + midnightblue: "#191970", + mintcream: "#f5fffa", + mistyrose: "#ffe4e1", + moccasin: "#ffe4b5", + navajowhite: "#ffdead", + navy: "#000080", + oldlace: "#fdf5e6", + olive: "#808000", + olivedrab: "#6b8e23", + orange: "#ffa500", + orangered: "#ff4500", + orchid: "#da70d6", + palegoldenrod: "#eee8aa", + palegreen: "#98fb98", + paleturquoise: "#afeeee", + palevioletred: "#db7093", + papayawhip: "#ffefd5", + peachpuff: "#ffdab9", + peru: "#cd853f", + pink: "#ffc0cb", + plum: "#dda0dd", + powderblue: "#b0e0e6", + purple: "#800080", + purple2: "#7f007f", + purple3: "#a020f0", + rebeccapurple: "#663399", + red: "#ff0000", + rosybrown: "#bc8f8f", + royalblue: "#4169e1", + saddlebrown: "#8b4513", + salmon: "#fa8072", + sandybrown: "#f4a460", + seagreen: "#2e8b57", + seashell: "#fff5ee", + sienna: "#a0522d", + silver: "#c0c0c0", + skyblue: "#87ceeb", + slateblue: "#6a5acd", + slategray: "#708090", + slategrey: "#708090", + snow: "#fffafa", + springgreen: "#00ff7f", + steelblue: "#4682b4", + tan: "#d2b48c", + teal: "#008080", + thistle: "#d8bfd8", + tomato: "#ff6347", + turquoise: "#40e0d0", + violet: "#ee82ee", + wheat: "#f5deb3", + white: "#ffffff", + whitesmoke: "#f5f5f5", + yellow: "#ffff00", + yellowgreen: "#9acd32" + }, cs = Ao, No = D, gs = N, ko = v.type, Vr = cs, Ro = zr, xo = Ne; + No.prototype.name = function() { + for (var o = xo(this._rgb, "rgb"), f = 0, p = Object.keys(Vr); f < p.length; f += 1) { + var b = p[f]; + if (Vr[b] === o) + return b.toLowerCase(); + } + return o; + }, gs.format.named = function(o) { + if (o = o.toLowerCase(), Vr[o]) + return Ro(Vr[o]); + throw new Error("unknown color name: " + o); + }, gs.autodetect.push({ + p: 5, + test: function(o) { + for (var f = [], p = arguments.length - 1; p-- > 0; ) + f[p] = arguments[p + 1]; + if (!f.length && ko(o) === "string" && Vr[o.toLowerCase()]) + return "named"; + } + }); + var To = v.unpack, Eo = function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + var p = To(o, "rgb"), b = p[0], C = p[1], A = p[2]; + return (b << 16) + (C << 8) + A; + }, Lo = Eo, Mo = v.type, Bo = function(o) { + if (Mo(o) == "number" && o >= 0 && o <= 16777215) { + var f = o >> 16, p = o >> 8 & 255, b = o & 255; + return [f, p, b, 1]; + } + throw new Error("unknown num color: " + o); + }, Do = Bo, Po = O, ds = D, ps = N, $o = v.type, Io = Lo; + ds.prototype.num = function() { + return Io(this._rgb); + }, Po.num = function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + return new (Function.prototype.bind.apply(ds, [null].concat(o, ["num"])))(); + }, ps.format.num = Do, ps.autodetect.push({ + p: 5, + test: function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + if (o.length === 1 && $o(o[0]) === "number" && o[0] >= 0 && o[0] <= 16777215) + return "num"; + } + }); + var Oo = O, an = D, vs = N, ms = v.unpack, bs = v.type, ws = Math.round; + an.prototype.rgb = function(o) { + return o === void 0 && (o = !0), o === !1 ? this._rgb.slice(0, 3) : this._rgb.slice(0, 3).map(ws); + }, an.prototype.rgba = function(o) { + return o === void 0 && (o = !0), this._rgb.slice(0, 4).map(function(f, p) { + return p < 3 ? o === !1 ? f : ws(f) : f; + }); + }, Oo.rgb = function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + return new (Function.prototype.bind.apply(an, [null].concat(o, ["rgb"])))(); + }, vs.format.rgb = function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + var p = ms(o, "rgba"); + return p[3] === void 0 && (p[3] = 1), p; + }, vs.autodetect.push({ + p: 3, + test: function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + if (o = ms(o, "rgba"), bs(o) === "array" && (o.length === 3 || o.length === 4 && bs(o[3]) == "number" && o[3] >= 0 && o[3] <= 1)) + return "rgb"; + } + }); + var di = Math.log, Fo = function(o) { + var f = o / 100, p, b, C; + return f < 66 ? (p = 255, b = f < 6 ? 0 : -155.25485562709179 - 0.44596950469579133 * (b = f - 2) + 104.49216199393888 * di(b), C = f < 20 ? 0 : -254.76935184120902 + 0.8274096064007395 * (C = f - 10) + 115.67994401066147 * di(C)) : (p = 351.97690566805693 + 0.114206453784165 * (p = f - 55) - 40.25366309332127 * di(p), b = 325.4494125711974 + 0.07943456536662342 * (b = f - 50) - 28.0852963507957 * di(b), C = 255), [p, b, C, 1]; + }, ys = Fo, zo = ys, Ho = v.unpack, Wo = Math.round, qo = function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + for (var p = Ho(o, "rgb"), b = p[0], C = p[2], A = 1e3, S = 4e4, R = 0.4, E; S - A > R; ) { + E = (S + A) * 0.5; + var P = zo(E); + P[2] / P[0] >= C / b ? S = E : A = E; + } + return Wo(E); + }, Vo = qo, ln = O, pi = D, on = N, Xo = Vo; + pi.prototype.temp = pi.prototype.kelvin = pi.prototype.temperature = function() { + return Xo(this._rgb); + }, ln.temp = ln.kelvin = ln.temperature = function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + return new (Function.prototype.bind.apply(pi, [null].concat(o, ["temp"])))(); + }, on.format.temp = on.format.kelvin = on.format.temperature = ys; + var Yo = v.unpack, hn = Math.cbrt, Go = Math.pow, Uo = Math.sign, Zo = function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + var p = Yo(o, "rgb"), b = p[0], C = p[1], A = p[2], S = [fn(b / 255), fn(C / 255), fn(A / 255)], R = S[0], E = S[1], P = S[2], I = hn(0.4122214708 * R + 0.5363325363 * E + 0.0514459929 * P), V = hn(0.2119034982 * R + 0.6806995451 * E + 0.1073969566 * P), F = hn(0.0883024619 * R + 0.2817188376 * E + 0.6299787005 * P); + return [ + 0.2104542553 * I + 0.793617785 * V - 0.0040720468 * F, + 1.9779984951 * I - 2.428592205 * V + 0.4505937099 * F, + 0.0259040371 * I + 0.7827717662 * V - 0.808675766 * F + ]; + }, _s = Zo; + function fn(o) { + var f = Math.abs(o); + return f < 0.04045 ? o / 12.92 : (Uo(o) || 1) * Go((f + 0.055) / 1.055, 2.4); + } + var Ko = v.unpack, vi = Math.pow, jo = Math.sign, Jo = function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + o = Ko(o, "lab"); + var p = o[0], b = o[1], C = o[2], A = vi(p + 0.3963377774 * b + 0.2158037573 * C, 3), S = vi(p - 0.1055613458 * b - 0.0638541728 * C, 3), R = vi(p - 0.0894841775 * b - 1.291485548 * C, 3); + return [ + 255 * un(4.0767416621 * A - 3.3077115913 * S + 0.2309699292 * R), + 255 * un(-1.2684380046 * A + 2.6097574011 * S - 0.3413193965 * R), + 255 * un(-0.0041960863 * A - 0.7034186147 * S + 1.707614701 * R), + o.length > 3 ? o[3] : 1 + ]; + }, Ss = Jo; + function un(o) { + var f = Math.abs(o); + return f > 31308e-7 ? (jo(o) || 1) * (1.055 * vi(f, 1 / 2.4) - 0.055) : o * 12.92; + } + var Qo = v.unpack, eh = v.type, th = O, Cs = D, As = N, rh = _s; + Cs.prototype.oklab = function() { + return rh(this._rgb); + }, th.oklab = function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + return new (Function.prototype.bind.apply(Cs, [null].concat(o, ["oklab"])))(); + }, As.format.oklab = Ss, As.autodetect.push({ + p: 3, + test: function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + if (o = Qo(o, "oklab"), eh(o) === "array" && o.length === 3) + return "oklab"; + } + }); + var ih = v.unpack, nh = _s, sh = ls, ah = function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + var p = ih(o, "rgb"), b = p[0], C = p[1], A = p[2], S = nh(b, C, A), R = S[0], E = S[1], P = S[2]; + return sh(R, E, P); + }, lh = ah, oh = v.unpack, hh = os, fh = Ss, uh = function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + o = oh(o, "lch"); + var p = o[0], b = o[1], C = o[2], A = hh(p, b, C), S = A[0], R = A[1], E = A[2], P = fh(S, R, E), I = P[0], V = P[1], F = P[2]; + return [I, V, F, o.length > 3 ? o[3] : 1]; + }, ch = uh, gh = v.unpack, dh = v.type, ph = O, Ns = D, ks = N, vh = lh; + Ns.prototype.oklch = function() { + return vh(this._rgb); + }, ph.oklch = function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + return new (Function.prototype.bind.apply(Ns, [null].concat(o, ["oklch"])))(); + }, ks.format.oklch = ch, ks.autodetect.push({ + p: 3, + test: function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + if (o = gh(o, "oklch"), dh(o) === "array" && o.length === 3) + return "oklch"; + } + }); + var Rs = D, mh = v.type; + Rs.prototype.alpha = function(o, f) { + return f === void 0 && (f = !1), o !== void 0 && mh(o) === "number" ? f ? (this._rgb[3] = o, this) : new Rs([this._rgb[0], this._rgb[1], this._rgb[2], o], "rgb") : this._rgb[3]; + }; + var bh = D; + bh.prototype.clipped = function() { + return this._rgb._clipped || !1; + }; + var hr = D, wh = ci; + hr.prototype.darken = function(o) { + o === void 0 && (o = 1); + var f = this, p = f.lab(); + return p[0] -= wh.Kn * o, new hr(p, "lab").alpha(f.alpha(), !0); + }, hr.prototype.brighten = function(o) { + return o === void 0 && (o = 1), this.darken(-o); + }, hr.prototype.darker = hr.prototype.darken, hr.prototype.brighter = hr.prototype.brighten; + var yh = D; + yh.prototype.get = function(o) { + var f = o.split("."), p = f[0], b = f[1], C = this[p](); + if (b) { + var A = p.indexOf(b) - (p.substr(0, 2) === "ok" ? 2 : 0); + if (A > -1) + return C[A]; + throw new Error("unknown channel " + b + " in mode " + p); + } else + return C; + }; + var yr = D, _h = v.type, Sh = Math.pow, Ch = 1e-7, Ah = 20; + yr.prototype.luminance = function(o) { + if (o !== void 0 && _h(o) === "number") { + if (o === 0) + return new yr([0, 0, 0, this._rgb[3]], "rgb"); + if (o === 1) + return new yr([255, 255, 255, this._rgb[3]], "rgb"); + var f = this.luminance(), p = "rgb", b = Ah, C = function(S, R) { + var E = S.interpolate(R, 0.5, p), P = E.luminance(); + return Math.abs(o - P) < Ch || !b-- ? E : P > o ? C(S, E) : C(E, R); + }, A = (f > o ? C(new yr([0, 0, 0]), this) : C(this, new yr([255, 255, 255]))).rgb(); + return new yr(A.concat([this._rgb[3]])); + } + return Nh.apply(void 0, this._rgb.slice(0, 3)); + }; + var Nh = function(o, f, p) { + return o = cn(o), f = cn(f), p = cn(p), 0.2126 * o + 0.7152 * f + 0.0722 * p; + }, cn = function(o) { + return o /= 255, o <= 0.03928 ? o / 12.92 : Sh((o + 0.055) / 1.055, 2.4); + }, lt = {}, xs = D, Ts = v.type, mi = lt, Es = function(o, f, p) { + p === void 0 && (p = 0.5); + for (var b = [], C = arguments.length - 3; C-- > 0; ) + b[C] = arguments[C + 3]; + var A = b[0] || "lrgb"; + if (!mi[A] && !b.length && (A = Object.keys(mi)[0]), !mi[A]) + throw new Error("interpolation mode " + A + " is not defined"); + return Ts(o) !== "object" && (o = new xs(o)), Ts(f) !== "object" && (f = new xs(f)), mi[A](o, f, p).alpha(o.alpha() + p * (f.alpha() - o.alpha())); + }, Ls = D, kh = Es; + Ls.prototype.mix = Ls.prototype.interpolate = function(o, f) { + f === void 0 && (f = 0.5); + for (var p = [], b = arguments.length - 2; b-- > 0; ) + p[b] = arguments[b + 2]; + return kh.apply(void 0, [this, o, f].concat(p)); + }; + var Ms = D; + Ms.prototype.premultiply = function(o) { + o === void 0 && (o = !1); + var f = this._rgb, p = f[3]; + return o ? (this._rgb = [f[0] * p, f[1] * p, f[2] * p, p], this) : new Ms([f[0] * p, f[1] * p, f[2] * p, p], "rgb"); + }; + var gn = D, Rh = ci; + gn.prototype.saturate = function(o) { + o === void 0 && (o = 1); + var f = this, p = f.lch(); + return p[1] += Rh.Kn * o, p[1] < 0 && (p[1] = 0), new gn(p, "lch").alpha(f.alpha(), !0); + }, gn.prototype.desaturate = function(o) { + return o === void 0 && (o = 1), this.saturate(-o); + }; + var Bs = D, Ds = v.type; + Bs.prototype.set = function(o, f, p) { + p === void 0 && (p = !1); + var b = o.split("."), C = b[0], A = b[1], S = this[C](); + if (A) { + var R = C.indexOf(A) - (C.substr(0, 2) === "ok" ? 2 : 0); + if (R > -1) { + if (Ds(f) == "string") + switch (f.charAt(0)) { + case "+": + S[R] += +f; + break; + case "-": + S[R] += +f; + break; + case "*": + S[R] *= +f.substr(1); + break; + case "/": + S[R] /= +f.substr(1); + break; + default: + S[R] = +f; + } + else if (Ds(f) === "number") + S[R] = f; + else + throw new Error("unsupported value for Color.set"); + var E = new Bs(S, C); + return p ? (this._rgb = E._rgb, this) : E; + } + throw new Error("unknown channel " + A + " in mode " + C); + } else + return S; + }; + var xh = D, Th = function(o, f, p) { + var b = o._rgb, C = f._rgb; + return new xh( + b[0] + p * (C[0] - b[0]), + b[1] + p * (C[1] - b[1]), + b[2] + p * (C[2] - b[2]), + "rgb" + ); + }; + lt.rgb = Th; + var Eh = D, dn = Math.sqrt, _r = Math.pow, Lh = function(o, f, p) { + var b = o._rgb, C = b[0], A = b[1], S = b[2], R = f._rgb, E = R[0], P = R[1], I = R[2]; + return new Eh( + dn(_r(C, 2) * (1 - p) + _r(E, 2) * p), + dn(_r(A, 2) * (1 - p) + _r(P, 2) * p), + dn(_r(S, 2) * (1 - p) + _r(I, 2) * p), + "rgb" + ); + }; + lt.lrgb = Lh; + var Mh = D, Bh = function(o, f, p) { + var b = o.lab(), C = f.lab(); + return new Mh( + b[0] + p * (C[0] - b[0]), + b[1] + p * (C[1] - b[1]), + b[2] + p * (C[2] - b[2]), + "lab" + ); + }; + lt.lab = Bh; + var Ps = D, Sr = function(o, f, p, b) { + var C, A, S, R; + b === "hsl" ? (S = o.hsl(), R = f.hsl()) : b === "hsv" ? (S = o.hsv(), R = f.hsv()) : b === "hcg" ? (S = o.hcg(), R = f.hcg()) : b === "hsi" ? (S = o.hsi(), R = f.hsi()) : b === "lch" || b === "hcl" ? (b = "hcl", S = o.hcl(), R = f.hcl()) : b === "oklch" && (S = o.oklch().reverse(), R = f.oklch().reverse()); + var E, P, I, V, F, U; + (b.substr(0, 1) === "h" || b === "oklch") && (C = S, E = C[0], I = C[1], F = C[2], A = R, P = A[0], V = A[1], U = A[2]); + var G, ae, he, ue; + return !isNaN(E) && !isNaN(P) ? (P > E && P - E > 180 ? ue = P - (E + 360) : P < E && E - P > 180 ? ue = P + 360 - E : ue = P - E, ae = E + p * ue) : isNaN(E) ? isNaN(P) ? ae = Number.NaN : (ae = P, (F == 1 || F == 0) && b != "hsv" && (G = V)) : (ae = E, (U == 1 || U == 0) && b != "hsv" && (G = I)), G === void 0 && (G = I + p * (V - I)), he = F + p * (U - F), b === "oklch" ? new Ps([he, G, ae], b) : new Ps([ae, G, he], b); + }, Dh = Sr, $s = function(o, f, p) { + return Dh(o, f, p, "lch"); + }; + lt.lch = $s, lt.hcl = $s; + var Ph = D, $h = function(o, f, p) { + var b = o.num(), C = f.num(); + return new Ph(b + p * (C - b), "num"); + }; + lt.num = $h; + var Ih = Sr, Oh = function(o, f, p) { + return Ih(o, f, p, "hcg"); + }; + lt.hcg = Oh; + var Fh = Sr, zh = function(o, f, p) { + return Fh(o, f, p, "hsi"); + }; + lt.hsi = zh; + var Hh = Sr, Wh = function(o, f, p) { + return Hh(o, f, p, "hsl"); + }; + lt.hsl = Wh; + var qh = Sr, Vh = function(o, f, p) { + return qh(o, f, p, "hsv"); + }; + lt.hsv = Vh; + var Xh = D, Yh = function(o, f, p) { + var b = o.oklab(), C = f.oklab(); + return new Xh( + b[0] + p * (C[0] - b[0]), + b[1] + p * (C[1] - b[1]), + b[2] + p * (C[2] - b[2]), + "oklab" + ); + }; + lt.oklab = Yh; + var Gh = Sr, Uh = function(o, f, p) { + return Gh(o, f, p, "oklch"); + }; + lt.oklch = Uh; + var pn = D, Zh = v.clip_rgb, vn = Math.pow, mn = Math.sqrt, bn = Math.PI, Is = Math.cos, Os = Math.sin, Kh = Math.atan2, jh = function(o, f, p) { + f === void 0 && (f = "lrgb"), p === void 0 && (p = null); + var b = o.length; + p || (p = Array.from(new Array(b)).map(function() { + return 1; + })); + var C = b / p.reduce(function(ae, he) { + return ae + he; + }); + if (p.forEach(function(ae, he) { + p[he] *= C; + }), o = o.map(function(ae) { + return new pn(ae); + }), f === "lrgb") + return Jh(o, p); + for (var A = o.shift(), S = A.get(f), R = [], E = 0, P = 0, I = 0; I < S.length; I++) + if (S[I] = (S[I] || 0) * p[0], R.push(isNaN(S[I]) ? 0 : p[0]), f.charAt(I) === "h" && !isNaN(S[I])) { + var V = S[I] / 180 * bn; + E += Is(V) * p[0], P += Os(V) * p[0]; + } + var F = A.alpha() * p[0]; + o.forEach(function(ae, he) { + var ue = ae.get(f); + F += ae.alpha() * p[he + 1]; + for (var de = 0; de < S.length; de++) + if (!isNaN(ue[de])) + if (R[de] += p[he + 1], f.charAt(de) === "h") { + var Ve = ue[de] / 180 * bn; + E += Is(Ve) * p[he + 1], P += Os(Ve) * p[he + 1]; + } else + S[de] += ue[de] * p[he + 1]; + }); + for (var U = 0; U < S.length; U++) + if (f.charAt(U) === "h") { + for (var G = Kh(P / R[U], E / R[U]) / bn * 180; G < 0; ) + G += 360; + for (; G >= 360; ) + G -= 360; + S[U] = G; + } else + S[U] = S[U] / R[U]; + return F /= b, new pn(S, f).alpha(F > 0.99999 ? 1 : F, !0); + }, Jh = function(o, f) { + for (var p = o.length, b = [0, 0, 0, 0], C = 0; C < o.length; C++) { + var A = o[C], S = f[C] / p, R = A._rgb; + b[0] += vn(R[0], 2) * S, b[1] += vn(R[1], 2) * S, b[2] += vn(R[2], 2) * S, b[3] += R[3] * S; + } + return b[0] = mn(b[0]), b[1] = mn(b[1]), b[2] = mn(b[2]), b[3] > 0.9999999 && (b[3] = 1), new pn(Zh(b)); + }, St = O, Cr = v.type, Qh = Math.pow, wn = function(o) { + var f = "rgb", p = St("#ccc"), b = 0, C = [0, 1], A = [], S = [0, 0], R = !1, E = [], P = !1, I = 0, V = 1, F = !1, U = {}, G = !0, ae = 1, he = function(W) { + if (W = W || ["#fff", "#000"], W && Cr(W) === "string" && St.brewer && St.brewer[W.toLowerCase()] && (W = St.brewer[W.toLowerCase()]), Cr(W) === "array") { + W.length === 1 && (W = [W[0], W[0]]), W = W.slice(0); + for (var te = 0; te < W.length; te++) + W[te] = St(W[te]); + A.length = 0; + for (var oe = 0; oe < W.length; oe++) + A.push(oe / (W.length - 1)); + } + return tt(), E = W; + }, ue = function(W) { + if (R != null) { + for (var te = R.length - 1, oe = 0; oe < te && W >= R[oe]; ) + oe++; + return oe - 1; + } + return 0; + }, de = function(W) { + return W; + }, Ve = function(W) { + return W; + }, ze = function(W, te) { + var oe, le; + if (te == null && (te = !1), isNaN(W) || W === null) + return p; + if (te) + le = W; + else if (R && R.length > 2) { + var Xe = ue(W); + le = Xe / (R.length - 2); + } else + V !== I ? le = (W - I) / (V - I) : le = 1; + le = Ve(le), te || (le = de(le)), ae !== 1 && (le = Qh(le, ae)), le = S[0] + le * (1 - S[0] - S[1]), le = Math.min(1, Math.max(0, le)); + var _e = Math.floor(le * 1e4); + if (G && U[_e]) + oe = U[_e]; + else { + if (Cr(E) === "array") + for (var ce = 0; ce < A.length; ce++) { + var pe = A[ce]; + if (le <= pe) { + oe = E[ce]; + break; + } + if (le >= pe && ce === A.length - 1) { + oe = E[ce]; + break; + } + if (le > pe && le < A[ce + 1]) { + le = (le - pe) / (A[ce + 1] - pe), oe = St.interpolate(E[ce], E[ce + 1], le, f); + break; + } + } + else + Cr(E) === "function" && (oe = E(le)); + G && (U[_e] = oe); + } + return oe; + }, tt = function() { + return U = {}; + }; + he(o); + var fe = function(W) { + var te = St(ze(W)); + return P && te[P] ? te[P]() : te; + }; + return fe.classes = function(W) { + if (W != null) { + if (Cr(W) === "array") + R = W, C = [W[0], W[W.length - 1]]; + else { + var te = St.analyze(C); + W === 0 ? R = [te.min, te.max] : R = St.limits(te, "e", W); + } + return fe; + } + return R; + }, fe.domain = function(W) { + if (!arguments.length) + return C; + I = W[0], V = W[W.length - 1], A = []; + var te = E.length; + if (W.length === te && I !== V) + for (var oe = 0, le = Array.from(W); oe < le.length; oe += 1) { + var Xe = le[oe]; + A.push((Xe - I) / (V - I)); + } + else { + for (var _e = 0; _e < te; _e++) + A.push(_e / (te - 1)); + if (W.length > 2) { + var ce = W.map(function(ve, me) { + return me / (W.length - 1); + }), pe = W.map(function(ve) { + return (ve - I) / (V - I); + }); + pe.every(function(ve, me) { + return ce[me] === ve; + }) || (Ve = function(ve) { + if (ve <= 0 || ve >= 1) + return ve; + for (var me = 0; ve >= pe[me + 1]; ) + me++; + var At = (ve - pe[me]) / (pe[me + 1] - pe[me]), rr = ce[me] + At * (ce[me + 1] - ce[me]); + return rr; + }); + } + } + return C = [I, V], fe; + }, fe.mode = function(W) { + return arguments.length ? (f = W, tt(), fe) : f; + }, fe.range = function(W, te) { + return he(W), fe; + }, fe.out = function(W) { + return P = W, fe; + }, fe.spread = function(W) { + return arguments.length ? (b = W, fe) : b; + }, fe.correctLightness = function(W) { + return W == null && (W = !0), F = W, tt(), F ? de = function(te) { + for (var oe = ze(0, !0).lab()[0], le = ze(1, !0).lab()[0], Xe = oe > le, _e = ze(te, !0).lab()[0], ce = oe + (le - oe) * te, pe = _e - ce, ve = 0, me = 1, At = 20; Math.abs(pe) > 0.01 && At-- > 0; ) + (function() { + return Xe && (pe *= -1), pe < 0 ? (ve = te, te += (me - te) * 0.5) : (me = te, te += (ve - te) * 0.5), _e = ze(te, !0).lab()[0], pe = _e - ce; + })(); + return te; + } : de = function(te) { + return te; + }, fe; + }, fe.padding = function(W) { + return W != null ? (Cr(W) === "number" && (W = [W, W]), S = W, fe) : S; + }, fe.colors = function(W, te) { + arguments.length < 2 && (te = "hex"); + var oe = []; + if (arguments.length === 0) + oe = E.slice(0); + else if (W === 1) + oe = [fe(0.5)]; + else if (W > 1) { + var le = C[0], Xe = C[1] - le; + oe = ef(0, W, !1).map(function(me) { + return fe(le + me / (W - 1) * Xe); + }); + } else { + o = []; + var _e = []; + if (R && R.length > 2) + for (var ce = 1, pe = R.length, ve = 1 <= pe; ve ? ce < pe : ce > pe; ve ? ce++ : ce--) + _e.push((R[ce - 1] + R[ce]) * 0.5); + else + _e = C; + oe = _e.map(function(me) { + return fe(me); + }); + } + return St[te] && (oe = oe.map(function(me) { + return me[te](); + })), oe; + }, fe.cache = function(W) { + return W != null ? (G = W, fe) : G; + }, fe.gamma = function(W) { + return W != null ? (ae = W, fe) : ae; + }, fe.nodata = function(W) { + return W != null ? (p = St(W), fe) : p; + }, fe; + }; + function ef(o, f, p) { + for (var b = [], C = o < f, A = p ? C ? f + 1 : f - 1 : f, S = o; C ? S < A : S > A; C ? S++ : S--) + b.push(S); + return b; + } + var Xr = D, tf = wn, rf = function(o) { + for (var f = [1, 1], p = 1; p < o; p++) { + for (var b = [1], C = 1; C <= f.length; C++) + b[C] = (f[C] || 0) + f[C - 1]; + f = b; + } + return f; + }, nf = function(o) { + var f, p, b, C, A, S, R; + if (o = o.map(function(F) { + return new Xr(F); + }), o.length === 2) + f = o.map(function(F) { + return F.lab(); + }), A = f[0], S = f[1], C = function(F) { + var U = [0, 1, 2].map(function(G) { + return A[G] + F * (S[G] - A[G]); + }); + return new Xr(U, "lab"); + }; + else if (o.length === 3) + p = o.map(function(F) { + return F.lab(); + }), A = p[0], S = p[1], R = p[2], C = function(F) { + var U = [0, 1, 2].map(function(G) { + return (1 - F) * (1 - F) * A[G] + 2 * (1 - F) * F * S[G] + F * F * R[G]; + }); + return new Xr(U, "lab"); + }; + else if (o.length === 4) { + var E; + b = o.map(function(F) { + return F.lab(); + }), A = b[0], S = b[1], R = b[2], E = b[3], C = function(F) { + var U = [0, 1, 2].map(function(G) { + return (1 - F) * (1 - F) * (1 - F) * A[G] + 3 * (1 - F) * (1 - F) * F * S[G] + 3 * (1 - F) * F * F * R[G] + F * F * F * E[G]; + }); + return new Xr(U, "lab"); + }; + } else if (o.length >= 5) { + var P, I, V; + P = o.map(function(F) { + return F.lab(); + }), V = o.length - 1, I = rf(V), C = function(F) { + var U = 1 - F, G = [0, 1, 2].map(function(ae) { + return P.reduce(function(he, ue, de) { + return he + I[de] * Math.pow(U, V - de) * Math.pow(F, de) * ue[ae]; + }, 0); + }); + return new Xr(G, "lab"); + }; + } else + throw new RangeError("No point in running bezier with only one color."); + return C; + }, sf = function(o) { + var f = nf(o); + return f.scale = function() { + return tf(f); + }, f; + }, yn = O, Ct = function(o, f, p) { + if (!Ct[p]) + throw new Error("unknown blend mode " + p); + return Ct[p](o, f); + }, er = function(o) { + return function(f, p) { + var b = yn(p).rgb(), C = yn(f).rgb(); + return yn.rgb(o(b, C)); + }; + }, tr = function(o) { + return function(f, p) { + var b = []; + return b[0] = o(f[0], p[0]), b[1] = o(f[1], p[1]), b[2] = o(f[2], p[2]), b; + }; + }, af = function(o) { + return o; + }, lf = function(o, f) { + return o * f / 255; + }, of = function(o, f) { + return o > f ? f : o; + }, hf = function(o, f) { + return o > f ? o : f; + }, ff = function(o, f) { + return 255 * (1 - (1 - o / 255) * (1 - f / 255)); + }, uf = function(o, f) { + return f < 128 ? 2 * o * f / 255 : 255 * (1 - 2 * (1 - o / 255) * (1 - f / 255)); + }, cf = function(o, f) { + return 255 * (1 - (1 - f / 255) / (o / 255)); + }, gf = function(o, f) { + return o === 255 ? 255 : (o = 255 * (f / 255) / (1 - o / 255), o > 255 ? 255 : o); + }; + Ct.normal = er(tr(af)), Ct.multiply = er(tr(lf)), Ct.screen = er(tr(ff)), Ct.overlay = er(tr(uf)), Ct.darken = er(tr(of)), Ct.lighten = er(tr(hf)), Ct.dodge = er(tr(gf)), Ct.burn = er(tr(cf)); + for (var df = Ct, _n = v.type, pf = v.clip_rgb, vf = v.TWOPI, mf = Math.pow, bf = Math.sin, wf = Math.cos, Fs = O, yf = function(o, f, p, b, C) { + o === void 0 && (o = 300), f === void 0 && (f = -1.5), p === void 0 && (p = 1), b === void 0 && (b = 1), C === void 0 && (C = [0, 1]); + var A = 0, S; + _n(C) === "array" ? S = C[1] - C[0] : (S = 0, C = [C, C]); + var R = function(E) { + var P = vf * ((o + 120) / 360 + f * E), I = mf(C[0] + S * E, b), V = A !== 0 ? p[0] + E * A : p, F = V * I * (1 - I) / 2, U = wf(P), G = bf(P), ae = I + F * (-0.14861 * U + 1.78277 * G), he = I + F * (-0.29227 * U - 0.90649 * G), ue = I + F * (1.97294 * U); + return Fs(pf([ae * 255, he * 255, ue * 255, 1])); + }; + return R.start = function(E) { + return E == null ? o : (o = E, R); + }, R.rotations = function(E) { + return E == null ? f : (f = E, R); + }, R.gamma = function(E) { + return E == null ? b : (b = E, R); + }, R.hue = function(E) { + return E == null ? p : (p = E, _n(p) === "array" ? (A = p[1] - p[0], A === 0 && (p = p[1])) : A = 0, R); + }, R.lightness = function(E) { + return E == null ? C : (_n(E) === "array" ? (C = E, S = E[1] - E[0]) : (C = [E, E], S = 0), R); + }, R.scale = function() { + return Fs.scale(R); + }, R.hue(p), R; + }, _f = D, Sf = "0123456789abcdef", Cf = Math.floor, Af = Math.random, Nf = function() { + for (var o = "#", f = 0; f < 6; f++) + o += Sf.charAt(Cf(Af() * 16)); + return new _f(o, "hex"); + }, Sn = l, zs = Math.log, kf = Math.pow, Rf = Math.floor, xf = Math.abs, Hs = function(o, f) { + f === void 0 && (f = null); + var p = { + min: Number.MAX_VALUE, + max: Number.MAX_VALUE * -1, + sum: 0, + values: [], + count: 0 + }; + return Sn(o) === "object" && (o = Object.values(o)), o.forEach(function(b) { + f && Sn(b) === "object" && (b = b[f]), b != null && !isNaN(b) && (p.values.push(b), p.sum += b, b < p.min && (p.min = b), b > p.max && (p.max = b), p.count += 1); + }), p.domain = [p.min, p.max], p.limits = function(b, C) { + return Ws(p, b, C); + }, p; + }, Ws = function(o, f, p) { + f === void 0 && (f = "equal"), p === void 0 && (p = 7), Sn(o) == "array" && (o = Hs(o)); + var b = o.min, C = o.max, A = o.values.sort(function(An, Nn) { + return An - Nn; + }); + if (p === 1) + return [b, C]; + var S = []; + if (f.substr(0, 1) === "c" && (S.push(b), S.push(C)), f.substr(0, 1) === "e") { + S.push(b); + for (var R = 1; R < p; R++) + S.push(b + R / p * (C - b)); + S.push(C); + } else if (f.substr(0, 1) === "l") { + if (b <= 0) + throw new Error("Logarithmic scales are only possible for values > 0"); + var E = Math.LOG10E * zs(b), P = Math.LOG10E * zs(C); + S.push(b); + for (var I = 1; I < p; I++) + S.push(kf(10, E + I / p * (P - E))); + S.push(C); + } else if (f.substr(0, 1) === "q") { + S.push(b); + for (var V = 1; V < p; V++) { + var F = (A.length - 1) * V / p, U = Rf(F); + if (U === F) + S.push(A[U]); + else { + var G = F - U; + S.push(A[U] * (1 - G) + A[U + 1] * G); + } + } + S.push(C); + } else if (f.substr(0, 1) === "k") { + var ae, he = A.length, ue = new Array(he), de = new Array(p), Ve = !0, ze = 0, tt = null; + tt = [], tt.push(b); + for (var fe = 1; fe < p; fe++) + tt.push(b + fe / p * (C - b)); + for (tt.push(C); Ve; ) { + for (var W = 0; W < p; W++) + de[W] = 0; + for (var te = 0; te < he; te++) + for (var oe = A[te], le = Number.MAX_VALUE, Xe = void 0, _e = 0; _e < p; _e++) { + var ce = xf(tt[_e] - oe); + ce < le && (le = ce, Xe = _e), de[Xe]++, ue[te] = Xe; + } + for (var pe = new Array(p), ve = 0; ve < p; ve++) + pe[ve] = null; + for (var me = 0; me < he; me++) + ae = ue[me], pe[ae] === null ? pe[ae] = A[me] : pe[ae] += A[me]; + for (var At = 0; At < p; At++) + pe[At] *= 1 / de[At]; + Ve = !1; + for (var rr = 0; rr < p; rr++) + if (pe[rr] !== tt[rr]) { + Ve = !0; + break; + } + tt = pe, ze++, ze > 200 && (Ve = !1); + } + for (var ir = {}, Ar = 0; Ar < p; Ar++) + ir[Ar] = []; + for (var Nr = 0; Nr < he; Nr++) + ae = ue[Nr], ir[ae].push(A[Nr]); + for (var Wt = [], fr = 0; fr < p; fr++) + Wt.push(ir[fr][0]), Wt.push(ir[fr][ir[fr].length - 1]); + Wt = Wt.sort(function(An, Nn) { + return An - Nn; + }), S.push(Wt[0]); + for (var Yr = 1; Yr < Wt.length; Yr += 2) { + var ur = Wt[Yr]; + !isNaN(ur) && S.indexOf(ur) === -1 && S.push(ur); + } + } + return S; + }, qs = { analyze: Hs, limits: Ws }, Vs = D, Tf = function(o, f) { + o = new Vs(o), f = new Vs(f); + var p = o.luminance(), b = f.luminance(); + return p > b ? (p + 0.05) / (b + 0.05) : (b + 0.05) / (p + 0.05); + }, Xs = D, Ht = Math.sqrt, Pe = Math.pow, Ef = Math.min, Lf = Math.max, Ys = Math.atan2, Gs = Math.abs, bi = Math.cos, Us = Math.sin, Mf = Math.exp, Zs = Math.PI, Bf = function(o, f, p, b, C) { + p === void 0 && (p = 1), b === void 0 && (b = 1), C === void 0 && (C = 1); + var A = function(ur) { + return 360 * ur / (2 * Zs); + }, S = function(ur) { + return 2 * Zs * ur / 360; + }; + o = new Xs(o), f = new Xs(f); + var R = Array.from(o.lab()), E = R[0], P = R[1], I = R[2], V = Array.from(f.lab()), F = V[0], U = V[1], G = V[2], ae = (E + F) / 2, he = Ht(Pe(P, 2) + Pe(I, 2)), ue = Ht(Pe(U, 2) + Pe(G, 2)), de = (he + ue) / 2, Ve = 0.5 * (1 - Ht(Pe(de, 7) / (Pe(de, 7) + Pe(25, 7)))), ze = P * (1 + Ve), tt = U * (1 + Ve), fe = Ht(Pe(ze, 2) + Pe(I, 2)), W = Ht(Pe(tt, 2) + Pe(G, 2)), te = (fe + W) / 2, oe = A(Ys(I, ze)), le = A(Ys(G, tt)), Xe = oe >= 0 ? oe : oe + 360, _e = le >= 0 ? le : le + 360, ce = Gs(Xe - _e) > 180 ? (Xe + _e + 360) / 2 : (Xe + _e) / 2, pe = 1 - 0.17 * bi(S(ce - 30)) + 0.24 * bi(S(2 * ce)) + 0.32 * bi(S(3 * ce + 6)) - 0.2 * bi(S(4 * ce - 63)), ve = _e - Xe; + ve = Gs(ve) <= 180 ? ve : _e <= Xe ? ve + 360 : ve - 360, ve = 2 * Ht(fe * W) * Us(S(ve) / 2); + var me = F - E, At = W - fe, rr = 1 + 0.015 * Pe(ae - 50, 2) / Ht(20 + Pe(ae - 50, 2)), ir = 1 + 0.045 * te, Ar = 1 + 0.015 * te * pe, Nr = 30 * Mf(-Pe((ce - 275) / 25, 2)), Wt = 2 * Ht(Pe(te, 7) / (Pe(te, 7) + Pe(25, 7))), fr = -Wt * Us(2 * S(Nr)), Yr = Ht(Pe(me / (p * rr), 2) + Pe(At / (b * ir), 2) + Pe(ve / (C * Ar), 2) + fr * (At / (b * ir)) * (ve / (C * Ar))); + return Lf(0, Ef(100, Yr)); + }, Ks = D, Df = function(o, f, p) { + p === void 0 && (p = "lab"), o = new Ks(o), f = new Ks(f); + var b = o.get(p), C = f.get(p), A = 0; + for (var S in b) { + var R = (b[S] || 0) - (C[S] || 0); + A += R * R; + } + return Math.sqrt(A); + }, Pf = D, $f = function() { + for (var o = [], f = arguments.length; f--; ) + o[f] = arguments[f]; + try { + return new (Function.prototype.bind.apply(Pf, [null].concat(o)))(), !0; + } catch { + return !1; + } + }, js = O, Js = wn, If = { + cool: function() { + return Js([js.hsl(180, 1, 0.9), js.hsl(250, 0.7, 0.4)]); + }, + hot: function() { + return Js(["#000", "#f00", "#ff0", "#fff"]).mode("rgb"); + } + }, wi = { + // sequential + OrRd: ["#fff7ec", "#fee8c8", "#fdd49e", "#fdbb84", "#fc8d59", "#ef6548", "#d7301f", "#b30000", "#7f0000"], + PuBu: ["#fff7fb", "#ece7f2", "#d0d1e6", "#a6bddb", "#74a9cf", "#3690c0", "#0570b0", "#045a8d", "#023858"], + BuPu: ["#f7fcfd", "#e0ecf4", "#bfd3e6", "#9ebcda", "#8c96c6", "#8c6bb1", "#88419d", "#810f7c", "#4d004b"], + Oranges: ["#fff5eb", "#fee6ce", "#fdd0a2", "#fdae6b", "#fd8d3c", "#f16913", "#d94801", "#a63603", "#7f2704"], + BuGn: ["#f7fcfd", "#e5f5f9", "#ccece6", "#99d8c9", "#66c2a4", "#41ae76", "#238b45", "#006d2c", "#00441b"], + YlOrBr: ["#ffffe5", "#fff7bc", "#fee391", "#fec44f", "#fe9929", "#ec7014", "#cc4c02", "#993404", "#662506"], + YlGn: ["#ffffe5", "#f7fcb9", "#d9f0a3", "#addd8e", "#78c679", "#41ab5d", "#238443", "#006837", "#004529"], + Reds: ["#fff5f0", "#fee0d2", "#fcbba1", "#fc9272", "#fb6a4a", "#ef3b2c", "#cb181d", "#a50f15", "#67000d"], + RdPu: ["#fff7f3", "#fde0dd", "#fcc5c0", "#fa9fb5", "#f768a1", "#dd3497", "#ae017e", "#7a0177", "#49006a"], + Greens: ["#f7fcf5", "#e5f5e0", "#c7e9c0", "#a1d99b", "#74c476", "#41ab5d", "#238b45", "#006d2c", "#00441b"], + YlGnBu: ["#ffffd9", "#edf8b1", "#c7e9b4", "#7fcdbb", "#41b6c4", "#1d91c0", "#225ea8", "#253494", "#081d58"], + Purples: ["#fcfbfd", "#efedf5", "#dadaeb", "#bcbddc", "#9e9ac8", "#807dba", "#6a51a3", "#54278f", "#3f007d"], + GnBu: ["#f7fcf0", "#e0f3db", "#ccebc5", "#a8ddb5", "#7bccc4", "#4eb3d3", "#2b8cbe", "#0868ac", "#084081"], + Greys: ["#ffffff", "#f0f0f0", "#d9d9d9", "#bdbdbd", "#969696", "#737373", "#525252", "#252525", "#000000"], + YlOrRd: ["#ffffcc", "#ffeda0", "#fed976", "#feb24c", "#fd8d3c", "#fc4e2a", "#e31a1c", "#bd0026", "#800026"], + PuRd: ["#f7f4f9", "#e7e1ef", "#d4b9da", "#c994c7", "#df65b0", "#e7298a", "#ce1256", "#980043", "#67001f"], + Blues: ["#f7fbff", "#deebf7", "#c6dbef", "#9ecae1", "#6baed6", "#4292c6", "#2171b5", "#08519c", "#08306b"], + PuBuGn: ["#fff7fb", "#ece2f0", "#d0d1e6", "#a6bddb", "#67a9cf", "#3690c0", "#02818a", "#016c59", "#014636"], + Viridis: ["#440154", "#482777", "#3f4a8a", "#31678e", "#26838f", "#1f9d8a", "#6cce5a", "#b6de2b", "#fee825"], + // diverging + Spectral: ["#9e0142", "#d53e4f", "#f46d43", "#fdae61", "#fee08b", "#ffffbf", "#e6f598", "#abdda4", "#66c2a5", "#3288bd", "#5e4fa2"], + RdYlGn: ["#a50026", "#d73027", "#f46d43", "#fdae61", "#fee08b", "#ffffbf", "#d9ef8b", "#a6d96a", "#66bd63", "#1a9850", "#006837"], + RdBu: ["#67001f", "#b2182b", "#d6604d", "#f4a582", "#fddbc7", "#f7f7f7", "#d1e5f0", "#92c5de", "#4393c3", "#2166ac", "#053061"], + PiYG: ["#8e0152", "#c51b7d", "#de77ae", "#f1b6da", "#fde0ef", "#f7f7f7", "#e6f5d0", "#b8e186", "#7fbc41", "#4d9221", "#276419"], + PRGn: ["#40004b", "#762a83", "#9970ab", "#c2a5cf", "#e7d4e8", "#f7f7f7", "#d9f0d3", "#a6dba0", "#5aae61", "#1b7837", "#00441b"], + RdYlBu: ["#a50026", "#d73027", "#f46d43", "#fdae61", "#fee090", "#ffffbf", "#e0f3f8", "#abd9e9", "#74add1", "#4575b4", "#313695"], + BrBG: ["#543005", "#8c510a", "#bf812d", "#dfc27d", "#f6e8c3", "#f5f5f5", "#c7eae5", "#80cdc1", "#35978f", "#01665e", "#003c30"], + RdGy: ["#67001f", "#b2182b", "#d6604d", "#f4a582", "#fddbc7", "#ffffff", "#e0e0e0", "#bababa", "#878787", "#4d4d4d", "#1a1a1a"], + PuOr: ["#7f3b08", "#b35806", "#e08214", "#fdb863", "#fee0b6", "#f7f7f7", "#d8daeb", "#b2abd2", "#8073ac", "#542788", "#2d004b"], + // qualitative + Set2: ["#66c2a5", "#fc8d62", "#8da0cb", "#e78ac3", "#a6d854", "#ffd92f", "#e5c494", "#b3b3b3"], + Accent: ["#7fc97f", "#beaed4", "#fdc086", "#ffff99", "#386cb0", "#f0027f", "#bf5b17", "#666666"], + Set1: ["#e41a1c", "#377eb8", "#4daf4a", "#984ea3", "#ff7f00", "#ffff33", "#a65628", "#f781bf", "#999999"], + Set3: ["#8dd3c7", "#ffffb3", "#bebada", "#fb8072", "#80b1d3", "#fdb462", "#b3de69", "#fccde5", "#d9d9d9", "#bc80bd", "#ccebc5", "#ffed6f"], + Dark2: ["#1b9e77", "#d95f02", "#7570b3", "#e7298a", "#66a61e", "#e6ab02", "#a6761d", "#666666"], + Paired: ["#a6cee3", "#1f78b4", "#b2df8a", "#33a02c", "#fb9a99", "#e31a1c", "#fdbf6f", "#ff7f00", "#cab2d6", "#6a3d9a", "#ffff99", "#b15928"], + Pastel2: ["#b3e2cd", "#fdcdac", "#cbd5e8", "#f4cae4", "#e6f5c9", "#fff2ae", "#f1e2cc", "#cccccc"], + Pastel1: ["#fbb4ae", "#b3cde3", "#ccebc5", "#decbe4", "#fed9a6", "#ffffcc", "#e5d8bd", "#fddaec", "#f2f2f2"] + }, Cn = 0, Qs = Object.keys(wi); Cn < Qs.length; Cn += 1) { + var ea = Qs[Cn]; + wi[ea.toLowerCase()] = wi[ea]; + } + var Of = wi, Fe = O; + Fe.average = jh, Fe.bezier = sf, Fe.blend = df, Fe.cubehelix = yf, Fe.mix = Fe.interpolate = Es, Fe.random = Nf, Fe.scale = wn, Fe.analyze = qs.analyze, Fe.contrast = Tf, Fe.deltaE = Bf, Fe.distance = Df, Fe.limits = qs.limits, Fe.valid = $f, Fe.scales = If, Fe.colors = cs, Fe.brewer = Of; + var Ff = Fe; + return Ff; + }); +})(ml); +var Bg = ml.exports; +const $a = ar, Dg = Mg, Pg = Bg; +let $g = class { + /** + * The constructor of the class Graph. + * + * @param {Vector2[]} points The centres of the gaussians. + * @param {Number[]} weights The weights / amplitudes for each gaussian. + */ + constructor(e, t, r, i, s = 0.3, a = 0, n = null, h = 1, l = !1) { + this.points = e, this.weights = t, this.width = r, this.height = i, this.sigma = s, this.interval = a, this.opacity = h, this.normalized = l, n === null && (n = [ + "#c51b7d", + "#de77ae", + "#f1b6da", + "#fde0ef", + "#ffffff", + "#e6f5d0", + "#b8e186", + "#7fbc41", + "#4d9221" + ]), this.colormap = n, this.canvas = document.createElement("canvas"), this.context = this.canvas.getContext("2d"), this.canvas.width = this.width, this.canvas.height = this.height; + } + setFromArray(e, t) { + this.points = [], e.forEach((r) => { + this.points.push(new $a(r[0], r[1])); + }), this.weights = [], t.forEach((r) => { + this.weights.push(r); + }); + } + /** + * Compute and draw the gaussians. + */ + draw() { + let e = []; + for (let s = 0; s < this.width; s++) { + let a = []; + for (let n = 0; n < this.height; n++) + a.push(0); + e.push(a); + } + let t = 1 / (2 * this.sigma ** 2); + for (let s = 0; s < this.points.length; s++) { + let a = this.points[s], n = this.weights[s]; + for (let h = 0; h < this.width; h++) + for (let l = 0; l < this.height; l++) { + let c = ((h - a.x) ** 2 + (l - a.y) ** 2) * t, u = n * Math.exp(-c); + e[h][l] += u; + } + } + let r = 1; + if (!this.normalized) { + let s = -Number.MAX_SAFE_INTEGER, a = Number.MAX_SAFE_INTEGER; + for (let n = 0; n < this.width; n++) + for (let h = 0; h < this.height; h++) + e[n][h] < a && (a = e[n][h]), e[n][h] > s && (s = e[n][h]); + r = Math.max(Math.abs(a), Math.abs(s)); + } + const i = Pg.scale(this.colormap).domain([-1, 1]); + for (let s = 0; s < this.width; s++) + for (let a = 0; a < this.height; a++) { + this.normalized || (e[s][a] = e[s][a] / r), this.interval !== 0 && (e[s][a] = Math.round(e[s][a] / this.interval) * this.interval); + let [n, h, l] = i(e[s][a]).rgb(); + this.setPixel(new $a(s, a), n, h, l); + } + } + /** + * Get the canvas as an HTML image. + * + * @param {CallableFunction} callback + */ + getImage(e) { + let t = new Image(); + t.onload = () => { + this.context.imageSmoothingEnabled = !1, this.context.drawImage(t, 0, 0, this.width, this.height), e && e(t); + }, t.onerror = function(r) { + console.log(r); + }, t.src = this.canvas.toDataURL(); + } + /** + * Get the canvas as an SVG element. + * + * @param {CallableFunction} callback + */ + getSVG() { + return Dg(this.context.getImageData(0, 0, this.width, this.height)); + } + /** + * Set the colour at a specific point on the canvas. + * + * @param {Vector2} vec The pixel position on the canvas. + * @param {Number} r The red colour-component. + * @param {Number} g The green colour-component. + * @param {Number} b The blue colour-component. + * @param {Number} a The alpha colour-component. + */ + setPixel(e, t, r, i) { + this.context.fillStyle = "rgba(" + t + "," + r + "," + i + "," + this.opacity + ")", this.context.fillRect(e.x, e.y, 1, 1); + } +}; +var bl = $g; +const Ia = Zr, Ig = Li(), Og = kg, Je = Xn, Fg = Un, zg = Yn, $e = ar, Hg = bl; +let Wg = class { + constructor(e, t = !0) { + this.preprocessor = new Og(e), this.opts = this.preprocessor.opts, this.clear = t, this.svgWrapper = null; + } + /** + * Draws the parsed smiles data to an svg element. + * + * @param {Object} data The tree returned by the smiles parser. + * @param {?(String|SVGElement)} target The id of the HTML svg element the structure is drawn to - or the element itself. + * @param {String} themeName='dark' The name of the theme to use. Built-in themes are 'light' and 'dark'. + * @param {Boolean} infoOnly=false Only output info on the molecule without drawing anything to the canvas. + * + * @returns {SVGElement} The svg element + */ + draw(e, t, r = "light", i = null, s = !1, a = [], n = !1) { + t === null || t === "svg" ? (t = document.createElementNS("http://www.w3.org/2000/svg", "svg"), t.setAttribute("xmlns", "http://www.w3.org/2000/svg"), t.setAttribute("xmlns:xlink", "http://www.w3.org/1999/xlink"), t.setAttributeNS(null, "width", this.opts.width), t.setAttributeNS(null, "height", this.opts.height)) : t instanceof String && (t = document.getElementById(t)); + let h = { + padding: this.opts.padding, + compactDrawing: this.opts.compactDrawing + }; + i !== null && (this.opts.padding += this.opts.weights.additionalPadding, this.opts.compactDrawing = !1); + let l = this.preprocessor; + return l.initDraw(e, r, s, a), s || (this.themeManager = new zg(this.opts.themes, r), (this.svgWrapper === null || this.clear) && (this.svgWrapper = new Fg(this.themeManager, t, this.opts, this.clear))), l.processGraph(), this.svgWrapper.determineDimensions(l.graph.vertices), this.drawAtomHighlights(l.opts.debug), this.drawEdges(l.opts.debug), this.drawVertices(l.opts.debug), i !== null && this.drawWeights(i, n), l.opts.debug && (console.log(l.graph), console.log(l.rings), console.log(l.ringConnections)), this.svgWrapper.constructSvg(), i !== null && (this.opts.padding = h.padding, this.opts.compactDrawing = h.padding), t; + } + /** + * Draws the parsed smiles data to a canvas element. + * + * @param {Object} data The tree returned by the smiles parser. + * @param {(String|HTMLCanvasElement)} target The id of the HTML canvas element the structure is drawn to - or the element itself. + * @param {String} themeName='dark' The name of the theme to use. Built-in themes are 'light' and 'dark'. + * @param {Boolean} infoOnly=false Only output info on the molecule without drawing anything to the canvas. + */ + drawCanvas(e, t, r = "light", i = !1) { + let s = null; + typeof t == "string" || t instanceof String ? s = document.getElementById(t) : s = t; + let a = document.createElementNS("http://www.w3.org/2000/svg", "svg"); + return a.setAttribute("xmlns", "http://www.w3.org/2000/svg"), a.setAttributeNS(null, "viewBox", "0 0 500 500"), a.setAttributeNS(null, "width", "500"), a.setAttributeNS(null, "height", "500"), a.setAttributeNS(null, "style", "visibility: hidden: position: absolute; left: -1000px"), document.body.appendChild(a), this.svgDrawer.draw(e, a, r, i), this.svgDrawer.svgWrapper.toCanvas(s, this.svgDrawer.opts.width, this.svgDrawer.opts.height), document.body.removeChild(a), t; + } + /** + * Draws a ring inside a provided ring, indicating aromaticity. + * + * @param {Ring} ring A ring. + */ + drawAromaticityRing(e) { + this.svgWrapper.drawRing(e.center.x, e.center.y, e.getSize()); + } + /** + * Draw the actual edges as bonds. + * + * @param {Boolean} debug A boolean indicating whether or not to draw debug helpers. + */ + drawEdges(e) { + let t = this.preprocessor, r = t.graph, i = t.rings, s = Array(this.preprocessor.graph.edges.length); + if (s.fill(!1), r.traverseBF(0, (n) => { + let h = r.getEdges(n.id); + for (var l = 0; l < h.length; l++) { + let c = h[l]; + s[c] || (s[c] = !0, this.drawEdge(c, e)); + } + }), !this.bridgedRing) + for (var a = 0; a < i.length; a++) { + let n = i[a]; + t.isRingAromatic(n) && this.drawAromaticityRing(n); + } + } + /** + * Draw the an edge as a bond. + * + * @param {Number} edgeId An edge id. + * @param {Boolean} debug A boolean indicating whether or not to draw debug helpers. + */ + drawEdge(e, t) { + let r = this.preprocessor, i = r.opts, s = this.svgWrapper, a = r.graph.edges[e], n = r.graph.vertices[a.sourceId], h = r.graph.vertices[a.targetId], l = n.value.element, c = h.value.element; + if ((!n.value.isDrawn || !h.value.isDrawn) && r.opts.atomVisualization === "default") + return; + let u = n.position, g = h.position, m = r.getEdgeNormals(a), _ = Ia.clone(m); + if (_[0].multiplyScalar(10).add(u), _[1].multiplyScalar(10).add(u), a.bondType === "=" || r.getRingbondType(n, h) === "=" || a.isPartOfAromaticRing && r.bridgedRing) { + let v = r.areVerticesInSameRing(n, h), N = r.chooseSide(n, h, _); + if (v) { + let x = r.getLargestOrAromaticCommonRing(n, h).center; + m[0].multiplyScalar(i.bondSpacing), m[1].multiplyScalar(i.bondSpacing); + let L = null; + x.sameSideAs(n.position, h.position, $e.add(u, m[0])) ? L = new Je($e.add(u, m[0]), $e.add(g, m[0]), l, c) : L = new Je($e.add(u, m[1]), $e.add(g, m[1]), l, c), L.shorten(i.bondLength - i.shortBondLength * i.bondLength), a.isPartOfAromaticRing ? s.drawLine(L, !0) : s.drawLine(L), s.drawLine(new Je(u, g, l, c)); + } else if (a.center || n.isTerminal() && h.isTerminal() || N.anCount == 0 && N.bnCount > 1 || N.bnCount == 0 && N.anCount > 1) { + this.multiplyNormals(m, i.halfBondSpacing); + let B = new Je($e.add(u, m[0]), $e.add(g, m[0]), l, c), x = new Je($e.add(u, m[1]), $e.add(g, m[1]), l, c); + s.drawLine(B), s.drawLine(x); + } else if (N.sideCount[0] > N.sideCount[1] || N.totalSideCount[0] > N.totalSideCount[1]) { + this.multiplyNormals(m, i.bondSpacing); + let B = new Je($e.add(u, m[0]), $e.add(g, m[0]), l, c); + B.shorten(i.bondLength - i.shortBondLength * i.bondLength), s.drawLine(B), s.drawLine(new Je(u, g, l, c)); + } else if (N.sideCount[0] < N.sideCount[1] || N.totalSideCount[0] <= N.totalSideCount[1]) { + this.multiplyNormals(m, i.bondSpacing); + let B = new Je($e.add(u, m[1]), $e.add(g, m[1]), l, c); + B.shorten(i.bondLength - i.shortBondLength * i.bondLength), s.drawLine(B), s.drawLine(new Je(u, g, l, c)); + } + } else if (a.bondType === "#") { + m[0].multiplyScalar(i.bondSpacing / 1.5), m[1].multiplyScalar(i.bondSpacing / 1.5); + let v = new Je($e.add(u, m[0]), $e.add(g, m[0]), l, c), N = new Je($e.add(u, m[1]), $e.add(g, m[1]), l, c); + s.drawLine(v), s.drawLine(N), s.drawLine(new Je(u, g, l, c)); + } else if (a.bondType !== ".") { + let v = n.value.isStereoCenter, N = h.value.isStereoCenter; + a.wedge === "up" ? s.drawWedge(new Je(u, g, l, c, v, N)) : a.wedge === "down" ? s.drawDashedWedge(new Je(u, g, l, c, v, N)) : s.drawLine(new Je(u, g, l, c, v, N)); + } + if (t) { + let v = $e.midpoint(u, g); + s.drawDebugText(v.x, v.y, "e: " + e); + } + } + /** + * Draw the highlights for atoms to the canvas. + * + * @param {Boolean} debug + */ + drawAtomHighlights(e) { + let t = this.preprocessor; + t.opts; + let r = t.graph; + t.rings; + let i = this.svgWrapper; + for (var s = 0; s < r.vertices.length; s++) { + let n = r.vertices[s], h = n.value; + for (var a = 0; a < t.highlight_atoms.length; a++) { + let l = t.highlight_atoms[a]; + h.class === l[0] && i.drawAtomHighlight(n.position.x, n.position.y, l[1]); + } + } + } + /** + * Draws the vertices representing atoms to the canvas. + * + * @param {Boolean} debug A boolean indicating whether or not to draw debug messages to the canvas. + */ + drawVertices(e) { + let t = this.preprocessor, r = t.opts, i = t.graph, s = t.rings, a = this.svgWrapper; + for (var n = i.vertices.length, n = 0; n < i.vertices.length; n++) { + let l = i.vertices[n], c = l.value, u = 0, g = 0, m = l.value.bondCount, _ = c.element, v = Ig.maxBonds[_] - m, N = l.getTextDirection(i.vertices, c.hasAttachedPseudoElements), B = r.terminalCarbons || _ !== "C" || c.hasAttachedPseudoElements ? l.isTerminal() : !1, x = c.element === "C"; + if (i.vertices.length < 3 && (x = !1), c.element === "N" && c.isPartOfAromaticRing && (v = 0), c.bracket && (v = c.bracket.hcount, u = c.bracket.charge, g = c.bracket.isotope), r.atomVisualization === "allballs") + a.drawBall(l.position.x, l.position.y, _); + else if (c.isDrawn && (!x || c.drawExplicit || B || c.hasAttachedPseudoElements) || i.vertices.length === 1) + if (r.atomVisualization === "default") { + let L = c.getAttachedPseudoElements(); + c.hasAttachedPseudoElements && i.vertices.length === Object.keys(L).length + 1 && (N = "right"), a.drawText( + l.position.x, + l.position.y, + _, + v, + N, + B, + u, + g, + i.vertices.length, + L + ); + } else + r.atomVisualization === "balls" && a.drawBall(l.position.x, l.position.y, _); + else if (l.getNeighbourCount() === 2 && l.forcePositioned == !0) { + let L = i.vertices[l.neighbours[0]].position, k = i.vertices[l.neighbours[1]].position, z = $e.threePointangle(l.position, L, k); + Math.abs(Math.PI - z) < 0.1 && a.drawPoint(l.position.x, l.position.y, _); + } + if (e) { + let L = "v: " + l.id + " " + Ia.print(c.ringbonds); + a.drawDebugText(l.position.x, l.position.y, L); + } + } + if (r.debug) + for (var n = 0; n < s.length; n++) { + let l = s[n].center; + a.drawDebugPoint(l.x, l.y, "r: " + s[n].id); + } + } + /** + * Draw the weights on a background image. + * @param {Number[]} weights The weights assigned to each atom. + */ + drawWeights(e, t) { + if (e.every((s) => s === 0)) + return; + if (e.length !== this.preprocessor.graph.atomIdxToVertexId.length) + throw new Error("The number of weights supplied must be equal to the number of (heavy) atoms in the molecule."); + let r = []; + for (const s of this.preprocessor.graph.atomIdxToVertexId) { + let a = this.preprocessor.graph.vertices[s]; + r.push( + new $e( + a.position.x - this.svgWrapper.minX, + a.position.y - this.svgWrapper.minY + ) + ); + } + let i = new Hg( + r, + e, + this.svgWrapper.drawingWidth, + this.svgWrapper.drawingHeight, + this.opts.weights.sigma, + this.opts.weights.interval, + this.opts.weights.colormap, + this.opts.weights.opacity, + t + ); + i.draw(), this.svgWrapper.addLayer(i.getSVG()); + } + /** + * Returns the total overlap score of the current molecule. + * + * @returns {Number} The overlap score. + */ + getTotalOverlapScore() { + return this.preprocessor.getTotalOverlapScore(); + } + /** + * Returns the molecular formula of the loaded molecule as a string. + * + * @returns {String} The molecular formula. + */ + getMolecularFormula(e = null) { + return this.preprocessor.getMolecularFormula(e); + } + /** + * @param {Array} normals list of normals to multiply + * @param {Number} spacing value to multiply normals by + */ + multiplyNormals(e, t) { + e[0].multiplyScalar(t), e[1].multiplyScalar(t); + } +}; +var Mi = Wg; +const qg = Mi; +let Vg = class { + /** + * The constructor for the class SmilesDrawer. + * + * @param {Object} options An object containing custom values for different options. It is merged with the default options. + */ + constructor(e) { + this.svgDrawer = new qg(e); + } + /** + * Draws the parsed smiles data to a canvas element. + * + * @param {Object} data The tree returned by the smiles parser. + * @param {(String|HTMLCanvasElement)} target The id of the HTML canvas element the structure is drawn to - or the element itself. + * @param {String} themeName='dark' The name of the theme to use. Built-in themes are 'light' and 'dark'. + * @param {Boolean} infoOnly=false Only output info on the molecule without drawing anything to the canvas. + */ + draw(e, t, r = "light", i = !1, s = []) { + let a = null; + typeof t == "string" || t instanceof String ? a = document.getElementById(t) : a = t; + let n = document.createElementNS("http://www.w3.org/2000/svg", "svg"); + n.setAttribute("xmlns", "http://www.w3.org/2000/svg"), n.setAttributeNS(null, "viewBox", "0 0 " + this.svgDrawer.opts.width + " " + this.svgDrawer.opts.height), n.setAttributeNS(null, "width", this.svgDrawer.opts.width + ""), n.setAttributeNS(null, "height", this.svgDrawer.opts.height + ""), this.svgDrawer.draw(e, n, r, i, s), this.svgDrawer.svgWrapper.toCanvas(a, this.svgDrawer.opts.width, this.svgDrawer.opts.height); + } + /** + * Returns the total overlap score of the current molecule. + * + * @returns {Number} The overlap score. + */ + getTotalOverlapScore() { + return this.svgDrawer.getTotalOverlapScore(); + } + /** + * Returns the molecular formula of the loaded molecule as a string. + * + * @returns {String} The molecular formula. + */ + getMolecularFormula() { + this.svgDrawer.getMolecularFormula(); + } +}; +var Xg = Vg, Zn = function() { + function d(r, i) { + function s() { + this.constructor = r; + } + s.prototype = i.prototype, r.prototype = new s(); + } + function e(r, i, s, a) { + this.message = r, this.expected = i, this.found = s, this.location = a, this.name = "SyntaxError", typeof Error.captureStackTrace == "function" && Error.captureStackTrace(this, e); + } + d(e, Error), e.buildMessage = function(r, i) { + var s = { + literal: function(g) { + return '"' + n(g.text) + '"'; + }, + class: function(g) { + var m = "", _; + for (_ = 0; _ < g.parts.length; _++) + m += g.parts[_] instanceof Array ? h(g.parts[_][0]) + "-" + h(g.parts[_][1]) : h(g.parts[_]); + return "[" + (g.inverted ? "^" : "") + m + "]"; + }, + any: function(g) { + return "any character"; + }, + end: function(g) { + return "end of input"; + }, + other: function(g) { + return g.description; + } + }; + function a(g) { + return g.charCodeAt(0).toString(16).toUpperCase(); + } + function n(g) { + return g.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\0/g, "\\0").replace(/\t/g, "\\t").replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/[\x00-\x0F]/g, function(m) { + return "\\x0" + a(m); + }).replace(/[\x10-\x1F\x7F-\x9F]/g, function(m) { + return "\\x" + a(m); + }); + } + function h(g) { + return g.replace(/\\/g, "\\\\").replace(/\]/g, "\\]").replace(/\^/g, "\\^").replace(/-/g, "\\-").replace(/\0/g, "\\0").replace(/\t/g, "\\t").replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/[\x00-\x0F]/g, function(m) { + return "\\x0" + a(m); + }).replace(/[\x10-\x1F\x7F-\x9F]/g, function(m) { + return "\\x" + a(m); + }); + } + function l(g) { + return s[g.type](g); + } + function c(g) { + var m = new Array(g.length), _, v; + for (_ = 0; _ < g.length; _++) + m[_] = l(g[_]); + if (m.sort(), m.length > 0) { + for (_ = 1, v = 1; _ < m.length; _++) + m[_ - 1] !== m[_] && (m[v] = m[_], v++); + m.length = v; + } + switch (m.length) { + case 1: + return m[0]; + case 2: + return m[0] + " or " + m[1]; + default: + return m.slice(0, -1).join(", ") + ", or " + m[m.length - 1]; + } + } + function u(g) { + return g ? '"' + n(g) + '"' : "end of input"; + } + return "Expected " + c(r) + " but " + u(i) + " found."; + }; + function t(r, i) { + i = i !== void 0 ? i : {}; + var s = r.split("(").length - 1, a = r.split(")").length - 1; + if (s !== a) + throw Hr("The number of opening parentheses does not match the number of closing parentheses.", 0); + var n = {}, h = { + chain: lr + }, l = lr, c = function(M) { + for (var w = [], $ = [], T = 0; T < M[1].length; T++) + w.push(M[1][T]); + for (var T = 0; T < M[2].length; T++) { + var H = M[2][T][0] ? M[2][T][0] : "-"; + $.push({ + bond: H, + id: M[2][T][1] + }); + } + for (var T = 0; T < M[3].length; T++) + w.push(M[3][T]); + for (var T = 0; T < M[6].length; T++) + w.push(M[6][T]); + return { + atom: M[0], + isBracket: !!M[0].element, + branches: w, + branchCount: w.length, + ringbonds: $, + ringbondCount: $.length, + bond: M[4] ? M[4] : "-", + next: M[5], + hasNext: !!M[5] + }; + }, u = "(", g = Ne("(", !1), m = ")", _ = Ne(")", !1), v = function(M) { + var w = M[1] ? M[1] : "-"; + return M[2].branchBond = w, M[2]; + }, N = function(M) { + return M; + }, B = /^[\-=#$:\/\\.]/, x = ft(["-", "=", "#", "$", ":", "/", "\\", "."], !1, !1), L = function(M) { + return M; + }, k = "[", z = Ne("[", !1), D = "se", Y = Ne("se", !1), O = "as", Z = Ne("as", !1), j = "]", q = Ne("]", !1), se = function(M) { + return { + isotope: M[1], + element: M[2], + chirality: M[3], + hcount: M[4], + charge: M[5], + class: M[6] + }; + }, ye = "B", ke = Ne("B", !1), xe = "r", we = Ne("r", !1), Ee = "C", Qe = Ne("C", !1), Ce = "l", Ae = Ne("l", !1), Be = /^[NOPSFI]/, st = ft(["N", "O", "P", "S", "F", "I"], !1, !1), It = function(M) { + return M.length > 1 ? M.join("") : M; + }, wt = /^[bcnops]/, K = ft(["b", "c", "n", "o", "p", "s"], !1, !1), Ot = "*", J = Ne("*", !1), Te = function(M) { + return M; + }, et = /^[A-Z]/, Ie = ft([ + ["A", "Z"] + ], !1, !1), Ye = /^[a-z]/, Ue = ft([ + ["a", "z"] + ], !1, !1), Ge = function(M) { + return M.join(""); + }, De = "%", Ze = Ne("%", !1), He = /^[1-9]/, We = ft([ + ["1", "9"] + ], !1, !1), Le = /^[0-9]/, qe = ft([ + ["0", "9"] + ], !1, !1), Lt = function(M) { + return M.length == 1 ? Number(M) : Number(M.join("").replace("%", "")); + }, yt = "@", Vt = Ne("@", !1), Xt = "TH", Yt = Ne("TH", !1), Ft = /^[12]/, _t = ft(["1", "2"], !1, !1), zt = "AL", Gt = Ne("AL", !1), Ut = "SP", Zt = Ne("SP", !1), Bi = /^[1-3]/, Di = ft([ + ["1", "3"] + ], !1, !1), Fr = "TB", Jr = Ne("TB", !1), Qr = "OH", Pi = Ne("OH", !1), ei = function(M) { + return M[1] ? M[1] == "@" ? "@@" : M[1].join("").replace(",", "") : "@"; + }, ti = function(M) { + return M; + }, ri = "+", ii = Ne("+", !1), $i = function(M) { + return M[1] ? M[1] != "+" ? Number(M[1].join("")) : 2 : 1; + }, ni = "-", si = Ne("-", !1), Ii = function(M) { + return M[1] ? M[1] != "-" ? -Number(M[1].join("")) : -2 : -1; + }, Oi = "H", Fi = Ne("H", !1), zi = function(M) { + return M[1] ? Number(M[1]) : 1; + }, Hi = ":", Wi = Ne(":", !1), qi = /^[0]/, Vi = ft(["0"], !1, !1), ai = function(M) { + return Number(M[1][0] + M[1][1].join("")); + }, li = function(M) { + return Number(M.join("")); + }, y = 0, vr = [{ + line: 1, + column: 1 + }], ht = 0, Kt = [], mr; + if ("startRule" in i) { + if (!(i.startRule in h)) + throw new Error(`Can't start parsing from rule "` + i.startRule + '".'); + l = h[i.startRule]; + } + function Ne(M, w) { + return { + type: "literal", + text: M, + ignoreCase: w + }; + } + function ft(M, w, $) { + return { + type: "class", + parts: M, + inverted: w, + ignoreCase: $ + }; + } + function Xi() { + return { + type: "end" + }; + } + function oi(M) { + var w = vr[M], $; + if (w) + return w; + for ($ = M - 1; !vr[$]; ) + $--; + for (w = vr[$], w = { + line: w.line, + column: w.column + }; $ < M; ) + r.charCodeAt($) === 10 ? (w.line++, w.column = 1) : w.column++, $++; + return vr[M] = w, w; + } + function zr(M, w) { + var $ = oi(M), T = oi(w); + return { + start: { + offset: M, + line: $.line, + column: $.column + }, + end: { + offset: w, + line: T.line, + column: T.column + } + }; + } + function Q(M) { + y < ht || (y > ht && (ht = y, Kt = []), Kt.push(M)); + } + function Hr(M, w) { + return new e(M, null, null, w); + } + function Yi(M, w, $) { + return new e( + e.buildMessage(M, w), + M, + w, + $ + ); + } + function lr() { + var M, w, $, T, H, X, ee, Oe, at, ut; + if (M = y, w = y, $ = Gi(), $ !== n) { + for (T = [], H = jt(); H !== n; ) + T.push(H), H = jt(); + if (T !== n) { + for (H = [], X = y, ee = or(), ee === n && (ee = null), ee !== n ? (Oe = ui(), Oe !== n ? (ee = [ee, Oe], X = ee) : (y = X, X = n)) : (y = X, X = n); X !== n; ) + H.push(X), X = y, ee = or(), ee === n && (ee = null), ee !== n ? (Oe = ui(), Oe !== n ? (ee = [ee, Oe], X = ee) : (y = X, X = n)) : (y = X, X = n); + if (H !== n) { + for (X = [], ee = jt(); ee !== n; ) + X.push(ee), ee = jt(); + if (X !== n) + if (ee = or(), ee === n && (ee = null), ee !== n) + if (Oe = lr(), Oe === n && (Oe = null), Oe !== n) { + for (at = [], ut = jt(); ut !== n; ) + at.push(ut), ut = jt(); + at !== n ? ($ = [$, T, H, X, ee, Oe, at], w = $) : (y = w, w = n); + } else + y = w, w = n; + else + y = w, w = n; + else + y = w, w = n; + } else + y = w, w = n; + } else + y = w, w = n; + } else + y = w, w = n; + return w !== n && (w = c(w)), M = w, M; + } + function jt() { + var M, w, $, T, H, X; + return M = y, w = y, r.charCodeAt(y) === 40 ? ($ = u, y++) : ($ = n, Q(g)), $ !== n ? (T = or(), T === n && (T = null), T !== n ? (H = lr(), H !== n ? (r.charCodeAt(y) === 41 ? (X = m, y++) : (X = n, Q(_)), X !== n ? ($ = [$, T, H, X], w = $) : (y = w, w = n)) : (y = w, w = n)) : (y = w, w = n)) : (y = w, w = n), w !== n && (w = v(w)), M = w, M; + } + function Gi() { + var M, w; + return M = y, w = Zi(), w === n && (w = hi(), w === n && (w = Ui(), w === n && (w = fi()))), w !== n && (w = N(w)), M = w, M; + } + function or() { + var M, w; + if (M = y, B.test(r.charAt(y))) { + if (w = r.charAt(y), w === r.charAt(y + 1)) + throw w = n, Hr("The parser encountered a bond repetition.", y + 1); + y++; + } else + w = n, Q(x); + return w !== n && (w = L(w)), M = w, M; + } + function Ui() { + var M, w, $, T, H, X, ee, Oe, at, ut; + return M = y, w = y, r.charCodeAt(y) === 91 ? ($ = k, y++) : ($ = n, Q(z)), $ !== n ? (T = Qi(), T === n && (T = null), T !== n ? (r.substr(y, 2) === D ? (H = D, y += 2) : (H = n, Q(Y)), H === n && (r.substr(y, 2) === O ? (H = O, y += 2) : (H = n, Q(Z)), H === n && (H = hi(), H === n && (H = Ki(), H === n && (H = fi())))), H !== n ? (X = Wr(), X === n && (X = null), X !== n ? (ee = ji(), ee === n && (ee = null), ee !== n ? (Oe = Jt(), Oe === n && (Oe = null), Oe !== n ? (at = Ji(), at === n && (at = null), at !== n ? (r.charCodeAt(y) === 93 ? (ut = j, y++) : (ut = n, Q(q)), ut !== n ? ($ = [$, T, H, X, ee, Oe, at, ut], w = $) : (y = w, w = n)) : (y = w, w = n)) : (y = w, w = n)) : (y = w, w = n)) : (y = w, w = n)) : (y = w, w = n)) : (y = w, w = n)) : (y = w, w = n), w !== n && (w = se(w)), M = w, M; + } + function Zi() { + var M, w, $, T; + return M = y, w = y, r.charCodeAt(y) === 66 ? ($ = ye, y++) : ($ = n, Q(ke)), $ !== n ? (r.charCodeAt(y) === 114 ? (T = xe, y++) : (T = n, Q(we)), T === n && (T = null), T !== n ? ($ = [$, T], w = $) : (y = w, w = n)) : (y = w, w = n), w === n && (w = y, r.charCodeAt(y) === 67 ? ($ = Ee, y++) : ($ = n, Q(Qe)), $ !== n ? (r.charCodeAt(y) === 108 ? (T = Ce, y++) : (T = n, Q(Ae)), T === n && (T = null), T !== n ? ($ = [$, T], w = $) : (y = w, w = n)) : (y = w, w = n), w === n && (Be.test(r.charAt(y)) ? (w = r.charAt(y), y++) : (w = n, Q(st)))), w !== n && (w = It(w)), M = w, M; + } + function hi() { + var M, w; + return M = y, wt.test(r.charAt(y)) ? (w = r.charAt(y), y++) : (w = n, Q(K)), w !== n && (w = N(w)), M = w, M; + } + function fi() { + var M, w; + return M = y, r.charCodeAt(y) === 42 ? (w = Ot, y++) : (w = n, Q(J)), w !== n && (w = Te(w)), M = w, M; + } + function Ki() { + var M, w, $, T; + return M = y, w = y, et.test(r.charAt(y)) ? ($ = r.charAt(y), y++) : ($ = n, Q(Ie)), $ !== n ? (Ye.test(r.charAt(y)) ? (T = r.charAt(y), y++) : (T = n, Q(Ue)), T === n && (T = null), T !== n ? ($ = [$, T], w = $) : (y = w, w = n)) : (y = w, w = n), w !== n && (w = Ge(w)), M = w, M; + } + function ui() { + var M, w, $, T, H; + return M = y, w = y, r.charCodeAt(y) === 37 ? ($ = De, y++) : ($ = n, Q(Ze)), $ !== n ? (He.test(r.charAt(y)) ? (T = r.charAt(y), y++) : (T = n, Q(We)), T !== n ? (Le.test(r.charAt(y)) ? (H = r.charAt(y), y++) : (H = n, Q(qe)), H !== n ? ($ = [$, T, H], w = $) : (y = w, w = n)) : (y = w, w = n)) : (y = w, w = n), w === n && (Le.test(r.charAt(y)) ? (w = r.charAt(y), y++) : (w = n, Q(qe))), w !== n && (w = Lt(w)), M = w, M; + } + function Wr() { + var M, w, $, T, H, X, ee; + return M = y, w = y, r.charCodeAt(y) === 64 ? ($ = yt, y++) : ($ = n, Q(Vt)), $ !== n ? (r.charCodeAt(y) === 64 ? (T = yt, y++) : (T = n, Q(Vt)), T === n && (T = y, r.substr(y, 2) === Xt ? (H = Xt, y += 2) : (H = n, Q(Yt)), H !== n ? (Ft.test(r.charAt(y)) ? (X = r.charAt(y), y++) : (X = n, Q(_t)), X !== n ? (H = [H, X], T = H) : (y = T, T = n)) : (y = T, T = n), T === n && (T = y, r.substr(y, 2) === zt ? (H = zt, y += 2) : (H = n, Q(Gt)), H !== n ? (Ft.test(r.charAt(y)) ? (X = r.charAt(y), y++) : (X = n, Q(_t)), X !== n ? (H = [H, X], T = H) : (y = T, T = n)) : (y = T, T = n), T === n && (T = y, r.substr(y, 2) === Ut ? (H = Ut, y += 2) : (H = n, Q(Zt)), H !== n ? (Bi.test(r.charAt(y)) ? (X = r.charAt(y), y++) : (X = n, Q(Di)), X !== n ? (H = [H, X], T = H) : (y = T, T = n)) : (y = T, T = n), T === n && (T = y, r.substr(y, 2) === Fr ? (H = Fr, y += 2) : (H = n, Q(Jr)), H !== n ? (He.test(r.charAt(y)) ? (X = r.charAt(y), y++) : (X = n, Q(We)), X !== n ? (Le.test(r.charAt(y)) ? (ee = r.charAt(y), y++) : (ee = n, Q(qe)), ee === n && (ee = null), ee !== n ? (H = [H, X, ee], T = H) : (y = T, T = n)) : (y = T, T = n)) : (y = T, T = n), T === n && (T = y, r.substr(y, 2) === Qr ? (H = Qr, y += 2) : (H = n, Q(Pi)), H !== n ? (He.test(r.charAt(y)) ? (X = r.charAt(y), y++) : (X = n, Q(We)), X !== n ? (Le.test(r.charAt(y)) ? (ee = r.charAt(y), y++) : (ee = n, Q(qe)), ee === n && (ee = null), ee !== n ? (H = [H, X, ee], T = H) : (y = T, T = n)) : (y = T, T = n)) : (y = T, T = n)))))), T === n && (T = null), T !== n ? ($ = [$, T], w = $) : (y = w, w = n)) : (y = w, w = n), w !== n && (w = ei(w)), M = w, M; + } + function Jt() { + var M, w; + return M = y, w = qr(), w === n && (w = Qt()), w !== n && (w = ti(w)), M = w, M; + } + function qr() { + var M, w, $, T, H, X; + return M = y, w = y, r.charCodeAt(y) === 43 ? ($ = ri, y++) : ($ = n, Q(ii)), $ !== n ? (r.charCodeAt(y) === 43 ? (T = ri, y++) : (T = n, Q(ii)), T === n && (T = y, He.test(r.charAt(y)) ? (H = r.charAt(y), y++) : (H = n, Q(We)), H !== n ? (Le.test(r.charAt(y)) ? (X = r.charAt(y), y++) : (X = n, Q(qe)), X === n && (X = null), X !== n ? (H = [H, X], T = H) : (y = T, T = n)) : (y = T, T = n)), T === n && (T = null), T !== n ? ($ = [$, T], w = $) : (y = w, w = n)) : (y = w, w = n), w !== n && (w = $i(w)), M = w, M; + } + function Qt() { + var M, w, $, T, H, X; + return M = y, w = y, r.charCodeAt(y) === 45 ? ($ = ni, y++) : ($ = n, Q(si)), $ !== n ? (r.charCodeAt(y) === 45 ? (T = ni, y++) : (T = n, Q(si)), T === n && (T = y, He.test(r.charAt(y)) ? (H = r.charAt(y), y++) : (H = n, Q(We)), H !== n ? (Le.test(r.charAt(y)) ? (X = r.charAt(y), y++) : (X = n, Q(qe)), X === n && (X = null), X !== n ? (H = [H, X], T = H) : (y = T, T = n)) : (y = T, T = n)), T === n && (T = null), T !== n ? ($ = [$, T], w = $) : (y = w, w = n)) : (y = w, w = n), w !== n && (w = Ii(w)), M = w, M; + } + function ji() { + var M, w, $, T; + return M = y, w = y, r.charCodeAt(y) === 72 ? ($ = Oi, y++) : ($ = n, Q(Fi)), $ !== n ? (Le.test(r.charAt(y)) ? (T = r.charAt(y), y++) : (T = n, Q(qe)), T === n && (T = null), T !== n ? ($ = [$, T], w = $) : (y = w, w = n)) : (y = w, w = n), w !== n && (w = zi(w)), M = w, M; + } + function Ji() { + var M, w, $, T, H, X, ee; + if (M = y, w = y, r.charCodeAt(y) === 58 ? ($ = Hi, y++) : ($ = n, Q(Wi)), $ !== n) { + if (T = y, He.test(r.charAt(y)) ? (H = r.charAt(y), y++) : (H = n, Q(We)), H !== n) { + for (X = [], Le.test(r.charAt(y)) ? (ee = r.charAt(y), y++) : (ee = n, Q(qe)); ee !== n; ) + X.push(ee), Le.test(r.charAt(y)) ? (ee = r.charAt(y), y++) : (ee = n, Q(qe)); + X !== n ? (H = [H, X], T = H) : (y = T, T = n); + } else + y = T, T = n; + T === n && (qi.test(r.charAt(y)) ? (T = r.charAt(y), y++) : (T = n, Q(Vi))), T !== n ? ($ = [$, T], w = $) : (y = w, w = n); + } else + y = w, w = n; + return w !== n && (w = ai(w)), M = w, M; + } + function Qi() { + var M, w, $, T, H; + return M = y, w = y, He.test(r.charAt(y)) ? ($ = r.charAt(y), y++) : ($ = n, Q(We)), $ !== n ? (Le.test(r.charAt(y)) ? (T = r.charAt(y), y++) : (T = n, Q(qe)), T === n && (T = null), T !== n ? (Le.test(r.charAt(y)) ? (H = r.charAt(y), y++) : (H = n, Q(qe)), H === n && (H = null), H !== n ? ($ = [$, T, H], w = $) : (y = w, w = n)) : (y = w, w = n)) : (y = w, w = n), w !== n && (w = li(w)), M = w, M; + } + if (mr = l(), mr !== n && y === r.length) + return mr; + throw mr !== n && y < r.length && Q(Xi()), Yi( + Kt, + ht < r.length ? r.charAt(ht) : null, + ht < r.length ? zr(ht, ht + 1) : zr(ht, ht) + ); + } + return { + SyntaxError: e, + parse: t + }; +}(); +const Dn = Zn; +let Yg = class { + /** + * The constructor for the class Reaction. + * + * @param {string} reactionSmiles A reaction SMILES. + */ + constructor(e) { + this.reactantsSmiles = [], this.reagentsSmiles = [], this.productsSmiles = [], this.reactantsWeights = [], this.reagentsWeights = [], this.productsWeights = [], this.reactants = [], this.reagents = [], this.products = []; + let t = e.split(">"); + if (t.length !== 3) + throw new Error("Invalid reaction SMILES. Did you add fewer than or more than two '>'?"); + t[0] !== "" && (this.reactantsSmiles = t[0].split(".")), t[1] !== "" && (this.reagentsSmiles = t[1].split(".")), t[2] !== "" && (this.productsSmiles = t[2].split(".")); + for (var r = 0; r < this.reactantsSmiles.length; r++) + this.reactants.push(Dn.parse(this.reactantsSmiles[r])); + for (var r = 0; r < this.reagentsSmiles.length; r++) + this.reagents.push(Dn.parse(this.reagentsSmiles[r])); + for (var r = 0; r < this.productsSmiles.length; r++) + this.products.push(Dn.parse(this.productsSmiles[r])); + } +}; +var Gg = Yg; +const Ug = Gg; +let Zg = class { + /** + * Returns the hex code of a color associated with a key from the current theme. + * + * @param {String} reactionSmiles A reaction SMILES. + * @returns {Reaction} A reaction object. + */ + static parse(e) { + return new Ug(e); + } +}; +var wl = Zg; +const Kg = { + C2H4O2: "acetic acid", + C3H6O: "acetone", + C2H3N: "acetonitrile", + C6H6: "benzene", + CCl4: "carbon tetrachloride", + C6H5Cl: "chlorobenzene", + CHCl3: "chloroform", + C6H12: "cyclohexane", + C2H4Cl2: "1,2-dichloroethane", + C4H10O3: "diethylene glycol", + C6H14O3: "diglyme", + C4H10O2: "DME", + C3H7NO: "DMF", + C2H6OS: "DMSO", + C2H6O: "ethanol", + C2H6O2: "ethylene glycol", + C3H8O3: "glycerin", + C7H16: "heptane", + C6H18N3OP: "HMPA", + C6H18N3P: "HMPT", + C6H14: "hexane", + CH4O: "methanol", + C5H12O: "MTBE", + CH2Cl2: "methylene chloride", + CH5H9NO: "NMP", + CH3NO2: "nitromethane", + C5H12: "pentane", + C5H5N: "pyridine", + C7H8: "toluene", + C6H15N: "triethyl amine", + H2O: "water" +}; +var jg = Kg; +const Jg = Mi, Pn = Un, Qg = Gn, e0 = Yn, Oa = jg; +let t0 = class { + /** + * The constructor for the class ReactionDrawer. + * + * @param {Object} options An object containing reaction drawing specitic options. + * @param {Object} moleculeOptions An object containing molecule drawing specific options. + */ + constructor(e, t) { + this.defaultOptions = { + scale: t.scale > 0 ? t.scale : 1, + fontSize: t.fontSizeLarge * 0.8, + fontFamily: "Arial, Helvetica, sans-serif", + spacing: 10, + plus: { + size: 9, + thickness: 1 + }, + arrow: { + length: t.bondLength * 4, + headSize: 6, + thickness: 1, + margin: 3 + }, + weights: { + normalize: !1 + } + }, this.opts = Qg.extend(!0, this.defaultOptions, e), this.drawer = new Jg(t), this.molOpts = this.drawer.opts; + } + /** + * Draws the parsed reaction smiles data to a canvas element. + * + * @param {Object} reaction The reaction object returned by the reaction smiles parser. + * @param {(String|SVGElement)} target The id of the HTML canvas element the structure is drawn to - or the element itself. + * @param {String} themeName='dark' The name of the theme to use. Built-in themes are 'light' and 'dark'. + * @param {?Object} weights=null The weights for reactants, agents, and products. + * @param {String} textAbove='{reagents}' The text above the arrow. + * @param {String} textBelow='' The text below the arrow. + * @param {?Object} weights=null The weights for reactants, agents, and products. + * @param {Boolean} infoOnly=false Only output info on the molecule without drawing anything to the canvas. + * + * @returns {SVGElement} The svg element + */ + draw(e, t, r = "light", i = null, s = "{reagents}", a = "", n = !1) { + if (this.themeManager = new e0(this.molOpts.themes, r), this.opts.weights.normalize) { + let B = -Number.MAX_SAFE_INTEGER, x = Number.MAX_SAFE_INTEGER; + if (i.hasOwnProperty("reactants")) + for (let k = 0; k < i.reactants.length; k++) + for (let z = 0; z < i.reactants[k].length; z++) + i.reactants[k][z] < x && (x = i.reactants[k][z]), i.reactants[k][z] > B && (B = i.reactants[k][z]); + if (i.hasOwnProperty("reagents")) + for (let k = 0; k < i.reagents.length; k++) + for (let z = 0; z < i.reagents[k].length; z++) + i.reagents[k][z] < x && (x = i.reagents[k][z]), i.reagents[k][z] > B && (B = i.reagents[k][z]); + if (i.hasOwnProperty("products")) + for (let k = 0; k < i.products.length; k++) + for (let z = 0; z < i.products[k].length; z++) + i.products[k][z] < x && (x = i.products[k][z]), i.products[k][z] > B && (B = i.products[k][z]); + let L = Math.max(Math.abs(x), Math.abs(B)); + if (L === 0 && (L = 1), i.hasOwnProperty("reactants")) + for (let k = 0; k < i.reactants.length; k++) + for (let z = 0; z < i.reactants[k].length; z++) + i.reactants[k][z] /= L; + if (i.hasOwnProperty("reagents")) + for (let k = 0; k < i.reagents.length; k++) + for (let z = 0; z < i.reagents[k].length; z++) + i.reagents[k][z] /= L; + if (i.hasOwnProperty("products")) + for (let k = 0; k < i.products.length; k++) + for (let z = 0; z < i.products[k].length; z++) + i.products[k][z] /= L; + } + let h = null; + for (t === null || t === "svg" ? (h = document.createElementNS("http://www.w3.org/2000/svg", "svg"), h.setAttribute("xmlns", "http://www.w3.org/2000/svg"), h.setAttributeNS(null, "width", "500"), h.setAttributeNS(null, "height", "500")) : typeof t == "string" || t instanceof String ? h = document.getElementById(t) : h = t; h.firstChild; ) + h.removeChild(h.firstChild); + let l = [], c = 0; + for (var u = 0; u < e.reactants.length; u++) { + u > 0 && l.push({ + width: this.opts.plus.size * this.opts.scale, + height: this.opts.plus.size * this.opts.scale, + svg: this.getPlus() + }); + let B = null; + i && i.hasOwnProperty("reactants") && i.reactants.length > u && (B = i.reactants[u]); + let x = document.createElementNS("http://www.w3.org/2000/svg", "svg"); + this.drawer.draw(e.reactants[u], x, r, B, n, [], this.opts.weights.normalize); + let L = { + width: x.viewBox.baseVal.width * this.opts.scale, + height: x.viewBox.baseVal.height * this.opts.scale, + svg: x + }; + l.push(L), L.height > c && (c = L.height); + } + l.push({ + width: this.opts.arrow.length * this.opts.scale, + height: this.opts.arrow.headSize * 2 * this.opts.scale, + svg: this.getArrow() + }); + let g = ""; + for (var u = 0; u < e.reagents.length; u++) { + u > 0 && (g += ", "); + let x = this.drawer.getMolecularFormula(e.reagents[u]); + x in Oa && (x = Oa[x]), g += Pn.replaceNumbersWithSubscript(x); + } + s = s.replace("{reagents}", g); + const m = Pn.writeText( + s, + this.themeManager, + this.opts.fontSize * this.opts.scale, + this.opts.fontFamily, + this.opts.arrow.length * this.opts.scale + ); + let _ = (this.opts.arrow.length * this.opts.scale - m.width) / 2; + l.push({ + svg: m.svg, + height: m.height, + width: this.opts.arrow.length * this.opts.scale, + offsetX: -(this.opts.arrow.length * this.opts.scale + this.opts.spacing) + _, + offsetY: -(m.height / 2) - this.opts.arrow.margin, + position: "relative" + }); + const v = Pn.writeText( + a, + this.themeManager, + this.opts.fontSize * this.opts.scale, + this.opts.fontFamily, + this.opts.arrow.length * this.opts.scale + ); + _ = (this.opts.arrow.length * this.opts.scale - v.width) / 2, l.push({ + svg: v.svg, + height: v.height, + width: this.opts.arrow.length * this.opts.scale, + offsetX: -(this.opts.arrow.length * this.opts.scale + this.opts.spacing) + _, + offsetY: v.height / 2 + this.opts.arrow.margin, + position: "relative" + }); + for (var u = 0; u < e.products.length; u++) { + u > 0 && l.push({ + width: this.opts.plus.size * this.opts.scale, + height: this.opts.plus.size * this.opts.scale, + svg: this.getPlus() + }); + let x = null; + i && i.hasOwnProperty("products") && i.products.length > u && (x = i.products[u]); + let L = document.createElementNS("http://www.w3.org/2000/svg", "svg"); + this.drawer.draw(e.products[u], L, r, x, n, [], this.opts.weights.normalize); + let k = { + width: L.viewBox.baseVal.width * this.opts.scale, + height: L.viewBox.baseVal.height * this.opts.scale, + svg: L + }; + l.push(k), k.height > c && (c = k.height); + } + let N = 0; + return l.forEach((B) => { + let x = B.offsetX ?? 0, L = B.offsetY ?? 0; + B.svg.setAttributeNS(null, "x", Math.round(N + x)), B.svg.setAttributeNS(null, "y", Math.round((c - B.height) / 2 + L)), B.svg.setAttributeNS(null, "width", Math.round(B.width)), B.svg.setAttributeNS(null, "height", Math.round(B.height)), h.appendChild(B.svg), B.position !== "relative" && (N += Math.round(B.width + this.opts.spacing + x)); + }), h.setAttributeNS(null, "viewBox", `0 0 ${N} ${c}`), h.style.width = N + "px", h.style.height = c + "px", h; + } + getPlus() { + let e = this.opts.plus.size, t = this.opts.plus.thickness, r = document.createElementNS("http://www.w3.org/2000/svg", "svg"), i = document.createElementNS("http://www.w3.org/2000/svg", "rect"), s = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + return r.setAttributeNS(null, "id", "plus"), i.setAttributeNS(null, "x", 0), i.setAttributeNS(null, "y", e / 2 - t / 2), i.setAttributeNS(null, "width", e), i.setAttributeNS(null, "height", t), i.setAttributeNS(null, "fill", this.themeManager.getColor("C")), s.setAttributeNS(null, "x", e / 2 - t / 2), s.setAttributeNS(null, "y", 0), s.setAttributeNS(null, "width", t), s.setAttributeNS(null, "height", e), s.setAttributeNS(null, "fill", this.themeManager.getColor("C")), r.appendChild(i), r.appendChild(s), r.setAttributeNS(null, "viewBox", `0 0 ${e} ${e}`), r; + } + getArrowhead() { + let e = this.opts.arrow.headSize, t = document.createElementNS("http://www.w3.org/2000/svg", "marker"), r = document.createElementNS("http://www.w3.org/2000/svg", "polygon"); + return t.setAttributeNS(null, "id", "arrowhead"), t.setAttributeNS(null, "viewBox", `0 0 ${e} ${e}`), t.setAttributeNS(null, "markerUnits", "userSpaceOnUse"), t.setAttributeNS(null, "markerWidth", e), t.setAttributeNS(null, "markerHeight", e), t.setAttributeNS(null, "refX", 0), t.setAttributeNS(null, "refY", e / 2), t.setAttributeNS(null, "orient", "auto"), t.setAttributeNS(null, "fill", this.themeManager.getColor("C")), r.setAttributeNS(null, "points", `0 0, ${e} ${e / 2}, 0 ${e}`), t.appendChild(r), t; + } + getCDArrowhead() { + let e = this.opts.arrow.headSize, t = e * (7 / 4.5), r = document.createElementNS("http://www.w3.org/2000/svg", "marker"), i = document.createElementNS("http://www.w3.org/2000/svg", "path"); + return r.setAttributeNS(null, "id", "arrowhead"), r.setAttributeNS(null, "viewBox", `0 0 ${t} ${e}`), r.setAttributeNS(null, "markerUnits", "userSpaceOnUse"), r.setAttributeNS(null, "markerWidth", t * 2), r.setAttributeNS(null, "markerHeight", e * 2), r.setAttributeNS(null, "refX", 2.2), r.setAttributeNS(null, "refY", 2.2), r.setAttributeNS(null, "orient", "auto"), r.setAttributeNS(null, "fill", this.themeManager.getColor("C")), i.setAttributeNS(null, "style", "fill-rule:nonzero;"), i.setAttributeNS(null, "d", "m 0 0 l 7 2.25 l -7 2.25 c 0 0 0.735 -1.084 0.735 -2.28 c 0 -1.196 -0.735 -2.22 -0.735 -2.22 z"), r.appendChild(i), r; + } + getArrow() { + let e = this.opts.arrow.headSize, t = this.opts.arrow.length, r = document.createElementNS("http://www.w3.org/2000/svg", "svg"), i = document.createElementNS("http://www.w3.org/2000/svg", "defs"), s = document.createElementNS("http://www.w3.org/2000/svg", "line"); + return i.appendChild(this.getCDArrowhead()), r.appendChild(i), r.setAttributeNS(null, "id", "arrow"), s.setAttributeNS(null, "x1", 0), s.setAttributeNS(null, "y1", -this.opts.arrow.thickness / 2), s.setAttributeNS(null, "x2", t), s.setAttributeNS(null, "y2", -this.opts.arrow.thickness / 2), s.setAttributeNS(null, "stroke-width", this.opts.arrow.thickness), s.setAttributeNS(null, "stroke", this.themeManager.getColor("C")), s.setAttributeNS(null, "marker-end", "url(#arrowhead)"), r.appendChild(s), r.setAttributeNS(null, "viewBox", `0 ${-e / 2} ${t + e * (7 / 4.5)} ${e}`), r; + } +}; +var yl = t0; +const r0 = Zn, i0 = wl, n0 = Mi, s0 = yl, Fa = Un, a0 = Gn; +let l0 = class qn { + constructor(e = {}, t = {}) { + this.drawer = new n0(e), this.reactionDrawer = new s0(t, JSON.parse(JSON.stringify(this.drawer.opts))); + } + static apply(e = {}, t = {}, r = "data-smiles", i = "light", s = null, a = null) { + new qn(e, t).apply(r, i, s, a); + } + apply(e = "data-smiles", t = "light", r = null, i = null) { + document.querySelectorAll(`[${e}]`).forEach((a) => { + let n = a.getAttribute(e); + if (n === null) + throw Error("No SMILES provided."); + let h = t, l = null; + if (a.hasAttribute("data-smiles-theme") && (h = a.getAttribute("data-smiles-theme")), a.hasAttribute("data-smiles-weights") && (l = a.getAttribute("data-smiles-weights").split(",").map(parseFloat)), (a.hasAttribute("data-smiles-reactant-weights") || a.hasAttribute("data-smiles-reagent-weights") || a.hasAttribute("data-smiles-product-weights")) && (l = { reactants: [], reagents: [], products: [] }, a.hasAttribute("data-smiles-reactant-weights") && (l.reactants = a.getAttribute("data-smiles-reactant-weights").split(";").map((c) => c.split(",").map(parseFloat))), a.hasAttribute("data-smiles-reagent-weights") && (l.reagents = a.getAttribute("data-smiles-reagent-weights").split(";").map((c) => c.split(",").map(parseFloat))), a.hasAttribute("data-smiles-product-weights") && (l.products = a.getAttribute("data-smiles-product-weights").split(";").map((c) => c.split(",").map(parseFloat)))), a.hasAttribute("data-smiles-options") || a.hasAttribute("data-smiles-reaction-options")) { + let c = {}; + a.hasAttribute("data-smiles-options") && (c = JSON.parse(a.getAttribute("data-smiles-options").replaceAll("'", '"'))); + let u = {}; + a.hasAttribute("data-smiles-reaction-options") && (u = JSON.parse(a.getAttribute("data-smiles-reaction-options").replaceAll("'", '"'))), new qn(c, u).draw(n, a, h, r, i, l); + } else + this.draw(n, a, h, r, i, l); + }); + } + /** + * Draw the smiles to the target. + * @param {String} smiles The SMILES to be depicted. + * @param {*} target The target element. + * @param {String} theme The theme. + * @param {?CallableFunction} successCallback The function called on success. + * @param {?CallableFunction} errorCallback The function called on error. + * @param {?Number[]|Object} weights The weights for the gaussians. + */ + draw(e, t, r = "light", i = null, s = null, a = null) { + let n = []; + [e, ...n] = e.split(" "); + let h = n.join(" "), l = {}; + if (h.includes("__")) { + let u = h.substring( + h.indexOf("__") + 2, + h.lastIndexOf("__") + ); + l = JSON.parse(u.replaceAll("'", '"')); + } + let c = { + textAboveArrow: "{reagents}", + textBelowArrow: "" + }; + if (l = a0.extend(!0, c, l), e.includes(">")) + try { + this.drawReaction(e, t, r, l, a, i); + } catch (u) { + s ? s(u) : console.error(u); + } + else + try { + this.drawMolecule(e, t, r, a, i); + } catch (u) { + s ? s(u) : console.error(u); + } + } + drawMolecule(e, t, r, i, s) { + let a = r0.parse(e); + if (t === null || t === "svg") { + let n = this.drawer.draw(a, null, r, i), h = this.getDimensions(n); + n.setAttributeNS(null, "width", "" + h.w), n.setAttributeNS(null, "height", "" + h.h), s && s(n); + } else if (t === "canvas") { + let n = this.svgToCanvas(this.drawer.draw(a, null, r, i)); + s && s(n); + } else if (t === "img") { + let n = this.svgToImg(this.drawer.draw(a, null, r, i)); + s && s(n); + } else + t instanceof HTMLImageElement ? (this.svgToImg(this.drawer.draw(a, null, r, i), t), s && s(t)) : t instanceof SVGElement ? (this.drawer.draw(a, t, r, i), s && s(t)) : document.querySelectorAll(t).forEach((h) => { + let l = h.nodeName.toLowerCase(); + l === "svg" ? (this.drawer.draw(a, h, r, i), s && s(h)) : l === "canvas" ? (this.svgToCanvas(this.drawer.draw(a, null, r, i), h), s && s(h)) : l === "img" && (this.svgToImg(this.drawer.draw(a, null, r, i), h), s && s(h)); + }); + } + drawReaction(e, t, r, i, s, a) { + let n = i0.parse(e); + if (t === null || t === "svg") { + let h = this.reactionDrawer.draw(n, null, r), l = this.getDimensions(h); + h.setAttributeNS(null, "width", "" + l.w), h.setAttributeNS(null, "height", "" + l.h), a && a(h); + } else if (t === "canvas") { + let h = this.svgToCanvas(this.reactionDrawer.draw(n, null, r, s, i.textAboveArrow, i.textBelowArrow)); + a && a(h); + } else if (t === "img") { + let h = this.svgToImg(this.reactionDrawer.draw(n, null, r, s, i.textAboveArrow, i.textBelowArrow)); + a && a(h); + } else + t instanceof HTMLImageElement ? (this.svgToImg(this.reactionDrawer.draw(n, null, r, s, i.textAboveArrow, i.textBelowArrow), t), a && a(t)) : t instanceof SVGElement ? (this.reactionDrawer.draw(n, t, r, s, i.textAboveArrow, i.textBelowArrow), a && a(t)) : document.querySelectorAll(t).forEach((l) => { + let c = l.nodeName.toLowerCase(); + c === "svg" ? (this.reactionDrawer.draw(n, l, r, s, i.textAboveArrow, i.textBelowArrow), this.reactionDrawer.opts.scale <= 0 && (l.style.width = null, l.style.height = null), a && a(l)) : c === "canvas" ? (this.svgToCanvas(this.reactionDrawer.draw(n, null, r, s, i.textAboveArrow, i.textBelowArrow), l), a && a(l)) : c === "img" && (this.svgToImg(this.reactionDrawer.draw(n, null, r, s, i.textAboveArrow, i.textBelowArrow), l), a && a(l)); + }); + } + svgToCanvas(e, t = null) { + t === null && (t = document.createElement("canvas")); + let r = this.getDimensions(t, e); + return Fa.svgToCanvas(e, t, r.w, r.h), t; + } + svgToImg(e, t = null) { + t === null && (t = document.createElement("img")); + let r = this.getDimensions(t, e); + return Fa.svgToImg(e, t, r.w, r.h), t; + } + /** + * + * @param {HTMLImageElement|HTMLCanvasElement|SVGElement} element + * @param {SVGElement} svg + * @returns {{w: Number, h: Number}} The width and height. + */ + getDimensions(e, t = null) { + let r = this.drawer.opts.width, i = this.drawer.opts.height; + return this.drawer.opts.scale <= 0 ? (r === null && (r = e.width), i === null && (i = e.height), e.style.width !== "" && (r = parseInt(e.style.width)), e.style.height !== "" && (i = parseInt(e.style.height))) : t && (r = parseFloat(t.style.width), i = parseFloat(t.style.height)), { w: r, h: i }; + } +}; +var o0 = l0; +const _l = Xg, Sl = Zn, Cl = wl, h0 = Mi, f0 = yl, Al = o0, u0 = bl; +var c0 = !!(typeof window < "u" && window.document && window.document.createElement), nt = { + Version: "1.0.0" +}; +nt.Drawer = _l; +nt.Parser = Sl; +nt.SvgDrawer = h0; +nt.ReactionDrawer = f0; +nt.ReactionParser = Cl; +nt.GaussDrawer = u0; +nt.clean = function(d) { + return d.replace(/[^A-Za-z0-9@\.\+\-\?!\(\)\[\]\{\}/\\=#\$:\*]/g, ""); +}; +nt.apply = function(d, e = "canvas[data-smiles]", t = "light", r = null) { + let i = new _l(d), s = document.querySelectorAll(e); + for (var a = 0; a < s.length; a++) { + let n = s[a]; + nt.parse(n.getAttribute("data-smiles"), function(h) { + i.draw(h, n, t, !1); + }, function(h) { + r && r(h); + }); + } +}; +nt.parse = function(d, e, t) { + try { + e && e(Sl.parse(d)); + } catch (r) { + t && t(r); + } +}; +nt.parseReaction = function(d, e, t) { + try { + e && e(Cl.parse(d)); + } catch (r) { + t && t(r); + } +}; +c0 && (window.SmilesDrawer = nt, window.SmiDrawer = Al); +nt.SmiDrawer = Al; +Array.prototype.fill || Object.defineProperty(Array.prototype, "fill", { + value: function(d) { + if (this == null) + throw new TypeError("this is null or not defined"); + for (var e = Object(this), t = e.length >>> 0, r = arguments[1], i = r >> 0, s = i < 0 ? Math.max(t + i, 0) : Math.min(i, t), a = arguments[2], n = a === void 0 ? t : a >> 0, h = n < 0 ? Math.max(t + n, 0) : Math.min(n, t); s < h; ) + e[s] = d, s++; + return e; + } +}); +var g0 = nt; +const za = /* @__PURE__ */ tg(g0), { + SvelteComponent: d0, + append: p0, + attr: Ti, + binding_callbacks: v0, + detach: Kn, + element: Nl, + empty: m0, + init: b0, + insert: jn, + noop: Vn, + safe_not_equal: w0, + svg_element: y0 +} = window.__gradio__svelte__internal, { afterUpdate: _0 } = window.__gradio__svelte__internal; +function S0(d) { + let e; + return { + c() { + e = Nl("div"), e.textContent = "No molecule to display", Ti(e, "class", "text-center my-10 py-10 text-gray-600"); + }, + m(t, r) { + jn(t, e, r); + }, + p: Vn, + d(t) { + t && Kn(e); + } + }; +} +function C0(d) { + let e, t; + return { + c() { + e = Nl("div"), t = y0("svg"), Ti( + t, + "data-smiles", + /*smiles*/ + d[0] + ), Ti(t, "class", "svelte-zjukdr"); + }, + m(r, i) { + jn(r, e, i), p0(e, t), d[2](t); + }, + p(r, i) { + i & /*smiles*/ + 1 && Ti( + t, + "data-smiles", + /*smiles*/ + r[0] + ); + }, + d(r) { + r && Kn(e), d[2](null); + } + }; +} +function A0(d) { + let e; + function t(s, a) { + return ( + /*smiles*/ + s[0].length > 0 ? C0 : S0 + ); + } + let r = t(d), i = r(d); + return { + c() { + i.c(), e = m0(); + }, + m(s, a) { + i.m(s, a), jn(s, e, a); + }, + p(s, [a]) { + r === (r = t(s)) && i ? i.p(s, a) : (i.d(1), i = r(s), i && (i.c(), i.m(e.parentNode, e))); + }, + i: Vn, + o: Vn, + d(s) { + s && Kn(e), i.d(s); + } + }; +} +function N0(d, e, t) { + let { smiles: r = "" } = e; + const i = { width: 300, height: 200 }; + let s = new za.SvgDrawer(i), a; + _0(() => { + za.parse(r, function(h) { + s.draw(h, a, "light"); + }); + }); + function n(h) { + v0[h ? "unshift" : "push"](() => { + a = h, t(1, a); + }); + } + return d.$$set = (h) => { + "smiles" in h && t(0, r = h.smiles); + }, [r, a, n]; +} +class k0 extends d0 { + constructor(e) { + super(), b0(this, e, N0, A0, w0, { smiles: 0 }); + } +} +const { + SvelteComponent: R0, + attr: x0, + create_component: T0, + destroy_component: E0, + detach: L0, + element: M0, + init: B0, + insert: D0, + mount_component: P0, + safe_not_equal: $0, + set_style: Ha, + toggle_class: Wa, + transition_in: I0, + transition_out: O0 +} = window.__gradio__svelte__internal, { createEventDispatcher: F0 } = window.__gradio__svelte__internal; +function z0(d) { + let e, t, r; + return t = new tl({ + props: { + Icon: rl, + label: "Finish drawing", + size: "large" + } + }), t.$on( + "click", + /*click_handler*/ + d[2] + ), { + c() { + e = M0("div"), T0(t.$$.fragment), x0(e, "class", "svelte-181q4hi"), Wa(e, "not-absolute", !/*absolute*/ + d[0]), Ha( + e, + "position", + /*absolute*/ + d[0] ? "absolute" : "static" + ); + }, + m(i, s) { + D0(i, e, s), P0(t, e, null), r = !0; + }, + p(i, [s]) { + (!r || s & /*absolute*/ + 1) && Wa(e, "not-absolute", !/*absolute*/ + i[0]), s & /*absolute*/ + 1 && Ha( + e, + "position", + /*absolute*/ + i[0] ? "absolute" : "static" + ); + }, + i(i) { + r || (I0(t.$$.fragment, i), r = !0); + }, + o(i) { + O0(t.$$.fragment, i), r = !1; + }, + d(i) { + i && L0(e), E0(t); + } + }; +} +function H0(d, e, t) { + let { absolute: r = !0 } = e; + const i = F0(), s = (a) => { + i("clear"), a.stopPropagation(); + }; + return d.$$set = (a) => { + "absolute" in a && t(0, r = a.absolute); + }, [r, i, s]; +} +class W0 extends R0 { + constructor(e) { + super(), B0(this, e, H0, z0, $0, { absolute: 0 }); + } +} +const { + SvelteComponent: q0, + append: V0, + attr: $n, + create_component: X0, + destroy_component: Y0, + detach: qa, + element: Va, + init: G0, + insert: Xa, + mount_component: U0, + noop: Z0, + safe_not_equal: K0, + space: j0, + transition_in: J0, + transition_out: Q0 +} = window.__gradio__svelte__internal, { createEventDispatcher: ed } = window.__gradio__svelte__internal; +function td(d) { + let e, t, r, i, s; + return e = new W0({}), e.$on( + "clear", + /*getsmiles*/ + d[0] + ), { + c() { + X0(e.$$.fragment), t = j0(), r = Va("div"), i = Va("iframe"), $n( + i, + "srcdoc", + /*ketcherDoc*/ + d[1] + ), $n(i, "class", "svelte-rryiqv"), $n(r, "class", "composerWrapper"); + }, + m(a, n) { + U0(e, a, n), Xa(a, t, n), Xa(a, r, n), V0(r, i), s = !0; + }, + p: Z0, + i(a) { + s || (J0(e.$$.fragment, a), s = !0); + }, + o(a) { + Q0(e.$$.fragment, a), s = !1; + }, + d(a) { + a && (qa(t), qa(r)), Y0(e, a); + } + }; +} +function rd(d) { + const e = ed(); + function t() { + document.querySelector("iframe").contentWindow.ketcher.getSmiles().then((a) => { + e("moleculesketched", { smiles: a }); + }); + } + return [t, ` + + + +
+

+ loading SMILES editor +

+ + + + + + + + + + + +
+
+