diff --git "a/src/backend/gradio_molgallery3d/templates/component/index.js" "b/src/backend/gradio_molgallery3d/templates/component/index.js"
new file mode 100644--- /dev/null
+++ "b/src/backend/gradio_molgallery3d/templates/component/index.js"
@@ -0,0 +1,26119 @@
+const Block_svelte_svelte_type_style_lang = "", {
+ SvelteComponent: SvelteComponent$7,
+ assign: assign$1,
+ create_slot: create_slot$2,
+ detach: detach$7,
+ element: element$5,
+ get_all_dirty_from_scope: get_all_dirty_from_scope$2,
+ get_slot_changes: get_slot_changes$2,
+ get_spread_update: get_spread_update$1,
+ init: init$7,
+ insert: insert$7,
+ safe_not_equal: safe_not_equal$8,
+ set_dynamic_element_data,
+ set_style: set_style$3,
+ toggle_class: toggle_class$5,
+ transition_in: transition_in$5,
+ transition_out: transition_out$5,
+ update_slot_base: update_slot_base$2
+} = window.__gradio__svelte__internal;
+function create_dynamic_element(P) {
+ let _, s, v;
+ const M = (
+ /*#slots*/
+ P[17].default
+ ), E = create_slot$2(
+ M,
+ P,
+ /*$$scope*/
+ P[16],
+ null
+ );
+ let A = [
+ { "data-testid": (
+ /*test_id*/
+ P[7]
+ ) },
+ { id: (
+ /*elem_id*/
+ P[2]
+ ) },
+ {
+ class: s = "block " + /*elem_classes*/
+ P[3].join(" ") + " svelte-1t38q2d"
+ }
+ ], h = {};
+ for (let g = 0; g < A.length; g += 1)
+ h = assign$1(h, A[g]);
+ return {
+ c() {
+ _ = element$5(
+ /*tag*/
+ P[14]
+ ), E && E.c(), set_dynamic_element_data(
+ /*tag*/
+ P[14]
+ )(_, h), toggle_class$5(
+ _,
+ "hidden",
+ /*visible*/
+ P[10] === !1
+ ), toggle_class$5(
+ _,
+ "padded",
+ /*padding*/
+ P[6]
+ ), toggle_class$5(
+ _,
+ "border_focus",
+ /*border_mode*/
+ P[5] === "focus"
+ ), toggle_class$5(_, "hide-container", !/*explicit_call*/
+ P[8] && !/*container*/
+ P[9]), set_style$3(_, "height", typeof /*height*/
+ P[0] == "number" ? (
+ /*height*/
+ P[0] + "px"
+ ) : void 0), set_style$3(_, "width", typeof /*width*/
+ P[1] == "number" ? `calc(min(${/*width*/
+ P[1]}px, 100%))` : void 0), set_style$3(
+ _,
+ "border-style",
+ /*variant*/
+ P[4]
+ ), set_style$3(
+ _,
+ "overflow",
+ /*allow_overflow*/
+ P[11] ? "visible" : "hidden"
+ ), set_style$3(
+ _,
+ "flex-grow",
+ /*scale*/
+ P[12]
+ ), set_style$3(_, "min-width", `calc(min(${/*min_width*/
+ P[13]}px, 100%))`), set_style$3(_, "border-width", "var(--block-border-width)");
+ },
+ m(g, C) {
+ insert$7(g, _, C), E && E.m(_, null), v = !0;
+ },
+ p(g, C) {
+ E && E.p && (!v || C & /*$$scope*/
+ 65536) && update_slot_base$2(
+ E,
+ M,
+ g,
+ /*$$scope*/
+ g[16],
+ v ? get_slot_changes$2(
+ M,
+ /*$$scope*/
+ g[16],
+ C,
+ null
+ ) : get_all_dirty_from_scope$2(
+ /*$$scope*/
+ g[16]
+ ),
+ null
+ ), set_dynamic_element_data(
+ /*tag*/
+ g[14]
+ )(_, h = get_spread_update$1(A, [
+ (!v || C & /*test_id*/
+ 128) && { "data-testid": (
+ /*test_id*/
+ g[7]
+ ) },
+ (!v || C & /*elem_id*/
+ 4) && { id: (
+ /*elem_id*/
+ g[2]
+ ) },
+ (!v || C & /*elem_classes*/
+ 8 && s !== (s = "block " + /*elem_classes*/
+ g[3].join(" ") + " svelte-1t38q2d")) && { class: s }
+ ])), toggle_class$5(
+ _,
+ "hidden",
+ /*visible*/
+ g[10] === !1
+ ), toggle_class$5(
+ _,
+ "padded",
+ /*padding*/
+ g[6]
+ ), toggle_class$5(
+ _,
+ "border_focus",
+ /*border_mode*/
+ g[5] === "focus"
+ ), toggle_class$5(_, "hide-container", !/*explicit_call*/
+ g[8] && !/*container*/
+ g[9]), C & /*height*/
+ 1 && set_style$3(_, "height", typeof /*height*/
+ g[0] == "number" ? (
+ /*height*/
+ g[0] + "px"
+ ) : void 0), C & /*width*/
+ 2 && set_style$3(_, "width", typeof /*width*/
+ g[1] == "number" ? `calc(min(${/*width*/
+ g[1]}px, 100%))` : void 0), C & /*variant*/
+ 16 && set_style$3(
+ _,
+ "border-style",
+ /*variant*/
+ g[4]
+ ), C & /*allow_overflow*/
+ 2048 && set_style$3(
+ _,
+ "overflow",
+ /*allow_overflow*/
+ g[11] ? "visible" : "hidden"
+ ), C & /*scale*/
+ 4096 && set_style$3(
+ _,
+ "flex-grow",
+ /*scale*/
+ g[12]
+ ), C & /*min_width*/
+ 8192 && set_style$3(_, "min-width", `calc(min(${/*min_width*/
+ g[13]}px, 100%))`);
+ },
+ i(g) {
+ v || (transition_in$5(E, g), v = !0);
+ },
+ o(g) {
+ transition_out$5(E, g), v = !1;
+ },
+ d(g) {
+ g && detach$7(_), E && E.d(g);
+ }
+ };
+}
+function create_fragment$7(P) {
+ let _, s = (
+ /*tag*/
+ P[14] && create_dynamic_element(P)
+ );
+ return {
+ c() {
+ s && s.c();
+ },
+ m(v, M) {
+ s && s.m(v, M), _ = !0;
+ },
+ p(v, [M]) {
+ /*tag*/
+ v[14] && s.p(v, M);
+ },
+ i(v) {
+ _ || (transition_in$5(s, v), _ = !0);
+ },
+ o(v) {
+ transition_out$5(s, v), _ = !1;
+ },
+ d(v) {
+ s && s.d(v);
+ }
+ };
+}
+function instance$6(P, _, s) {
+ let { $$slots: v = {}, $$scope: M } = _, { height: E = void 0 } = _, { width: A = void 0 } = _, { elem_id: h = "" } = _, { elem_classes: g = [] } = _, { variant: C = "solid" } = _, { border_mode: c = "base" } = _, { padding: S = !0 } = _, { type: y = "normal" } = _, { test_id: b = void 0 } = _, { explicit_call: w = !1 } = _, { container: t = !0 } = _, { visible: r = !0 } = _, { allow_overflow: u = !0 } = _, { scale: o = null } = _, { min_width: l = 0 } = _, e = y === "fieldset" ? "fieldset" : "div";
+ return P.$$set = (n) => {
+ "height" in n && s(0, E = n.height), "width" in n && s(1, A = n.width), "elem_id" in n && s(2, h = n.elem_id), "elem_classes" in n && s(3, g = n.elem_classes), "variant" in n && s(4, C = n.variant), "border_mode" in n && s(5, c = n.border_mode), "padding" in n && s(6, S = n.padding), "type" in n && s(15, y = n.type), "test_id" in n && s(7, b = n.test_id), "explicit_call" in n && s(8, w = n.explicit_call), "container" in n && s(9, t = n.container), "visible" in n && s(10, r = n.visible), "allow_overflow" in n && s(11, u = n.allow_overflow), "scale" in n && s(12, o = n.scale), "min_width" in n && s(13, l = n.min_width), "$$scope" in n && s(16, M = n.$$scope);
+ }, [
+ E,
+ A,
+ h,
+ g,
+ C,
+ c,
+ S,
+ b,
+ w,
+ t,
+ r,
+ u,
+ o,
+ l,
+ e,
+ y,
+ M,
+ v
+ ];
+}
+class Block extends SvelteComponent$7 {
+ constructor(_) {
+ super(), init$7(this, _, instance$6, create_fragment$7, safe_not_equal$8, {
+ height: 0,
+ width: 1,
+ elem_id: 2,
+ elem_classes: 3,
+ variant: 4,
+ border_mode: 5,
+ padding: 6,
+ type: 15,
+ test_id: 7,
+ explicit_call: 8,
+ container: 9,
+ visible: 10,
+ allow_overflow: 11,
+ scale: 12,
+ min_width: 13
+ });
+ }
+}
+const Info_svelte_svelte_type_style_lang = "", BlockTitle_svelte_svelte_type_style_lang = "", BlockLabel_svelte_svelte_type_style_lang = "", {
+ SvelteComponent: SvelteComponent$6,
+ append: append$5,
+ attr: attr$5,
+ create_component: create_component$3,
+ destroy_component: destroy_component$3,
+ detach: detach$6,
+ element: element$4,
+ init: init$6,
+ insert: insert$6,
+ mount_component: mount_component$3,
+ safe_not_equal: safe_not_equal$7,
+ set_data: set_data$2,
+ space: space$3,
+ text: text$2,
+ toggle_class: toggle_class$4,
+ transition_in: transition_in$4,
+ transition_out: transition_out$4
+} = window.__gradio__svelte__internal;
+function create_fragment$6(P) {
+ let _, s, v, M, E, A;
+ return v = new /*Icon*/
+ P[1]({}), {
+ c() {
+ _ = element$4("label"), s = element$4("span"), create_component$3(v.$$.fragment), M = space$3(), E = text$2(
+ /*label*/
+ P[0]
+ ), attr$5(s, "class", "svelte-9gxdi0"), attr$5(_, "for", ""), attr$5(_, "data-testid", "block-label"), attr$5(_, "class", "svelte-9gxdi0"), toggle_class$4(_, "hide", !/*show_label*/
+ P[2]), toggle_class$4(_, "sr-only", !/*show_label*/
+ P[2]), toggle_class$4(
+ _,
+ "float",
+ /*float*/
+ P[4]
+ ), toggle_class$4(
+ _,
+ "hide-label",
+ /*disable*/
+ P[3]
+ );
+ },
+ m(h, g) {
+ insert$6(h, _, g), append$5(_, s), mount_component$3(v, s, null), append$5(_, M), append$5(_, E), A = !0;
+ },
+ p(h, [g]) {
+ (!A || g & /*label*/
+ 1) && set_data$2(
+ E,
+ /*label*/
+ h[0]
+ ), (!A || g & /*show_label*/
+ 4) && toggle_class$4(_, "hide", !/*show_label*/
+ h[2]), (!A || g & /*show_label*/
+ 4) && toggle_class$4(_, "sr-only", !/*show_label*/
+ h[2]), (!A || g & /*float*/
+ 16) && toggle_class$4(
+ _,
+ "float",
+ /*float*/
+ h[4]
+ ), (!A || g & /*disable*/
+ 8) && toggle_class$4(
+ _,
+ "hide-label",
+ /*disable*/
+ h[3]
+ );
+ },
+ i(h) {
+ A || (transition_in$4(v.$$.fragment, h), A = !0);
+ },
+ o(h) {
+ transition_out$4(v.$$.fragment, h), A = !1;
+ },
+ d(h) {
+ h && detach$6(_), destroy_component$3(v);
+ }
+ };
+}
+function instance$5(P, _, s) {
+ let { label: v = null } = _, { Icon: M } = _, { show_label: E = !0 } = _, { disable: A = !1 } = _, { float: h = !0 } = _;
+ return P.$$set = (g) => {
+ "label" in g && s(0, v = g.label), "Icon" in g && s(1, M = g.Icon), "show_label" in g && s(2, E = g.show_label), "disable" in g && s(3, A = g.disable), "float" in g && s(4, h = g.float);
+ }, [v, M, E, A, h];
+}
+class BlockLabel extends SvelteComponent$6 {
+ constructor(_) {
+ super(), init$6(this, _, instance$5, create_fragment$6, safe_not_equal$7, {
+ label: 0,
+ Icon: 1,
+ show_label: 2,
+ disable: 3,
+ float: 4
+ });
+ }
+}
+const IconButton_svelte_svelte_type_style_lang = "", Empty_svelte_svelte_type_style_lang = "", {
+ SvelteComponent: SvelteComponent$5,
+ append: append$4,
+ attr: attr$4,
+ binding_callbacks: binding_callbacks$1,
+ create_slot: create_slot$1,
+ detach: detach$5,
+ element: element$3,
+ get_all_dirty_from_scope: get_all_dirty_from_scope$1,
+ get_slot_changes: get_slot_changes$1,
+ init: init$5,
+ insert: insert$5,
+ safe_not_equal: safe_not_equal$6,
+ toggle_class: toggle_class$3,
+ transition_in: transition_in$3,
+ transition_out: transition_out$3,
+ update_slot_base: update_slot_base$1
+} = window.__gradio__svelte__internal;
+function create_fragment$5(P) {
+ let _, s, v;
+ const M = (
+ /*#slots*/
+ P[5].default
+ ), E = create_slot$1(
+ M,
+ P,
+ /*$$scope*/
+ P[4],
+ null
+ );
+ return {
+ c() {
+ _ = element$3("div"), s = element$3("div"), E && E.c(), attr$4(s, "class", "icon svelte-3w3rth"), attr$4(_, "class", "empty svelte-3w3rth"), attr$4(_, "aria-label", "Empty value"), toggle_class$3(
+ _,
+ "small",
+ /*size*/
+ P[0] === "small"
+ ), toggle_class$3(
+ _,
+ "large",
+ /*size*/
+ P[0] === "large"
+ ), toggle_class$3(
+ _,
+ "unpadded_box",
+ /*unpadded_box*/
+ P[1]
+ ), toggle_class$3(
+ _,
+ "small_parent",
+ /*parent_height*/
+ P[3]
+ );
+ },
+ m(A, h) {
+ insert$5(A, _, h), append$4(_, s), E && E.m(s, null), P[6](_), v = !0;
+ },
+ p(A, [h]) {
+ E && E.p && (!v || h & /*$$scope*/
+ 16) && update_slot_base$1(
+ E,
+ M,
+ A,
+ /*$$scope*/
+ A[4],
+ v ? get_slot_changes$1(
+ M,
+ /*$$scope*/
+ A[4],
+ h,
+ null
+ ) : get_all_dirty_from_scope$1(
+ /*$$scope*/
+ A[4]
+ ),
+ null
+ ), (!v || h & /*size*/
+ 1) && toggle_class$3(
+ _,
+ "small",
+ /*size*/
+ A[0] === "small"
+ ), (!v || h & /*size*/
+ 1) && toggle_class$3(
+ _,
+ "large",
+ /*size*/
+ A[0] === "large"
+ ), (!v || h & /*unpadded_box*/
+ 2) && toggle_class$3(
+ _,
+ "unpadded_box",
+ /*unpadded_box*/
+ A[1]
+ ), (!v || h & /*parent_height*/
+ 8) && toggle_class$3(
+ _,
+ "small_parent",
+ /*parent_height*/
+ A[3]
+ );
+ },
+ i(A) {
+ v || (transition_in$3(E, A), v = !0);
+ },
+ o(A) {
+ transition_out$3(E, A), v = !1;
+ },
+ d(A) {
+ A && detach$5(_), E && E.d(A), P[6](null);
+ }
+ };
+}
+function _optionalChain(P) {
+ let _, s = P[0], v = 1;
+ for (; v < P.length; ) {
+ const M = P[v], E = P[v + 1];
+ if (v += 2, (M === "optionalAccess" || M === "optionalCall") && s == null)
+ return;
+ M === "access" || M === "optionalAccess" ? (_ = s, s = E(s)) : (M === "call" || M === "optionalCall") && (s = E((...A) => s.call(_, ...A)), _ = void 0);
+ }
+ return s;
+}
+function instance$4(P, _, s) {
+ let v, { $$slots: M = {}, $$scope: E } = _, { size: A = "small" } = _, { unpadded_box: h = !1 } = _, g;
+ function C(S) {
+ if (!S)
+ return !1;
+ const { height: y } = S.getBoundingClientRect(), { height: b } = _optionalChain([
+ S,
+ "access",
+ (w) => w.parentElement,
+ "optionalAccess",
+ (w) => w.getBoundingClientRect,
+ "call",
+ (w) => w()
+ ]) || { height: y };
+ return y > b + 2;
+ }
+ function c(S) {
+ binding_callbacks$1[S ? "unshift" : "push"](() => {
+ g = S, s(2, g);
+ });
+ }
+ return P.$$set = (S) => {
+ "size" in S && s(0, A = S.size), "unpadded_box" in S && s(1, h = S.unpadded_box), "$$scope" in S && s(4, E = S.$$scope);
+ }, P.$$.update = () => {
+ P.$$.dirty & /*el*/
+ 4 && s(3, v = C(g));
+ }, [A, h, g, v, E, M, c];
+}
+class Empty extends SvelteComponent$5 {
+ constructor(_) {
+ super(), init$5(this, _, instance$4, create_fragment$5, safe_not_equal$6, { size: 0, unpadded_box: 1 });
+ }
+}
+const DropdownArrow_svelte_svelte_type_style_lang = "", {
+ SvelteComponent: SvelteComponent$4,
+ append: append$3,
+ attr: attr$3,
+ detach: detach$4,
+ init: init$4,
+ insert: insert$4,
+ noop: noop$4,
+ safe_not_equal: safe_not_equal$5,
+ svg_element: svg_element$1
+} = window.__gradio__svelte__internal;
+function create_fragment$4(P) {
+ let _, s, v, M;
+ return {
+ c() {
+ _ = svg_element$1("svg"), s = svg_element$1("rect"), v = svg_element$1("circle"), M = svg_element$1("polyline"), attr$3(s, "x", "3"), attr$3(s, "y", "3"), attr$3(s, "width", "18"), attr$3(s, "height", "18"), attr$3(s, "rx", "2"), attr$3(s, "ry", "2"), attr$3(v, "cx", "8.5"), attr$3(v, "cy", "8.5"), attr$3(v, "r", "1.5"), attr$3(M, "points", "21 15 16 10 5 21"), attr$3(_, "xmlns", "http://www.w3.org/2000/svg"), attr$3(_, "width", "100%"), attr$3(_, "height", "100%"), attr$3(_, "viewBox", "0 0 24 24"), attr$3(_, "fill", "none"), attr$3(_, "stroke", "currentColor"), attr$3(_, "stroke-width", "1.5"), attr$3(_, "stroke-linecap", "round"), attr$3(_, "stroke-linejoin", "round"), attr$3(_, "class", "feather feather-image");
+ },
+ m(E, A) {
+ insert$4(E, _, A), append$3(_, s), append$3(_, v), append$3(_, M);
+ },
+ p: noop$4,
+ i: noop$4,
+ o: noop$4,
+ d(E) {
+ E && detach$4(_);
+ }
+ };
+}
+class Image extends SvelteComponent$4 {
+ constructor(_) {
+ super(), init$4(this, _, null, create_fragment$4, safe_not_equal$5, {});
+ }
+}
+const color_values = [
+ { 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 }
+], tw_colors = {
+ 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"
+ }
+};
+color_values.reduce(
+ (P, { color: _, primary: s, secondary: v }) => ({
+ ...P,
+ [_]: {
+ primary: tw_colors[_][s],
+ secondary: tw_colors[_][v]
+ }
+ }),
+ {}
+);
+const UploadText_svelte_svelte_type_style_lang = "", Toolbar_svelte_svelte_type_style_lang = "", SelectSource_svelte_svelte_type_style_lang = "";
+var commonjsGlobal = typeof globalThis < "u" ? globalThis : typeof window < "u" ? window : typeof global < "u" ? global : typeof self < "u" ? self : {};
+function getDefaultExportFromCjs(P) {
+ return P && P.__esModule && Object.prototype.hasOwnProperty.call(P, "default") ? P.default : P;
+}
+var _3Dmol = { exports: {} };
+/*!
+ * 3dmol v2.0.6
+ * JavaScript/TypeScript molecular visualization library
+ * Author: David Koes and contributors
+ */
+(function(module, exports) {
+ (function(_, s) {
+ module.exports = s();
+ })(commonjsGlobal, () => (
+ /******/
+ (() => {
+ var __webpack_modules__ = {
+ /***/
+ "./node_modules/iobuffer/lib-esm/IOBuffer.js": (
+ /*!***************************************************!*\
+ !*** ./node_modules/iobuffer/lib-esm/IOBuffer.js ***!
+ \***************************************************/
+ /***/
+ (P, _, s) => {
+ s.r(_), s.d(_, {
+ /* harmony export */
+ IOBuffer: () => (
+ /* binding */
+ h
+ )
+ /* harmony export */
+ });
+ var v = s(
+ /*! ./text */
+ "./node_modules/iobuffer/lib-esm/text.browser.js"
+ );
+ const M = 1024 * 8, E = (() => {
+ const g = new Uint8Array(4), C = new Uint32Array(g.buffer);
+ return !((C[0] = 1) & g[0]);
+ })(), A = {
+ int8: globalThis.Int8Array,
+ uint8: globalThis.Uint8Array,
+ int16: globalThis.Int16Array,
+ uint16: globalThis.Uint16Array,
+ int32: globalThis.Int32Array,
+ uint32: globalThis.Uint32Array,
+ uint64: globalThis.BigUint64Array,
+ int64: globalThis.BigInt64Array,
+ float32: globalThis.Float32Array,
+ float64: globalThis.Float64Array
+ };
+ class h {
+ /**
+ * @param data - The data to construct the IOBuffer with.
+ * If data is a number, it will be the new buffer's length
+ * If data is `undefined`, the buffer will be initialized with a default length of 8Kb
+ * If data is an ArrayBuffer, SharedArrayBuffer, an ArrayBufferView (Typed Array), an IOBuffer instance,
+ * or a Node.js Buffer, a view will be created over the underlying ArrayBuffer.
+ * @param options
+ */
+ constructor(C = M, c = {}) {
+ let S = !1;
+ typeof C == "number" ? C = new ArrayBuffer(C) : (S = !0, this.lastWrittenByte = C.byteLength);
+ const y = c.offset ? c.offset >>> 0 : 0, b = C.byteLength - y;
+ let w = y;
+ (ArrayBuffer.isView(C) || C instanceof h) && (C.byteLength !== C.buffer.byteLength && (w = C.byteOffset + y), C = C.buffer), S ? this.lastWrittenByte = b : this.lastWrittenByte = 0, this.buffer = C, this.length = b, this.byteLength = b, this.byteOffset = w, this.offset = 0, this.littleEndian = !0, this._data = new DataView(this.buffer, w, b), this._mark = 0, this._marks = [];
+ }
+ /**
+ * Checks if the memory allocated to the buffer is sufficient to store more
+ * bytes after the offset.
+ * @param byteLength - The needed memory in bytes.
+ * @returns `true` if there is sufficient space and `false` otherwise.
+ */
+ available(C = 1) {
+ return this.offset + C <= this.length;
+ }
+ /**
+ * Check if little-endian mode is used for reading and writing multi-byte
+ * values.
+ * @returns `true` if little-endian mode is used, `false` otherwise.
+ */
+ isLittleEndian() {
+ return this.littleEndian;
+ }
+ /**
+ * Set little-endian mode for reading and writing multi-byte values.
+ */
+ setLittleEndian() {
+ return this.littleEndian = !0, this;
+ }
+ /**
+ * Check if big-endian mode is used for reading and writing multi-byte values.
+ * @returns `true` if big-endian mode is used, `false` otherwise.
+ */
+ isBigEndian() {
+ return !this.littleEndian;
+ }
+ /**
+ * Switches to big-endian mode for reading and writing multi-byte values.
+ */
+ setBigEndian() {
+ return this.littleEndian = !1, this;
+ }
+ /**
+ * Move the pointer n bytes forward.
+ * @param n - Number of bytes to skip.
+ */
+ skip(C = 1) {
+ return this.offset += C, this;
+ }
+ /**
+ * Move the pointer n bytes backward.
+ * @param n - Number of bytes to move back.
+ */
+ back(C = 1) {
+ return this.offset -= C, this;
+ }
+ /**
+ * Move the pointer to the given offset.
+ * @param offset
+ */
+ seek(C) {
+ return this.offset = C, this;
+ }
+ /**
+ * Store the current pointer offset.
+ * @see {@link IOBuffer#reset}
+ */
+ mark() {
+ return this._mark = this.offset, this;
+ }
+ /**
+ * Move the pointer back to the last pointer offset set by mark.
+ * @see {@link IOBuffer#mark}
+ */
+ reset() {
+ return this.offset = this._mark, this;
+ }
+ /**
+ * Push the current pointer offset to the mark stack.
+ * @see {@link IOBuffer#popMark}
+ */
+ pushMark() {
+ return this._marks.push(this.offset), this;
+ }
+ /**
+ * Pop the last pointer offset from the mark stack, and set the current
+ * pointer offset to the popped value.
+ * @see {@link IOBuffer#pushMark}
+ */
+ popMark() {
+ const C = this._marks.pop();
+ if (C === void 0)
+ throw new Error("Mark stack empty");
+ return this.seek(C), this;
+ }
+ /**
+ * Move the pointer offset back to 0.
+ */
+ rewind() {
+ return this.offset = 0, this;
+ }
+ /**
+ * Make sure the buffer has sufficient memory to write a given byteLength at
+ * the current pointer offset.
+ * If the buffer's memory is insufficient, this method will create a new
+ * buffer (a copy) with a length that is twice (byteLength + current offset).
+ * @param byteLength
+ */
+ ensureAvailable(C = 1) {
+ if (!this.available(C)) {
+ const S = (this.offset + C) * 2, y = new Uint8Array(S);
+ y.set(new Uint8Array(this.buffer)), this.buffer = y.buffer, this.length = this.byteLength = S, this._data = new DataView(this.buffer);
+ }
+ return this;
+ }
+ /**
+ * Read a byte and return false if the byte's value is 0, or true otherwise.
+ * Moves pointer forward by one byte.
+ */
+ readBoolean() {
+ return this.readUint8() !== 0;
+ }
+ /**
+ * Read a signed 8-bit integer and move pointer forward by 1 byte.
+ */
+ readInt8() {
+ return this._data.getInt8(this.offset++);
+ }
+ /**
+ * Read an unsigned 8-bit integer and move pointer forward by 1 byte.
+ */
+ readUint8() {
+ return this._data.getUint8(this.offset++);
+ }
+ /**
+ * Alias for {@link IOBuffer#readUint8}.
+ */
+ readByte() {
+ return this.readUint8();
+ }
+ /**
+ * Read `n` bytes and move pointer forward by `n` bytes.
+ */
+ readBytes(C = 1) {
+ return this.readArray(C, "uint8");
+ }
+ /**
+ * Creates an array of corresponding to the type `type` and size `size`.
+ * For example type `uint8` will create a `Uint8Array`.
+ * @param size - size of the resulting array
+ * @param type - number type of elements to read
+ */
+ readArray(C, c) {
+ const S = A[c].BYTES_PER_ELEMENT * C, y = this.byteOffset + this.offset, b = this.buffer.slice(y, y + S);
+ if (this.littleEndian === E && c !== "uint8" && c !== "int8") {
+ const t = new Uint8Array(this.buffer.slice(y, y + S));
+ t.reverse();
+ const r = new A[c](t.buffer);
+ return this.offset += S, r.reverse(), r;
+ }
+ const w = new A[c](b);
+ return this.offset += S, w;
+ }
+ /**
+ * Read a 16-bit signed integer and move pointer forward by 2 bytes.
+ */
+ readInt16() {
+ const C = this._data.getInt16(this.offset, this.littleEndian);
+ return this.offset += 2, C;
+ }
+ /**
+ * Read a 16-bit unsigned integer and move pointer forward by 2 bytes.
+ */
+ readUint16() {
+ const C = this._data.getUint16(this.offset, this.littleEndian);
+ return this.offset += 2, C;
+ }
+ /**
+ * Read a 32-bit signed integer and move pointer forward by 4 bytes.
+ */
+ readInt32() {
+ const C = this._data.getInt32(this.offset, this.littleEndian);
+ return this.offset += 4, C;
+ }
+ /**
+ * Read a 32-bit unsigned integer and move pointer forward by 4 bytes.
+ */
+ readUint32() {
+ const C = this._data.getUint32(this.offset, this.littleEndian);
+ return this.offset += 4, C;
+ }
+ /**
+ * Read a 32-bit floating number and move pointer forward by 4 bytes.
+ */
+ readFloat32() {
+ const C = this._data.getFloat32(this.offset, this.littleEndian);
+ return this.offset += 4, C;
+ }
+ /**
+ * Read a 64-bit floating number and move pointer forward by 8 bytes.
+ */
+ readFloat64() {
+ const C = this._data.getFloat64(this.offset, this.littleEndian);
+ return this.offset += 8, C;
+ }
+ /**
+ * Read a 64-bit signed integer number and move pointer forward by 8 bytes.
+ */
+ readBigInt64() {
+ const C = this._data.getBigInt64(this.offset, this.littleEndian);
+ return this.offset += 8, C;
+ }
+ /**
+ * Read a 64-bit unsigned integer number and move pointer forward by 8 bytes.
+ */
+ readBigUint64() {
+ const C = this._data.getBigUint64(this.offset, this.littleEndian);
+ return this.offset += 8, C;
+ }
+ /**
+ * Read a 1-byte ASCII character and move pointer forward by 1 byte.
+ */
+ readChar() {
+ return String.fromCharCode(this.readInt8());
+ }
+ /**
+ * Read `n` 1-byte ASCII characters and move pointer forward by `n` bytes.
+ */
+ readChars(C = 1) {
+ let c = "";
+ for (let S = 0; S < C; S++)
+ c += this.readChar();
+ return c;
+ }
+ /**
+ * Read the next `n` bytes, return a UTF-8 decoded string and move pointer
+ * forward by `n` bytes.
+ */
+ readUtf8(C = 1) {
+ return (0, v.decode)(this.readBytes(C));
+ }
+ /**
+ * Read the next `n` bytes, return a string decoded with `encoding` and move pointer
+ * forward by `n` bytes.
+ * If no encoding is passed, the function is equivalent to @see {@link IOBuffer#readUtf8}
+ */
+ decodeText(C = 1, c = "utf-8") {
+ return (0, v.decode)(this.readBytes(C), c);
+ }
+ /**
+ * Write 0xff if the passed value is truthy, 0x00 otherwise and move pointer
+ * forward by 1 byte.
+ */
+ writeBoolean(C) {
+ return this.writeUint8(C ? 255 : 0), this;
+ }
+ /**
+ * Write `value` as an 8-bit signed integer and move pointer forward by 1 byte.
+ */
+ writeInt8(C) {
+ return this.ensureAvailable(1), this._data.setInt8(this.offset++, C), this._updateLastWrittenByte(), this;
+ }
+ /**
+ * Write `value` as an 8-bit unsigned integer and move pointer forward by 1
+ * byte.
+ */
+ writeUint8(C) {
+ return this.ensureAvailable(1), this._data.setUint8(this.offset++, C), this._updateLastWrittenByte(), this;
+ }
+ /**
+ * An alias for {@link IOBuffer#writeUint8}.
+ */
+ writeByte(C) {
+ return this.writeUint8(C);
+ }
+ /**
+ * Write all elements of `bytes` as uint8 values and move pointer forward by
+ * `bytes.length` bytes.
+ */
+ writeBytes(C) {
+ this.ensureAvailable(C.length);
+ for (let c = 0; c < C.length; c++)
+ this._data.setUint8(this.offset++, C[c]);
+ return this._updateLastWrittenByte(), this;
+ }
+ /**
+ * Write `value` as a 16-bit signed integer and move pointer forward by 2
+ * bytes.
+ */
+ writeInt16(C) {
+ return this.ensureAvailable(2), this._data.setInt16(this.offset, C, this.littleEndian), this.offset += 2, this._updateLastWrittenByte(), this;
+ }
+ /**
+ * Write `value` as a 16-bit unsigned integer and move pointer forward by 2
+ * bytes.
+ */
+ writeUint16(C) {
+ return this.ensureAvailable(2), this._data.setUint16(this.offset, C, this.littleEndian), this.offset += 2, this._updateLastWrittenByte(), this;
+ }
+ /**
+ * Write `value` as a 32-bit signed integer and move pointer forward by 4
+ * bytes.
+ */
+ writeInt32(C) {
+ return this.ensureAvailable(4), this._data.setInt32(this.offset, C, this.littleEndian), this.offset += 4, this._updateLastWrittenByte(), this;
+ }
+ /**
+ * Write `value` as a 32-bit unsigned integer and move pointer forward by 4
+ * bytes.
+ */
+ writeUint32(C) {
+ return this.ensureAvailable(4), this._data.setUint32(this.offset, C, this.littleEndian), this.offset += 4, this._updateLastWrittenByte(), this;
+ }
+ /**
+ * Write `value` as a 32-bit floating number and move pointer forward by 4
+ * bytes.
+ */
+ writeFloat32(C) {
+ return this.ensureAvailable(4), this._data.setFloat32(this.offset, C, this.littleEndian), this.offset += 4, this._updateLastWrittenByte(), this;
+ }
+ /**
+ * Write `value` as a 64-bit floating number and move pointer forward by 8
+ * bytes.
+ */
+ writeFloat64(C) {
+ return this.ensureAvailable(8), this._data.setFloat64(this.offset, C, this.littleEndian), this.offset += 8, this._updateLastWrittenByte(), this;
+ }
+ /**
+ * Write `value` as a 64-bit signed bigint and move pointer forward by 8
+ * bytes.
+ */
+ writeBigInt64(C) {
+ return this.ensureAvailable(8), this._data.setBigInt64(this.offset, C, this.littleEndian), this.offset += 8, this._updateLastWrittenByte(), this;
+ }
+ /**
+ * Write `value` as a 64-bit unsigned bigint and move pointer forward by 8
+ * bytes.
+ */
+ writeBigUint64(C) {
+ return this.ensureAvailable(8), this._data.setBigUint64(this.offset, C, this.littleEndian), this.offset += 8, this._updateLastWrittenByte(), this;
+ }
+ /**
+ * Write the charCode of `str`'s first character as an 8-bit unsigned integer
+ * and move pointer forward by 1 byte.
+ */
+ writeChar(C) {
+ return this.writeUint8(C.charCodeAt(0));
+ }
+ /**
+ * Write the charCodes of all `str`'s characters as 8-bit unsigned integers
+ * and move pointer forward by `str.length` bytes.
+ */
+ writeChars(C) {
+ for (let c = 0; c < C.length; c++)
+ this.writeUint8(C.charCodeAt(c));
+ return this;
+ }
+ /**
+ * UTF-8 encode and write `str` to the current pointer offset and move pointer
+ * forward according to the encoded length.
+ */
+ writeUtf8(C) {
+ return this.writeBytes((0, v.encode)(C));
+ }
+ /**
+ * Export a Uint8Array view of the internal buffer.
+ * The view starts at the byte offset and its length
+ * is calculated to stop at the last written byte or the original length.
+ */
+ toArray() {
+ return new Uint8Array(this.buffer, this.byteOffset, this.lastWrittenByte);
+ }
+ /**
+ * Update the last written byte offset
+ * @private
+ */
+ _updateLastWrittenByte() {
+ this.offset > this.lastWrittenByte && (this.lastWrittenByte = this.offset);
+ }
+ }
+ }
+ ),
+ /***/
+ "./node_modules/iobuffer/lib-esm/text-encoding-polyfill.js": (
+ /*!*****************************************************************!*\
+ !*** ./node_modules/iobuffer/lib-esm/text-encoding-polyfill.js ***!
+ \*****************************************************************/
+ /***/
+ function() {
+ (function(P) {
+ if (P.TextEncoder && P.TextDecoder)
+ return !1;
+ function _(v = "utf-8") {
+ if (v !== "utf-8")
+ throw new RangeError(`Failed to construct 'TextEncoder': The encoding label provided ('${v}') is invalid.`);
+ }
+ Object.defineProperty(_.prototype, "encoding", {
+ value: "utf-8"
+ }), _.prototype.encode = function(v, M = { stream: !1 }) {
+ if (M.stream)
+ throw new Error("Failed to encode: the 'stream' option is unsupported.");
+ let E = 0;
+ const A = v.length;
+ let h = 0, g = Math.max(32, A + (A >> 1) + 7), C = new Uint8Array(g >> 3 << 3);
+ for (; E < A; ) {
+ let c = v.charCodeAt(E++);
+ if (c >= 55296 && c <= 56319) {
+ if (E < A) {
+ const S = v.charCodeAt(E);
+ (S & 64512) === 56320 && (++E, c = ((c & 1023) << 10) + (S & 1023) + 65536);
+ }
+ if (c >= 55296 && c <= 56319)
+ continue;
+ }
+ if (h + 4 > C.length) {
+ g += 8, g *= 1 + E / v.length * 2, g = g >> 3 << 3;
+ const S = new Uint8Array(g);
+ S.set(C), C = S;
+ }
+ if (c & 4294967168)
+ if (!(c & 4294965248))
+ C[h++] = c >> 6 & 31 | 192;
+ else if (!(c & 4294901760))
+ C[h++] = c >> 12 & 15 | 224, C[h++] = c >> 6 & 63 | 128;
+ else if (!(c & 4292870144))
+ C[h++] = c >> 18 & 7 | 240, C[h++] = c >> 12 & 63 | 128, C[h++] = c >> 6 & 63 | 128;
+ else
+ continue;
+ else {
+ C[h++] = c;
+ continue;
+ }
+ C[h++] = c & 63 | 128;
+ }
+ return C.slice(0, h);
+ };
+ function s(v = "utf-8", M = { fatal: !1 }) {
+ if (v !== "utf-8")
+ throw new RangeError(`Failed to construct 'TextDecoder': The encoding label provided ('${v}') is invalid.`);
+ if (M.fatal)
+ throw new Error("Failed to construct 'TextDecoder': the 'fatal' option is unsupported.");
+ }
+ Object.defineProperty(s.prototype, "encoding", {
+ value: "utf-8"
+ }), Object.defineProperty(s.prototype, "fatal", { value: !1 }), Object.defineProperty(s.prototype, "ignoreBOM", {
+ value: !1
+ }), s.prototype.decode = function(v, M = { stream: !1 }) {
+ if (M.stream)
+ throw new Error("Failed to decode: the 'stream' option is unsupported.");
+ const E = new Uint8Array(v);
+ let A = 0;
+ const h = E.length, g = [];
+ for (; A < h; ) {
+ const C = E[A++];
+ if (C === 0)
+ break;
+ if (!(C & 128))
+ g.push(C);
+ else if ((C & 224) === 192) {
+ const c = E[A++] & 63;
+ g.push((C & 31) << 6 | c);
+ } else if ((C & 240) === 224) {
+ const c = E[A++] & 63, S = E[A++] & 63;
+ g.push((C & 31) << 12 | c << 6 | S);
+ } else if ((C & 248) === 240) {
+ const c = E[A++] & 63, S = E[A++] & 63, y = E[A++] & 63;
+ let b = (C & 7) << 18 | c << 12 | S << 6 | y;
+ b > 65535 && (b -= 65536, g.push(b >>> 10 & 1023 | 55296), b = 56320 | b & 1023), g.push(b);
+ }
+ }
+ return String.fromCharCode.apply(null, g);
+ }, P.TextEncoder = _, P.TextDecoder = s;
+ })(typeof window < "u" ? window : typeof self < "u" ? self : this);
+ }
+ ),
+ /***/
+ "./node_modules/iobuffer/lib-esm/text.browser.js": (
+ /*!*******************************************************!*\
+ !*** ./node_modules/iobuffer/lib-esm/text.browser.js ***!
+ \*******************************************************/
+ /***/
+ (P, _, s) => {
+ s.r(_), s.d(_, {
+ /* harmony export */
+ decode: () => (
+ /* binding */
+ v
+ ),
+ /* harmony export */
+ encode: () => (
+ /* binding */
+ E
+ )
+ /* harmony export */
+ }), s(
+ /*! ./text-encoding-polyfill */
+ "./node_modules/iobuffer/lib-esm/text-encoding-polyfill.js"
+ );
+ function v(A, h = "utf8") {
+ return new TextDecoder(h).decode(A);
+ }
+ const M = new TextEncoder();
+ function E(A) {
+ return M.encode(A);
+ }
+ }
+ ),
+ /***/
+ "./node_modules/netcdfjs/lib-esm/data.js": (
+ /*!***********************************************!*\
+ !*** ./node_modules/netcdfjs/lib-esm/data.js ***!
+ \***********************************************/
+ /***/
+ (P, _, s) => {
+ s.r(_), s.d(_, {
+ /* harmony export */
+ nonRecord: () => (
+ /* binding */
+ M
+ ),
+ /* harmony export */
+ record: () => (
+ /* binding */
+ E
+ )
+ /* harmony export */
+ });
+ var v = s(
+ /*! ./types */
+ "./node_modules/netcdfjs/lib-esm/types.js"
+ );
+ function M(A, h) {
+ const g = (0, v.str2num)(h.type), C = h.size / (0, v.num2bytes)(g), c = new Array(C);
+ for (let S = 0; S < C; S++)
+ c[S] = (0, v.readType)(A, g, 1);
+ return c;
+ }
+ function E(A, h, g) {
+ const C = (0, v.str2num)(h.type), c = h.size ? h.size / (0, v.num2bytes)(C) : 1, S = g.length, y = new Array(S), b = g.recordStep;
+ if (b)
+ for (let w = 0; w < S; w++) {
+ const t = A.offset;
+ y[w] = (0, v.readType)(A, C, c), A.seek(t + b);
+ }
+ else
+ throw new Error("recordDimension.recordStep is undefined");
+ return y;
+ }
+ }
+ ),
+ /***/
+ "./node_modules/netcdfjs/lib-esm/header.js": (
+ /*!*************************************************!*\
+ !*** ./node_modules/netcdfjs/lib-esm/header.js ***!
+ \*************************************************/
+ /***/
+ (P, _, s) => {
+ s.r(_), s.d(_, {
+ /* harmony export */
+ header: () => (
+ /* binding */
+ c
+ )
+ /* harmony export */
+ });
+ var v = s(
+ /*! ./types */
+ "./node_modules/netcdfjs/lib-esm/types.js"
+ ), M = s(
+ /*! ./utils */
+ "./node_modules/netcdfjs/lib-esm/utils.js"
+ );
+ const E = 0, A = 10, h = 11, g = 12, C = 0;
+ function c(w, t) {
+ const r = { version: t }, u = {
+ length: w.readUint32()
+ }, o = S(w);
+ Array.isArray(o) || (u.id = o.recordId, u.name = o.recordName, r.dimensions = o.dimensions), r.globalAttributes = y(w);
+ const l = b(w, u == null ? void 0 : u.id, t);
+ return Array.isArray(l) || (r.variables = l.variables, u.recordStep = l.recordStep), r.recordDimension = u, r;
+ }
+ function S(w) {
+ const t = {};
+ let r, u;
+ const o = w.readUint32();
+ let l;
+ if (o === E)
+ return (0, M.notNetcdf)(w.readUint32() !== E, "wrong empty tag for list of dimensions"), [];
+ {
+ (0, M.notNetcdf)(o !== A, "wrong tag for list of dimensions");
+ const e = w.readUint32();
+ l = new Array(e);
+ for (let n = 0; n < e; n++) {
+ const a = (0, M.readName)(w), p = w.readUint32();
+ p === C && (r = n, u = a), l[n] = {
+ name: a,
+ size: p
+ };
+ }
+ }
+ return r !== void 0 && (t.recordId = r), u !== void 0 && (t.recordName = u), t.dimensions = l, t;
+ }
+ function y(w) {
+ const t = w.readUint32();
+ let r;
+ if (t === E)
+ return (0, M.notNetcdf)(w.readUint32() !== E, "wrong empty tag for list of attributes"), [];
+ {
+ (0, M.notNetcdf)(t !== g, "wrong tag for list of attributes");
+ const u = w.readUint32();
+ r = new Array(u);
+ for (let o = 0; o < u; o++) {
+ const l = (0, M.readName)(w), e = w.readUint32();
+ (0, M.notNetcdf)(e < 1 || e > 6, `non valid type ${e}`);
+ const n = w.readUint32(), a = (0, v.readType)(w, e, n);
+ (0, M.padding)(w), r[o] = {
+ name: l,
+ type: (0, v.num2str)(e),
+ value: a
+ };
+ }
+ }
+ return r;
+ }
+ function b(w, t, r) {
+ const u = w.readUint32();
+ let o = 0, l;
+ if (u === E)
+ return (0, M.notNetcdf)(w.readUint32() !== E, "wrong empty tag for list of variables"), [];
+ {
+ (0, M.notNetcdf)(u !== h, "wrong tag for list of variables");
+ const e = w.readUint32();
+ l = new Array(e);
+ for (let n = 0; n < e; n++) {
+ const a = (0, M.readName)(w), p = w.readUint32(), x = new Array(p);
+ for (let B = 0; B < p; B++)
+ x[B] = w.readUint32();
+ const D = y(w), O = w.readUint32();
+ (0, M.notNetcdf)(O < 1 && O > 6, `non valid type ${O}`);
+ const R = w.readUint32();
+ let z = w.readUint32();
+ r === 2 && ((0, M.notNetcdf)(z > 0, "offsets larger than 4GB not supported"), z = w.readUint32());
+ let T = !1;
+ typeof t < "u" && x[0] === t && (o += R, T = !0), l[n] = {
+ name: a,
+ dimensions: x,
+ attributes: D,
+ type: (0, v.num2str)(O),
+ size: R,
+ offset: z,
+ record: T
+ };
+ }
+ }
+ return {
+ variables: l,
+ recordStep: o
+ };
+ }
+ }
+ ),
+ /***/
+ "./node_modules/netcdfjs/lib-esm/index.js": (
+ /*!************************************************!*\
+ !*** ./node_modules/netcdfjs/lib-esm/index.js ***!
+ \************************************************/
+ /***/
+ (P, _, s) => {
+ s.r(_), s.d(_, {
+ /* harmony export */
+ NetCDFReader: () => (
+ /* reexport safe */
+ v.NetCDFReader
+ )
+ /* harmony export */
+ });
+ var v = s(
+ /*! ./parser */
+ "./node_modules/netcdfjs/lib-esm/parser.js"
+ );
+ }
+ ),
+ /***/
+ "./node_modules/netcdfjs/lib-esm/parser.js": (
+ /*!*************************************************!*\
+ !*** ./node_modules/netcdfjs/lib-esm/parser.js ***!
+ \*************************************************/
+ /***/
+ (P, _, s) => {
+ s.r(_), s.d(_, {
+ /* harmony export */
+ NetCDFReader: () => (
+ /* binding */
+ g
+ )
+ /* harmony export */
+ });
+ var v = s(
+ /*! iobuffer */
+ "./node_modules/iobuffer/lib-esm/IOBuffer.js"
+ ), M = s(
+ /*! ./data */
+ "./node_modules/netcdfjs/lib-esm/data.js"
+ ), E = s(
+ /*! ./header */
+ "./node_modules/netcdfjs/lib-esm/header.js"
+ ), A = s(
+ /*! ./toString */
+ "./node_modules/netcdfjs/lib-esm/toString.js"
+ ), h = s(
+ /*! ./utils */
+ "./node_modules/netcdfjs/lib-esm/utils.js"
+ );
+ class g {
+ constructor(c) {
+ this.toString = A.toString;
+ const S = new v.IOBuffer(c);
+ S.setBigEndian(), (0, h.notNetcdf)(S.readChars(3) !== "CDF", "should start with CDF");
+ const y = S.readByte();
+ (0, h.notNetcdf)(y > 2, "unknown version"), this.header = (0, E.header)(S, y), this.buffer = S;
+ }
+ /**
+ * @return - Version for the NetCDF format
+ */
+ get version() {
+ return this.header.version === 1 ? "classic format" : "64-bit offset format";
+ }
+ /**
+ * @return {object} - Metadata for the record dimension
+ * * `length`: Number of elements in the record dimension
+ * * `id`: Id number in the list of dimensions for the record dimension
+ * * `name`: String with the name of the record dimension
+ * * `recordStep`: Number with the record variables step size
+ */
+ get recordDimension() {
+ return this.header.recordDimension;
+ }
+ /**
+ * @return - Array - List of dimensions with:
+ * * `name`: String with the name of the dimension
+ * * `size`: Number with the size of the dimension
+ */
+ get dimensions() {
+ return this.header.dimensions;
+ }
+ /**
+ * @return - Array - List of global attributes with:
+ * * `name`: String with the name of the attribute
+ * * `type`: String with the type of the attribute
+ * * `value`: A number or string with the value of the attribute
+ */
+ get globalAttributes() {
+ return this.header.globalAttributes;
+ }
+ /**
+ * Returns the value of an attribute
+ * @param - AttributeName
+ * @return - Value of the attributeName or null
+ */
+ getAttribute(c) {
+ const S = this.globalAttributes.find((y) => y.name === c);
+ return S ? S.value : null;
+ }
+ /**
+ * Returns the value of a variable as a string
+ * @param - variableName
+ * @return - Value of the variable as a string or null
+ */
+ getDataVariableAsString(c) {
+ const S = this.getDataVariable(c);
+ return S ? S.join("") : null;
+ }
+ get variables() {
+ return this.header.variables;
+ }
+ /**
+ * Retrieves the data for a given variable
+ * @param variableName - Name of the variable to search or variable object
+ * @return The variable values
+ */
+ getDataVariable(c) {
+ let S;
+ if (typeof c == "string" ? S = this.header.variables.find((y) => y.name === c) : S = c, S === void 0)
+ throw new Error("Not a valid NetCDF v3.x file: variable not found");
+ return this.buffer.seek(S.offset), S.record ? (0, M.record)(this.buffer, S, this.header.recordDimension) : (0, M.nonRecord)(this.buffer, S);
+ }
+ /**
+ * Check if a dataVariable exists
+ * @param variableName - Name of the variable to find
+ * @return boolean
+ */
+ dataVariableExists(c) {
+ return this.header.variables.find((y) => y.name === c) !== void 0;
+ }
+ /**
+ * Check if an attribute exists
+ * @param attributeName - Name of the attribute to find
+ * @return boolean
+ */
+ attributeExists(c) {
+ return this.globalAttributes.find((y) => y.name === c) !== void 0;
+ }
+ }
+ }
+ ),
+ /***/
+ "./node_modules/netcdfjs/lib-esm/toString.js": (
+ /*!***************************************************!*\
+ !*** ./node_modules/netcdfjs/lib-esm/toString.js ***!
+ \***************************************************/
+ /***/
+ (P, _, s) => {
+ s.r(_), s.d(_, {
+ /* harmony export */
+ toString: () => (
+ /* binding */
+ v
+ )
+ /* harmony export */
+ });
+ function v() {
+ const M = [];
+ M.push("DIMENSIONS");
+ for (const A of this.dimensions)
+ M.push(` ${A.name.padEnd(30)} = size: ${A.size}`);
+ M.push(""), M.push("GLOBAL ATTRIBUTES");
+ for (const A of this.globalAttributes)
+ M.push(` ${A.name.padEnd(30)} = ${A.value}`);
+ const E = JSON.parse(JSON.stringify(this.variables));
+ M.push(""), M.push("VARIABLES:");
+ for (const A of E) {
+ A.value = this.getDataVariable(A);
+ let h = JSON.stringify(A.value);
+ h.length > 50 && (h = h.substring(0, 50)), isNaN(A.value.length) || (h += ` (length: ${A.value.length})`), M.push(` ${A.name.padEnd(30)} = ${h}`);
+ }
+ return M.join(`
+`);
+ }
+ }
+ ),
+ /***/
+ "./node_modules/netcdfjs/lib-esm/types.js": (
+ /*!************************************************!*\
+ !*** ./node_modules/netcdfjs/lib-esm/types.js ***!
+ \************************************************/
+ /***/
+ (P, _, s) => {
+ s.r(_), s.d(_, {
+ /* harmony export */
+ num2bytes: () => (
+ /* binding */
+ E
+ ),
+ /* harmony export */
+ num2str: () => (
+ /* binding */
+ M
+ ),
+ /* harmony export */
+ readType: () => (
+ /* binding */
+ g
+ ),
+ /* harmony export */
+ str2num: () => (
+ /* binding */
+ A
+ )
+ /* harmony export */
+ });
+ const v = {
+ BYTE: 1,
+ CHAR: 2,
+ SHORT: 3,
+ INT: 4,
+ FLOAT: 5,
+ DOUBLE: 6
+ };
+ function M(c) {
+ switch (Number(c)) {
+ case v.BYTE:
+ return "byte";
+ case v.CHAR:
+ return "char";
+ case v.SHORT:
+ return "short";
+ case v.INT:
+ return "int";
+ case v.FLOAT:
+ return "float";
+ case v.DOUBLE:
+ return "double";
+ default:
+ return "undefined";
+ }
+ }
+ function E(c) {
+ switch (Number(c)) {
+ case v.BYTE:
+ return 1;
+ case v.CHAR:
+ return 1;
+ case v.SHORT:
+ return 2;
+ case v.INT:
+ return 4;
+ case v.FLOAT:
+ return 4;
+ case v.DOUBLE:
+ return 8;
+ default:
+ return -1;
+ }
+ }
+ function A(c) {
+ switch (String(c)) {
+ case "byte":
+ return v.BYTE;
+ case "char":
+ return v.CHAR;
+ case "short":
+ return v.SHORT;
+ case "int":
+ return v.INT;
+ case "float":
+ return v.FLOAT;
+ case "double":
+ return v.DOUBLE;
+ default:
+ return -1;
+ }
+ }
+ function h(c, S) {
+ if (c !== 1) {
+ const y = new Array(c);
+ for (let b = 0; b < c; b++)
+ y[b] = S();
+ return y;
+ } else
+ return S();
+ }
+ function g(c, S, y) {
+ switch (S) {
+ case v.BYTE:
+ return Array.from(c.readBytes(y));
+ case v.CHAR:
+ return C(c.readChars(y));
+ case v.SHORT:
+ return h(y, c.readInt16.bind(c));
+ case v.INT:
+ return h(y, c.readInt32.bind(c));
+ case v.FLOAT:
+ return h(y, c.readFloat32.bind(c));
+ case v.DOUBLE:
+ return h(y, c.readFloat64.bind(c));
+ default:
+ throw new Error(`non valid type ${S}`);
+ }
+ }
+ function C(c) {
+ return c.charCodeAt(c.length - 1) === 0 ? c.substring(0, c.length - 1) : c;
+ }
+ }
+ ),
+ /***/
+ "./node_modules/netcdfjs/lib-esm/utils.js": (
+ /*!************************************************!*\
+ !*** ./node_modules/netcdfjs/lib-esm/utils.js ***!
+ \************************************************/
+ /***/
+ (P, _, s) => {
+ s.r(_), s.d(_, {
+ /* harmony export */
+ notNetcdf: () => (
+ /* binding */
+ v
+ ),
+ /* harmony export */
+ padding: () => (
+ /* binding */
+ M
+ ),
+ /* harmony export */
+ readName: () => (
+ /* binding */
+ E
+ )
+ /* harmony export */
+ });
+ function v(A, h) {
+ if (A)
+ throw new TypeError(`Not a valid NetCDF v3.x file: ${h}`);
+ }
+ function M(A) {
+ A.offset % 4 !== 0 && A.skip(4 - A.offset % 4);
+ }
+ function E(A) {
+ const h = A.readUint32(), g = A.readChars(h);
+ return M(A), g;
+ }
+ }
+ ),
+ /***/
+ "./src/WebGL/shaders/lib/basic/basic.frag": (
+ /*!************************************************!*\
+ !*** ./src/WebGL/shaders/lib/basic/basic.frag ***!
+ \************************************************/
+ /***/
+ (P, _, s) => {
+ s.r(_), s.d(_, {
+ /* harmony export */
+ default: () => v
+ /* harmony export */
+ });
+ const v = `uniform mat4 viewMatrix;
+uniform float opacity;
+uniform vec3 fogColor;
+uniform float fogNear;
+uniform float fogFar;
+varying vec3 vColor;
+//DEFINEFRAGCOLOR
+void main() {
+ gl_FragColor = vec4( vColor, opacity );
+ float depth = gl_FragCoord.z / gl_FragCoord.w;
+ float fogFactor = smoothstep( fogNear, fogFar, depth );
+ gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );
+}`;
+ }
+ ),
+ /***/
+ "./src/WebGL/shaders/lib/basic/basic.vert": (
+ /*!************************************************!*\
+ !*** ./src/WebGL/shaders/lib/basic/basic.vert ***!
+ \************************************************/
+ /***/
+ (P, _, s) => {
+ s.r(_), s.d(_, {
+ /* harmony export */
+ default: () => v
+ /* harmony export */
+ });
+ const v = `uniform mat4 modelViewMatrix;
+uniform mat4 projectionMatrix;
+uniform mat4 viewMatrix;
+uniform mat3 normalMatrix;
+
+attribute vec3 position;
+attribute vec3 color;
+
+varying vec3 vColor;
+
+void main() {
+
+ vColor = color;
+ vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
+ gl_Position = projectionMatrix * mvPosition;
+
+}`;
+ }
+ ),
+ /***/
+ "./src/WebGL/shaders/lib/instanced/instanced.frag": (
+ /*!********************************************************!*\
+ !*** ./src/WebGL/shaders/lib/instanced/instanced.frag ***!
+ \********************************************************/
+ /***/
+ (P, _, s) => {
+ s.r(_), s.d(_, {
+ /* harmony export */
+ default: () => v
+ /* harmony export */
+ });
+ const v = `uniform mat4 viewMatrix;
+uniform float opacity;
+
+uniform vec3 fogColor;
+uniform float fogNear;
+uniform float fogFar;
+
+varying vec3 vLightFront;
+varying vec3 vColor;
+//DEFINEFRAGCOLOR
+
+void main() {
+
+ gl_FragColor = vec4( vec3 ( 1.0 ), opacity );
+
+ #ifndef WIREFRAME
+ gl_FragColor.xyz *= vLightFront;
+ #endif
+
+ gl_FragColor = gl_FragColor * vec4( vColor, opacity );
+ float depth = gl_FragCoord.z / gl_FragCoord.w;
+
+ float fogFactor = smoothstep( fogNear, fogFar, depth );
+
+ gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );
+
+}
+
+
+`;
+ }
+ ),
+ /***/
+ "./src/WebGL/shaders/lib/instanced/instanced.vert": (
+ /*!********************************************************!*\
+ !*** ./src/WebGL/shaders/lib/instanced/instanced.vert ***!
+ \********************************************************/
+ /***/
+ (P, _, s) => {
+ s.r(_), s.d(_, {
+ /* harmony export */
+ default: () => v
+ /* harmony export */
+ });
+ const v = `
+
+uniform mat4 modelViewMatrix;
+uniform mat4 projectionMatrix;
+uniform mat4 viewMatrix;
+uniform mat3 normalMatrix;
+uniform vec3 directionalLightColor[ 1 ];
+uniform vec3 directionalLightDirection[ 1 ];
+
+attribute vec3 offset;
+attribute vec3 position;
+attribute vec3 normal;
+attribute vec3 color;
+attribute float radius;
+
+varying vec3 vColor;
+varying vec3 vLightFront;
+
+void main() {
+
+ vColor = color;
+
+ vec3 objectNormal = normal;
+ vec3 transformedNormal = normalMatrix * objectNormal;
+ vec4 mvPosition = modelViewMatrix * vec4( position * radius + offset, 1.0 );
+
+ vLightFront = vec3( 0.0 );
+
+ transformedNormal = normalize( transformedNormal );
+
+ vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ 0 ], 0.0 );
+ vec3 dirVector = normalize( lDirection.xyz );
+ float dotProduct = dot( transformedNormal, dirVector );
+ vec3 directionalLightWeighting = vec3( max( dotProduct, 0.0 ) );
+
+ vLightFront += directionalLightColor[ 0 ] * directionalLightWeighting;
+
+ gl_Position = projectionMatrix * mvPosition;
+}
+
+`;
+ }
+ ),
+ /***/
+ "./src/WebGL/shaders/lib/lambert/lambert.frag": (
+ /*!****************************************************!*\
+ !*** ./src/WebGL/shaders/lib/lambert/lambert.frag ***!
+ \****************************************************/
+ /***/
+ (P, _, s) => {
+ s.r(_), s.d(_, {
+ /* harmony export */
+ default: () => v
+ /* harmony export */
+ });
+ const v = `uniform mat4 viewMatrix;
+uniform float opacity;
+
+uniform vec3 fogColor;
+uniform float fogNear;
+uniform float fogFar;
+
+varying vec3 vLightFront;
+varying vec3 vColor;
+//DEFINEFRAGCOLOR
+
+void main() {
+
+ gl_FragColor = vec4( vec3 ( 1.0 ), opacity );
+
+ #ifndef WIREFRAME
+ gl_FragColor.xyz *= vLightFront;
+ #endif
+
+ gl_FragColor = gl_FragColor * vec4( vColor, opacity );
+ float depth = gl_FragCoord.z / gl_FragCoord.w;
+
+ float fogFactor = smoothstep( fogNear, fogFar, depth );
+
+ gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );
+
+}`;
+ }
+ ),
+ /***/
+ "./src/WebGL/shaders/lib/lambert/lambert.vert": (
+ /*!****************************************************!*\
+ !*** ./src/WebGL/shaders/lib/lambert/lambert.vert ***!
+ \****************************************************/
+ /***/
+ (P, _, s) => {
+ s.r(_), s.d(_, {
+ /* harmony export */
+ default: () => v
+ /* harmony export */
+ });
+ const v = `
+uniform mat4 modelViewMatrix;
+uniform mat4 projectionMatrix;
+uniform mat4 viewMatrix;
+uniform mat3 normalMatrix;
+uniform vec3 directionalLightColor[ 1 ];
+uniform vec3 directionalLightDirection[ 1 ];
+
+attribute vec3 position;
+attribute vec3 normal;
+attribute vec3 color;
+
+varying vec3 vColor;
+varying vec3 vLightFront;
+
+void main() {
+
+ vColor = color;
+
+ vec3 objectNormal = normal;
+ vec3 transformedNormal = normalMatrix * objectNormal;
+ vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
+
+ vLightFront = vec3( 0.0 );
+
+ transformedNormal = normalize( transformedNormal );
+
+ vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ 0 ], 0.0 );
+ vec3 dirVector = normalize( lDirection.xyz );
+ float dotProduct = dot( transformedNormal, dirVector );
+ vec3 directionalLightWeighting = vec3( max( dotProduct, 0.0 ) );
+
+ vLightFront += directionalLightColor[ 0 ] * directionalLightWeighting;
+
+ gl_Position = projectionMatrix * mvPosition;
+}`;
+ }
+ ),
+ /***/
+ "./src/WebGL/shaders/lib/lambertdouble/lambertdouble.frag": (
+ /*!****************************************************************!*\
+ !*** ./src/WebGL/shaders/lib/lambertdouble/lambertdouble.frag ***!
+ \****************************************************************/
+ /***/
+ (P, _, s) => {
+ s.r(_), s.d(_, {
+ /* harmony export */
+ default: () => v
+ /* harmony export */
+ });
+ const v = `
+
+uniform mat4 viewMatrix;
+uniform float opacity;
+
+uniform vec3 fogColor;
+uniform float fogNear;
+uniform float fogFar;
+
+varying vec3 vLightFront;
+varying vec3 vLightBack;
+
+varying vec3 vColor;
+//DEFINEFRAGCOLOR
+
+void main() {
+
+ gl_FragColor = vec4( vec3 ( 1.0 ), opacity );
+
+ #ifndef WIREFRAME
+ if ( gl_FrontFacing )
+ gl_FragColor.xyz *= vLightFront;
+ else
+ gl_FragColor.xyz *= vLightBack;
+ #endif
+
+ gl_FragColor = gl_FragColor * vec4( vColor, opacity );
+ float depth = gl_FragCoord.z / gl_FragCoord.w;
+
+ float fogFactor = smoothstep( fogNear, fogFar, depth );
+
+ gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );
+
+}
+
+
+`;
+ }
+ ),
+ /***/
+ "./src/WebGL/shaders/lib/lambertdouble/lambertdouble.vert": (
+ /*!****************************************************************!*\
+ !*** ./src/WebGL/shaders/lib/lambertdouble/lambertdouble.vert ***!
+ \****************************************************************/
+ /***/
+ (P, _, s) => {
+ s.r(_), s.d(_, {
+ /* harmony export */
+ default: () => v
+ /* harmony export */
+ });
+ const v = `
+
+uniform mat4 modelViewMatrix;
+uniform mat4 projectionMatrix;
+uniform mat4 viewMatrix;
+uniform mat3 normalMatrix;
+uniform vec3 directionalLightColor[ 1 ];
+uniform vec3 directionalLightDirection[ 1 ];
+
+attribute vec3 position;
+attribute vec3 normal;
+attribute vec3 color;
+
+varying vec3 vColor;
+varying vec3 vLightFront;
+varying vec3 vLightBack;
+
+void main() {
+
+ vColor = color;
+
+ vec3 objectNormal = normal;
+ vec3 transformedNormal = normalMatrix * objectNormal;
+ vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
+
+ vLightFront = vec3( 0.0 );
+ vLightBack = vec3( 0.0 );
+
+ transformedNormal = normalize( transformedNormal );
+
+ vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ 0 ], 0.0 );
+ vec3 dirVector = normalize( lDirection.xyz );
+ float dotProduct = dot( transformedNormal, dirVector );
+ vec3 directionalLightWeighting = vec3( max( dotProduct, 0.0 ) );
+ vec3 directionalLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );
+
+ vLightFront += directionalLightColor[ 0 ] * directionalLightWeighting;
+ vLightBack += directionalLightColor[ 0 ] * directionalLightWeightingBack;
+
+ gl_Position = projectionMatrix * mvPosition;
+}
+
+`;
+ }
+ ),
+ /***/
+ "./src/WebGL/shaders/lib/outline/outline.frag": (
+ /*!****************************************************!*\
+ !*** ./src/WebGL/shaders/lib/outline/outline.frag ***!
+ \****************************************************/
+ /***/
+ (P, _, s) => {
+ s.r(_), s.d(_, {
+ /* harmony export */
+ default: () => v
+ /* harmony export */
+ });
+ const v = `
+
+uniform float opacity;
+uniform vec3 outlineColor;
+uniform vec3 fogColor;
+uniform float fogNear;
+uniform float fogFar;
+//DEFINEFRAGCOLOR
+
+void main() {
+ gl_FragColor = vec4( outlineColor, 1 );
+}
+
+
+`;
+ }
+ ),
+ /***/
+ "./src/WebGL/shaders/lib/outline/outline.vert": (
+ /*!****************************************************!*\
+ !*** ./src/WebGL/shaders/lib/outline/outline.vert ***!
+ \****************************************************/
+ /***/
+ (P, _, s) => {
+ s.r(_), s.d(_, {
+ /* harmony export */
+ default: () => v
+ /* harmony export */
+ });
+ const v = `
+
+uniform mat4 modelViewMatrix;
+uniform mat4 projectionMatrix;
+uniform float outlineWidth;
+uniform float outlinePushback;
+
+attribute vec3 position;
+attribute vec3 normal;
+attribute vec3 color;
+
+void main() {
+
+ vec4 norm = modelViewMatrix*vec4(normalize(normal),0.0);
+ vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
+ mvPosition.xy += norm.xy*outlineWidth;
+ gl_Position = projectionMatrix * mvPosition;
+ mvPosition.z -= outlinePushback; //go backwards in model space
+ vec4 pushpos = projectionMatrix*mvPosition; //project to get z in projection space, I'm probably missing some simple math to do the same thing..
+ gl_Position.z = gl_Position.w*pushpos.z/pushpos.w;
+}
+
+`;
+ }
+ ),
+ /***/
+ "./src/WebGL/shaders/lib/screen/screen.frag": (
+ /*!**************************************************!*\
+ !*** ./src/WebGL/shaders/lib/screen/screen.frag ***!
+ \**************************************************/
+ /***/
+ (P, _, s) => {
+ s.r(_), s.d(_, {
+ /* harmony export */
+ default: () => v
+ /* harmony export */
+ });
+ const v = `uniform sampler2D colormap;
+varying highp vec2 vTexCoords;
+uniform vec2 dimensions;
+//DEFINEFRAGCOLOR
+void main (void) {
+ gl_FragColor = texture2D(colormap, vTexCoords);
+}
+ `;
+ }
+ ),
+ /***/
+ "./src/WebGL/shaders/lib/screen/screen.vert": (
+ /*!**************************************************!*\
+ !*** ./src/WebGL/shaders/lib/screen/screen.vert ***!
+ \**************************************************/
+ /***/
+ (P, _, s) => {
+ s.r(_), s.d(_, {
+ /* harmony export */
+ default: () => v
+ /* harmony export */
+ });
+ const v = `attribute vec2 vertexPosition;
+varying highp vec2 vTexCoords;
+const vec2 scale = vec2(0.5, 0.5);
+
+void main() {
+ vTexCoords = vertexPosition * scale + scale; // scale vertex attribute to [0,1] range
+ gl_Position = vec4(vertexPosition, 0.0, 1.0);
+}
+ `;
+ }
+ ),
+ /***/
+ "./src/WebGL/shaders/lib/screenaa/screenaa.frag": (
+ /*!******************************************************!*\
+ !*** ./src/WebGL/shaders/lib/screenaa/screenaa.frag ***!
+ \******************************************************/
+ /***/
+ (P, _, s) => {
+ s.r(_), s.d(_, {
+ /* harmony export */
+ default: () => v
+ /* harmony export */
+ });
+ const v = `uniform sampler2D colormap;
+varying highp vec2 vTexCoords;
+uniform vec2 dimensions;
+
+// Basic FXAA implementation based on the code on geeks3d.com
+#define FXAA_REDUCE_MIN (1.0/ 128.0)
+#define FXAA_REDUCE_MUL (1.0 / 8.0)
+#define FXAA_SPAN_MAX 8.0
+
+vec4 applyFXAA(vec2 fragCoord, sampler2D tex)
+{
+ vec4 color;
+ vec2 inverseVP = vec2(1.0 / dimensions.x, 1.0 / dimensions.y);
+ vec3 rgbNW = texture2D(tex, fragCoord + vec2(-1.0, -1.0) * inverseVP).xyz;
+ vec3 rgbNE = texture2D(tex, fragCoord + vec2(1.0, -1.0) * inverseVP).xyz;
+ vec3 rgbSW = texture2D(tex, fragCoord + vec2(-1.0, 1.0) * inverseVP).xyz;
+ vec3 rgbSE = texture2D(tex, fragCoord + vec2(1.0, 1.0) * inverseVP).xyz;
+ vec3 rgbM = texture2D(tex, fragCoord * inverseVP).xyz;
+ vec3 luma = vec3(0.299, 0.587, 0.114);
+ float lumaNW = dot(rgbNW, luma);
+ float lumaNE = dot(rgbNE, luma);
+ float lumaSW = dot(rgbSW, luma);
+ float lumaSE = dot(rgbSE, luma);
+ float lumaM = dot(rgbM, luma);
+ float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));
+ float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));
+
+ vec2 dir;
+ dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));
+ dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));
+
+ float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) *
+ (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN);
+
+ float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce);
+ dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX),
+ max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),
+ dir * rcpDirMin)) * inverseVP;
+
+ vec3 rgbA = 0.5 * (
+ texture2D(tex, fragCoord + dir * (1.0 / 3.0 - 0.5)).xyz +
+ texture2D(tex, fragCoord + dir * (2.0 / 3.0 - 0.5)).xyz);
+ vec3 rgbB = rgbA * 0.5 + 0.25 * (
+ texture2D(tex, fragCoord + dir * -0.5).xyz +
+ texture2D(tex, fragCoord + dir * 0.5).xyz);
+
+ float lumaB = dot(rgbB, luma);
+ if ((lumaB < lumaMin) || (lumaB > lumaMax))
+ color = vec4(rgbA, 1.0);
+ else
+ color = vec4(rgbB, 1.0);
+ return color;
+}
+//DEFINEFRAGCOLOR
+void main (void) {
+ gl_FragColor = applyFXAA(vTexCoords, colormap);
+}
+ `;
+ }
+ ),
+ /***/
+ "./src/WebGL/shaders/lib/screenaa/screenaa.vert": (
+ /*!******************************************************!*\
+ !*** ./src/WebGL/shaders/lib/screenaa/screenaa.vert ***!
+ \******************************************************/
+ /***/
+ (P, _, s) => {
+ s.r(_), s.d(_, {
+ /* harmony export */
+ default: () => v
+ /* harmony export */
+ });
+ const v = `attribute vec2 vertexPosition;
+varying highp vec2 vTexCoords;
+const vec2 scale = vec2(0.5, 0.5);
+
+void main() {
+ vTexCoords = vertexPosition * scale + scale; // scale vertex attribute to [0,1] range
+ gl_Position = vec4(vertexPosition, 0.0, 1.0);
+}
+ `;
+ }
+ ),
+ /***/
+ "./src/WebGL/shaders/lib/sphereimposter/sphereimposter.frag": (
+ /*!******************************************************************!*\
+ !*** ./src/WebGL/shaders/lib/sphereimposter/sphereimposter.frag ***!
+ \******************************************************************/
+ /***/
+ (P, _, s) => {
+ s.r(_), s.d(_, {
+ /* harmony export */
+ default: () => v
+ /* harmony export */
+ });
+ const v = `
+uniform mat4 viewMatrix;
+uniform float opacity;
+uniform mat4 projectionMatrix;
+
+uniform vec3 fogColor;
+uniform float fogNear;
+uniform float fogFar;
+uniform float uDepth;
+uniform vec3 directionalLightColor[ 1 ];
+
+varying vec3 vColor;
+varying vec2 mapping;
+varying float rval;
+varying vec3 vLight;
+varying vec3 center;
+
+//DEFINEFRAGCOLOR
+
+void main() {
+ float lensqr = dot(mapping,mapping);
+ float rsqr = rval*rval;
+ if(lensqr > rsqr)
+ discard;
+ float z = sqrt(rsqr-lensqr);
+ vec3 cameraPos = center+ vec3(mapping.x,mapping.y,z);
+ vec4 clipPos = projectionMatrix * vec4(cameraPos, 1.0);
+ float ndcDepth = clipPos.z / clipPos.w;
+ gl_FragDepthEXT = ((gl_DepthRange.diff * ndcDepth) + gl_DepthRange.near + gl_DepthRange.far) / 2.0;
+ vec3 norm = normalize(vec3(mapping.x,mapping.y,z));
+ float dotProduct = dot( norm, vLight );
+ vec3 directionalLightWeighting = vec3( max( dotProduct, 0.0 ) );
+ vec3 vLight = directionalLightColor[ 0 ] * directionalLightWeighting;
+ gl_FragColor = vec4(vLight*vColor, opacity*opacity );
+ float fogFactor = smoothstep( fogNear, fogFar, gl_FragDepthEXT/gl_FragCoord.w );
+ gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );
+
+
+}
+
+`;
+ }
+ ),
+ /***/
+ "./src/WebGL/shaders/lib/sphereimposter/sphereimposter.vert": (
+ /*!******************************************************************!*\
+ !*** ./src/WebGL/shaders/lib/sphereimposter/sphereimposter.vert ***!
+ \******************************************************************/
+ /***/
+ (P, _, s) => {
+ s.r(_), s.d(_, {
+ /* harmony export */
+ default: () => v
+ /* harmony export */
+ });
+ const v = `uniform mat4 modelViewMatrix;
+uniform mat4 projectionMatrix;
+uniform mat4 viewMatrix;
+uniform mat3 normalMatrix;
+uniform vec3 directionalLightColor[ 1 ];
+uniform vec3 directionalLightDirection[ 1 ];
+
+attribute vec3 position;
+attribute vec3 normal;
+attribute vec3 color;
+
+varying vec2 mapping;
+varying vec3 vColor;
+varying float rval;
+varying vec3 vLight;
+varying vec3 center;
+
+void main() {
+
+ vColor = color;
+ vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
+ center = mvPosition.xyz;
+ vec4 projPosition = projectionMatrix * mvPosition;
+ vec4 adjust = projectionMatrix* vec4(normal,0.0); adjust.z = 0.0; adjust.w = 0.0;
+ vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ 0 ], 0.0 );
+ vLight = normalize( lDirection.xyz );
+ mapping = normal.xy;
+ rval = abs(normal.x);
+ gl_Position = projPosition+adjust;
+
+}
+`;
+ }
+ ),
+ /***/
+ "./src/WebGL/shaders/lib/sphereimposteroutline/sphereimposteroutline.frag": (
+ /*!********************************************************************************!*\
+ !*** ./src/WebGL/shaders/lib/sphereimposteroutline/sphereimposteroutline.frag ***!
+ \********************************************************************************/
+ /***/
+ (P, _, s) => {
+ s.r(_), s.d(_, {
+ /* harmony export */
+ default: () => v
+ /* harmony export */
+ });
+ const v = `
+
+uniform float opacity;
+uniform vec3 outlineColor;
+uniform vec3 fogColor;
+uniform float fogNear;
+uniform float fogFar;
+uniform mat4 projectionMatrix;
+varying vec2 mapping;
+varying float rval;
+varying vec3 center;
+
+uniform float outlinePushback;
+
+//DEFINEFRAGCOLOR
+
+void main() {
+ float lensqr = dot(mapping,mapping);
+ float rsqr = rval*rval;
+ if(lensqr > rsqr)
+ discard;
+ float z = sqrt(rsqr-lensqr);
+ vec3 cameraPos = center+ vec3(mapping.x,mapping.y,z-outlinePushback);
+ vec4 clipPos = projectionMatrix * vec4(cameraPos, 1.0);
+ float ndcDepth = clipPos.z / clipPos.w;
+ gl_FragDepthEXT = ((gl_DepthRange.diff * ndcDepth) + gl_DepthRange.near + gl_DepthRange.far) / 2.0;
+ gl_FragColor = vec4(outlineColor, 1 );
+}
+
+
+`;
+ }
+ ),
+ /***/
+ "./src/WebGL/shaders/lib/sphereimposteroutline/sphereimposteroutline.vert": (
+ /*!********************************************************************************!*\
+ !*** ./src/WebGL/shaders/lib/sphereimposteroutline/sphereimposteroutline.vert ***!
+ \********************************************************************************/
+ /***/
+ (P, _, s) => {
+ s.r(_), s.d(_, {
+ /* harmony export */
+ default: () => v
+ /* harmony export */
+ });
+ const v = `
+
+uniform mat4 modelViewMatrix;
+uniform mat4 projectionMatrix;
+uniform float outlineWidth;
+uniform float outlinePushback;
+
+attribute vec3 position;
+attribute vec3 normal;
+attribute vec3 color;
+
+varying vec2 mapping;
+varying float rval;
+varying vec3 center;
+
+void main() {
+
+ vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
+ center = mvPosition.xyz;
+ vec4 projPosition = projectionMatrix * mvPosition;
+ vec2 norm = normal.xy + vec2(sign(normal.x)*outlineWidth,sign(normal.y)*outlineWidth);
+ vec4 adjust = projectionMatrix* vec4(norm,normal.z,0.0); adjust.z = 0.0; adjust.w = 0.0;
+ mapping = norm.xy;
+ rval = abs(norm.x);
+ gl_Position = projPosition+adjust;
+}
+
+`;
+ }
+ ),
+ /***/
+ "./src/WebGL/shaders/lib/sprite/sprite.frag": (
+ /*!**************************************************!*\
+ !*** ./src/WebGL/shaders/lib/sprite/sprite.frag ***!
+ \**************************************************/
+ /***/
+ (P, _, s) => {
+ s.r(_), s.d(_, {
+ /* harmony export */
+ default: () => v
+ /* harmony export */
+ });
+ const v = `
+
+uniform vec3 color;
+uniform sampler2D map;
+uniform float opacity;
+
+uniform int fogType;
+uniform vec3 fogColor;
+uniform float fogDensity;
+uniform float fogNear;
+uniform float fogFar;
+uniform float alphaTest;
+
+varying vec2 vUV;
+//DEFINEFRAGCOLOR
+
+void main() {
+
+ vec4 texture = texture2D(map, vUV);
+
+ if (texture.a < alphaTest) discard;
+
+ gl_FragColor = vec4(color * texture.xyz, texture.a * opacity);
+
+ if (fogType > 0) {
+
+ float depth = gl_FragCoord.z / gl_FragCoord.w;
+ float fogFactor = 0.0;
+
+ if (fogType == 1) {
+ fogFactor = smoothstep(fogNear, fogFar, depth);
+ }
+
+ else {
+ const float LOG2 = 1.442695;
+ float fogFactor = exp2(- fogDensity * fogDensity * depth * depth * LOG2);
+ fogFactor = 1.0 - clamp(fogFactor, 0.0, 1.0);
+ }
+
+ gl_FragColor = mix(gl_FragColor, vec4(fogColor, gl_FragColor.w), fogFactor);
+
+ }
+}
+
+`;
+ }
+ ),
+ /***/
+ "./src/WebGL/shaders/lib/sprite/sprite.vert": (
+ /*!**************************************************!*\
+ !*** ./src/WebGL/shaders/lib/sprite/sprite.vert ***!
+ \**************************************************/
+ /***/
+ (P, _, s) => {
+ s.r(_), s.d(_, {
+ /* harmony export */
+ default: () => v
+ /* harmony export */
+ });
+ const v = `
+
+uniform int useScreenCoordinates;
+uniform vec3 screenPosition;
+uniform mat4 modelViewMatrix;
+uniform mat4 projectionMatrix;
+uniform float rotation;
+uniform vec2 scale;
+uniform vec2 alignment;
+uniform vec2 uvOffset;
+uniform vec2 uvScale;
+
+attribute vec2 position;
+attribute vec2 uv;
+
+varying vec2 vUV;
+
+void main() {
+
+ vUV = uvOffset + uv * uvScale;
+
+ vec2 alignedPosition = position + alignment;
+
+ vec2 rotatedPosition;
+ rotatedPosition.x = ( cos(rotation) * alignedPosition.x - sin(rotation) * alignedPosition.y ) * scale.x;
+ rotatedPosition.y = ( sin(rotation) * alignedPosition.x + cos(rotation) * alignedPosition.y ) * scale.y;
+
+ vec4 finalPosition;
+
+ if(useScreenCoordinates != 0) {
+ finalPosition = vec4(screenPosition.xy + rotatedPosition, screenPosition.z, 1.0);
+ }
+
+ else {
+ finalPosition = projectionMatrix * modelViewMatrix * vec4(0.0, 0.0, 0.0, 1.0); finalPosition /= finalPosition.w;
+ finalPosition.xy += rotatedPosition;
+ }
+
+ gl_Position = finalPosition;
+
+}
+
+`;
+ }
+ ),
+ /***/
+ "./src/WebGL/shaders/lib/stickimposter/stickimposter.partial.frag": (
+ /*!************************************************************************!*\
+ !*** ./src/WebGL/shaders/lib/stickimposter/stickimposter.partial.frag ***!
+ \************************************************************************/
+ /***/
+ (P, _, s) => {
+ s.r(_), s.d(_, {
+ /* harmony export */
+ default: () => v
+ /* harmony export */
+ });
+ const v = ` float dotProduct = dot( norm, vLight );
+ vec3 light = vec3( max( dotProduct, 0.0 ) );
+ gl_FragColor = vec4(light*color, opacity*opacity );
+ float fogFactor = smoothstep( fogNear, fogFar, depth );
+ gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );
+}`;
+ }
+ ),
+ /***/
+ "./src/WebGL/shaders/lib/stickimposter/stickimposter.vert": (
+ /*!****************************************************************!*\
+ !*** ./src/WebGL/shaders/lib/stickimposter/stickimposter.vert ***!
+ \****************************************************************/
+ /***/
+ (P, _, s) => {
+ s.r(_), s.d(_, {
+ /* harmony export */
+ default: () => v
+ /* harmony export */
+ });
+ const v = `
+
+uniform mat4 modelViewMatrix;
+uniform mat4 projectionMatrix;
+uniform mat4 viewMatrix;
+uniform mat3 normalMatrix;
+uniform vec3 directionalLightColor[ 1 ];
+uniform vec3 directionalLightDirection[ 1 ];
+
+attribute vec3 position;
+attribute vec3 normal;
+attribute vec3 color;
+attribute float radius;
+
+varying vec3 vColor;
+varying vec3 vLight;
+varying vec3 cposition;
+varying vec3 p1;
+varying vec3 p2;
+varying float r;
+
+void main() {
+
+ vColor = color; vColor.z = abs(vColor.z); //z indicates which vertex and so would vary
+ r = abs(radius);
+ vec4 to = modelViewMatrix*vec4(normal, 1.0); //normal is other point of cylinder
+ vec4 pt = modelViewMatrix*vec4(position, 1.0);
+ vec4 mvPosition = pt;
+ p1 = pt.xyz; p2 = to.xyz;
+ vec3 norm = to.xyz-pt.xyz;
+ float mult = 1.1; //slop to account for perspective of sphere
+ if(length(p1) > length(p2)) { //billboard at level of closest point
+ mvPosition = to;
+ }
+ vec3 n = normalize(mvPosition.xyz);
+//intersect with the plane defined by the camera looking at the billboard point
+ if(color.z >= 0.0) { //p1
+ if(projectionMatrix[3][3] == 0.0) { //perspective
+ vec3 pnorm = normalize(p1);
+ float t = dot(mvPosition.xyz-p1,n)/dot(pnorm,n);
+ mvPosition.xyz = p1+t*pnorm;
+ } else { //orthographic
+ mvPosition.xyz = p1;
+ }
+ } else {
+ if(projectionMatrix[3][3] == 0.0) { //perspective
+ vec3 pnorm = normalize(p2);
+ float t = dot(mvPosition.xyz-p2,n)/dot(pnorm,n);
+ mvPosition.xyz = p2+t*pnorm;
+ } else { //orthographic
+ mvPosition.xyz = p2;
+ }
+ mult *= -1.0;
+ }
+ vec3 cr = normalize(cross(mvPosition.xyz,norm))*radius;
+ vec3 doublecr = normalize(cross(mvPosition.xyz,cr))*radius;
+ mvPosition.xyz += mult*(cr + doublecr).xyz;
+ cposition = mvPosition.xyz;
+ gl_Position = projectionMatrix * mvPosition;
+ vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ 0 ], 0.0 );
+ vLight = normalize( lDirection.xyz )*directionalLightColor[0]; //not really sure this is right, but color is always white so..
+}
+
+`;
+ }
+ ),
+ /***/
+ "./src/WebGL/shaders/lib/stickimposteroutline/stickimposteroutline.vert": (
+ /*!******************************************************************************!*\
+ !*** ./src/WebGL/shaders/lib/stickimposteroutline/stickimposteroutline.vert ***!
+ \******************************************************************************/
+ /***/
+ (P, _, s) => {
+ s.r(_), s.d(_, {
+ /* harmony export */
+ default: () => v
+ /* harmony export */
+ });
+ const v = `
+
+uniform mat4 modelViewMatrix;
+uniform mat4 projectionMatrix;
+uniform mat4 viewMatrix;
+uniform mat3 normalMatrix;
+uniform vec3 directionalLightColor[ 1 ];
+uniform vec3 directionalLightDirection[ 1 ];
+uniform vec3 outlineColor;
+uniform float outlineWidth;
+uniform float outlinePushback;
+
+
+attribute vec3 position;
+attribute vec3 normal;
+attribute vec3 color;
+attribute float radius;
+
+varying vec3 vColor;
+varying vec3 vLight;
+varying vec3 cposition;
+varying vec3 p1;
+varying vec3 p2;
+varying float r;
+
+void main() {
+
+ vColor = outlineColor;
+ float rad = radius+sign(radius)*outlineWidth;
+ r = abs(rad);
+ vec4 to = modelViewMatrix*vec4(normal, 1.0); //normal is other point of cylinder
+ vec4 pt = modelViewMatrix*vec4(position, 1.0);
+//pushback
+ to.xyz += normalize(to.xyz)*outlinePushback;
+ pt.xyz += normalize(pt.xyz)*outlinePushback;
+
+ vec4 mvPosition = pt;
+ p1 = pt.xyz; p2 = to.xyz;
+ vec3 norm = to.xyz-pt.xyz;
+ float mult = 1.1; //slop to account for perspective of sphere
+ if(length(p1) > length(p2)) { //billboard at level of closest point
+ mvPosition = to;
+ }
+ vec3 n = normalize(mvPosition.xyz);
+//intersect with the plane defined by the camera looking at the billboard point
+ if(color.z >= 0.0) { //p1
+ vec3 pnorm = normalize(p1);
+ float t = dot(mvPosition.xyz-p1,n)/dot(pnorm,n);
+ mvPosition.xyz = p1+t*pnorm;
+ } else {
+ vec3 pnorm = normalize(p2);
+ float t = dot(mvPosition.xyz-p2,n)/dot(pnorm,n);
+ mvPosition.xyz = p2+t*pnorm;
+ mult *= -1.0;
+ }
+ vec3 cr = normalize(cross(mvPosition.xyz,norm))*rad;
+ vec3 doublecr = normalize(cross(mvPosition.xyz,cr))*rad;
+ mvPosition.xy += mult*(cr + doublecr).xy;
+ cposition = mvPosition.xyz;
+ gl_Position = projectionMatrix * mvPosition;
+ vLight = vec3(1.0,1.0,1.0);
+}
+
+`;
+ }
+ ),
+ /***/
+ "./src/WebGL/shaders/lib/volumetric/volumetric.frag": (
+ /*!**********************************************************!*\
+ !*** ./src/WebGL/shaders/lib/volumetric/volumetric.frag ***!
+ \**********************************************************/
+ /***/
+ (P, _, s) => {
+ s.r(_), s.d(_, {
+ /* harmony export */
+ default: () => v
+ /* harmony export */
+ });
+ const v = `
+uniform highp sampler3D data;
+uniform highp sampler2D colormap;
+uniform highp sampler2D depthmap;
+
+
+uniform mat4 textmat;
+uniform mat4 projinv;
+uniform mat4 projectionMatrix;
+
+uniform float step;
+uniform float subsamples;
+uniform float maxdepth;
+uniform float transfermin;
+uniform float transfermax;
+in vec4 mvPosition;
+out vec4 color;
+void main(void) {
+
+ vec4 pos = mvPosition;
+ bool seengood = false;
+ float i = 0.0;
+ color = vec4(1,1,1,0);
+ float increment = 1.0/subsamples;
+ float maxsteps = (maxdepth*subsamples/step);
+//there's probably a better way to do this..
+//calculate farthest possible point in model coordinates
+ vec4 maxpos = vec4(pos.x,pos.y,pos.z-maxdepth,1.0);
+// convert to projection
+ maxpos = projectionMatrix*maxpos;
+ vec4 startp = projectionMatrix*pos;
+// homogonize
+ maxpos /= maxpos.w;
+ startp /= startp.w;
+//take x,y from start and z from max
+ maxpos = vec4(startp.x,startp.y,maxpos.z,1.0);
+//convert back to model space
+ maxpos = projinv*maxpos;
+ maxpos /= maxpos.w;
+ float incr = step/subsamples;
+//get depth from depthmap
+//startp is apparently [-1,1]
+ vec2 tpos = startp.xy/2.0+0.5;
+ float depth = texture(depthmap, tpos).r;
+//compute vector between start and end
+ vec4 direction = maxpos-pos;
+ for( i = 0.0; i <= maxsteps; i++) {
+ vec4 pt = (pos+(i/maxsteps)*direction);
+ vec4 ppt = projectionMatrix*pt;
+ float ptdepth = ppt.z/ppt.w;
+ ptdepth = ((gl_DepthRange.diff * ptdepth) + gl_DepthRange.near + gl_DepthRange.far) / 2.0;
+ if(ptdepth > depth) break;
+ pt = textmat*pt;
+// pt /= pt.w;
+ if(pt.x >= -0.01 && pt.y >= -0.01 && pt.z >= -0.01 && pt.x <= 1.01 && pt.y <= 1.01 && pt.z <= 1.01) {
+ seengood = true;
+ } else if(seengood) {
+ break;
+ }
+ if( pt.x < -0.01 || pt.x > 1.01 || pt.y < -0.01 || pt.y > 1.01 || pt.z < -0.01 || pt.z > 1.01 ){
+ color.a = 0.0;
+ continue;
+ }
+ else {
+ float val = texture(data, pt.zyx).r;
+ if(isinf(val)) continue; //masked out
+ float cval = (val-transfermin)/(transfermax-transfermin); //scale to texture 0-1 range
+ vec4 val_color = texture(colormap, vec2(cval,0.5));
+ color.rgb = color.rgb*color.a + (1.0-color.a)*val_color.a*val_color.rgb;
+ color.a += (1.0 - color.a) * val_color.a;
+ if(color.a > 0.0) color.rgb /= color.a;
+// color = vec4(pt.x, pt.y, pt.z, 1.0);
+ }
+// color = vec4(pt.x, pt.y, pt.z, 0.0)
+ }
+}
+
+ `;
+ }
+ ),
+ /***/
+ "./src/WebGL/shaders/lib/volumetric/volumetric.vert": (
+ /*!**********************************************************!*\
+ !*** ./src/WebGL/shaders/lib/volumetric/volumetric.vert ***!
+ \**********************************************************/
+ /***/
+ (P, _, s) => {
+ s.r(_), s.d(_, {
+ /* harmony export */
+ default: () => v
+ /* harmony export */
+ });
+ const v = `uniform mat4 modelViewMatrix;
+uniform mat4 projectionMatrix;
+uniform mat4 viewMatrix;
+
+in vec3 position;
+out vec4 mvPosition;
+void main() {
+
+ mvPosition = modelViewMatrix * vec4( position, 1.0 );
+ gl_Position = projectionMatrix*mvPosition;
+}
+`;
+ }
+ ),
+ /***/
+ "./src/WebGL/shaders/utils/stickimposterFragmentShader.partial.frag": (
+ /*!**************************************************************************!*\
+ !*** ./src/WebGL/shaders/utils/stickimposterFragmentShader.partial.frag ***!
+ \**************************************************************************/
+ /***/
+ (P, _, s) => {
+ s.r(_), s.d(_, {
+ /* harmony export */
+ default: () => v
+ /* harmony export */
+ });
+ const v = `uniform float opacity;
+uniform mat4 projectionMatrix;
+
+uniform vec3 fogColor;
+uniform float fogNear;
+uniform float fogFar;
+
+varying vec3 vLight;
+varying vec3 vColor;
+varying vec3 cposition;
+varying vec3 p1;
+varying vec3 p2;
+varying float r;
+
+//DEFINEFRAGCOLOR
+
+//cylinder-ray intersection testing taken from http://mrl.nyu.edu/~dzorin/cg05/lecture12.pdf
+//also useful: http://stackoverflow.com/questions/9595300/cylinder-impostor-in-glsl
+//with a bit more care (caps) this could be a general cylinder imposter (see also outline)
+void main() {
+ vec3 color = abs(vColor);
+ vec3 pos = cposition;
+ vec3 p = pos; //ray point
+ vec3 v = vec3(0.0,0.0,-1.0); //ray normal - orthographic
+ if(projectionMatrix[3][3] == 0.0) v = normalize(pos); //ray normal - perspective
+ vec3 pa = p1; //cyl start
+ vec3 va = normalize(p2-p1); //cyl norm
+ vec3 tmp1 = v-(dot(v,va)*va);
+ vec3 deltap = p-pa;
+ float A = dot(tmp1,tmp1);
+ if(A == 0.0) discard;
+ vec3 tmp2 = deltap-(dot(deltap,va)*va);
+ float B = 2.0*dot(tmp1, tmp2);
+ float C = dot(tmp2,tmp2)-r*r;
+//quadratic equation!
+ float det = (B*B) - (4.0*A*C);
+ if(det < 0.0) discard;
+ float sqrtDet = sqrt(det);
+ float posT = (-B+sqrtDet)/(2.0*A);
+ float negT = (-B-sqrtDet)/(2.0*A);
+ float intersectionT = min(posT,negT);
+ vec3 qi = p+v*intersectionT;
+ float dotp1 = dot(va,qi-p1);
+ float dotp2 = dot(va,qi-p2);
+ vec3 norm;
+ if( dotp1 < 0.0 || dotp2 > 0.0) { //(p-c)^2 + 2(p-c)vt +v^2+t^2 - r^2 = 0
+ vec3 cp;
+ if( dotp1 < 0.0) {
+// if(vColor.x < 0.0 ) discard; //color sign bit indicates if we should cap or not
+ cp = p1;
+ } else {
+// if(vColor.y < 0.0 ) discard;
+ cp = p2;
+ }
+ vec3 diff = p-cp;
+ A = dot(v,v);
+ B = dot(diff,v)*2.0;
+ C = dot(diff,diff)-r*r;
+ det = (B*B) - (4.0*C);
+ if(det < 0.0) discard;
+ sqrtDet = sqrt(det);
+ posT = (-B+sqrtDet)/(2.0);
+ negT = (-B-sqrtDet)/(2.0);
+ float t = min(posT,negT);
+ qi = p+v*t;
+ norm = normalize(qi-cp);
+ } else {
+ norm = normalize(qi-(dotp1*va + p1));
+ }
+ vec4 clipPos = projectionMatrix * vec4(qi, 1.0);
+ float ndcDepth = clipPos.z / clipPos.w;
+ float depth = ((gl_DepthRange.diff * ndcDepth) + gl_DepthRange.near + gl_DepthRange.far) / 2.0;
+ gl_FragDepthEXT = depth;`;
+ }
+ ),
+ /***/
+ "./src/GLDraw.ts": (
+ /*!***********************!*\
+ !*** ./src/GLDraw.ts ***!
+ \***********************/
+ /***/
+ (P, _, s) => {
+ s.r(_), s.d(_, {
+ /* harmony export */
+ CAP: () => (
+ /* binding */
+ M
+ ),
+ /* harmony export */
+ GLDraw: () => (
+ /* binding */
+ E
+ )
+ /* harmony export */
+ });
+ var v = s(
+ /*! ./WebGL/math */
+ "./src/WebGL/math/index.ts"
+ ), M;
+ (function(A) {
+ A[A.NONE = 0] = "NONE", A[A.FLAT = 1] = "FLAT", A[A.ROUND = 2] = "ROUND";
+ })(M || (M = {}));
+ var E;
+ (function(A) {
+ function h(t, r, u) {
+ var o = Math.hypot(t, r), l, e, n, a, p;
+ o < 1e-4 ? (e = 0, n = 1) : (e = -t / o, n = r / o), r = -e * t + n * r, l = Math.hypot(r, u), l < 1e-4 ? (a = 0, p = 1) : (a = u / l, p = r / l);
+ var x = new Float32Array(9);
+ return x[0] = n, x[1] = e, x[2] = 0, x[3] = -e * p, x[4] = n * p, x[5] = a, x[6] = e * a, x[7] = -n * a, x[8] = p, x;
+ }
+ class g {
+ constructor() {
+ this.cache = {};
+ let r = [], u = 4, o = Math.pow(2, u), l = 2, e = Math.pow(2, l), n = o / e, a;
+ for (r[0] = new v.Vector3(-1, 0, 0), r[n] = new v.Vector3(0, 0, 1), r[n * 2] = new v.Vector3(1, 0, 0), r[n * 3] = new v.Vector3(0, 0, -1), l = 3; l <= u; l++) {
+ for (e = Math.pow(2, l - 1), n = o / e, a = 0; a < e - 1; a++)
+ r[n / 2 + a * n] = r[a * n].clone().add(r[(a + 1) * n]).normalize();
+ a = e - 1, r[n / 2 + a * n] = r[a * n].clone().add(r[0]).normalize();
+ }
+ this.basisVectors = r;
+ }
+ getVerticesForRadius(r, u, o) {
+ if (typeof this.cache < "u" && this.cache[r] !== void 0 && this.cache[r][u + o] !== void 0)
+ return this.cache[r][u + o];
+ for (var l = this.basisVectors.length, e = [], n = [], a, p = 0; p < l; p++)
+ e.push(this.basisVectors[p].clone().multiplyScalar(r)), e.push(this.basisVectors[p].clone().multiplyScalar(r)), a = this.basisVectors[p].clone().normalize(), n.push(a), n.push(a);
+ var x = [], D = 10, O = l, R = 0, z = Math.PI * 2, T = 0, B = Math.PI, W, k, F = !1, U = !1;
+ for (k = 0; k <= D; k++) {
+ F = k === 0 || k === D, U = k === D / 2;
+ var V = [], H = [];
+ for (W = 0; W <= O; W++) {
+ if (U) {
+ var G = W < O ? 2 * W : 0;
+ H.push(G + 1), V.push(G);
+ continue;
+ }
+ var Y = W / O, J = k / D;
+ if (!F || W === 0)
+ if (W < O) {
+ var re = new v.Vector3();
+ re.x = -r * Math.cos(R + Y * z) * Math.sin(T + J * B), u == 1 ? re.y = 0 : re.y = r * Math.cos(T + J * B), re.z = r * Math.sin(R + Y * z) * Math.sin(T + J * B), Math.abs(re.x) < 1e-5 && (re.x = 0), Math.abs(re.y) < 1e-5 && (re.y = 0), Math.abs(re.z) < 1e-5 && (re.z = 0), u == M.FLAT ? (a = new v.Vector3(0, Math.cos(T + J * B), 0), a.normalize()) : (a = new v.Vector3(re.x, re.y, re.z), a.normalize()), e.push(re), n.push(a), V.push(e.length - 1);
+ } else
+ V.push(e.length - O);
+ else
+ F && V.push(e.length - 1);
+ }
+ U && x.push(H), x.push(V);
+ }
+ var le = {
+ vertices: e,
+ normals: n,
+ verticesRows: x,
+ w: O,
+ h: D
+ };
+ return r in this.cache || (this.cache[r] = {}), this.cache[r][u + o] = le, le;
+ }
+ }
+ var C = new g();
+ function c(t, r, u, o, l, e = 0, n = 0) {
+ if (!(!r || !u)) {
+ var a = n || e;
+ l = l || { r: 0, g: 0, b: 0 };
+ var p = h(u.x - r.x, u.y - r.y, u.z - r.z), x = C.getVerticesForRadius(o, n, "to"), D = x.w, O = x.h, R = a ? O * D + 2 : 2 * D, z = t.updateGeoGroup(R), T = x.vertices, B = x.normals, W = x.verticesRows, k = W[O / 2], F = W[O / 2 + 1], U = z.vertices, V, H, G, Y, J, re, le = z.vertexArray, ie = z.normalArray, xe = z.colorArray, se = z.faceArray;
+ for (G = 0; G < D; ++G) {
+ var ce = 2 * G;
+ Y = p[0] * T[ce].x + p[3] * T[ce].y + p[6] * T[ce].z, J = p[1] * T[ce].x + p[4] * T[ce].y + p[7] * T[ce].z, re = p[5] * T[ce].y + p[8] * T[ce].z, V = 3 * (U + ce), H = z.faceidx, le[V] = Y + r.x, le[V + 1] = J + r.y, le[V + 2] = re + r.z, le[V + 3] = Y + u.x, le[V + 4] = J + u.y, le[V + 5] = re + u.z, ie[V] = Y, ie[V + 3] = Y, ie[V + 1] = J, ie[V + 4] = J, ie[V + 2] = re, ie[V + 5] = re, xe[V] = l.r, xe[V + 3] = l.r, xe[V + 1] = l.g, xe[V + 4] = l.g, xe[V + 2] = l.b, xe[V + 5] = l.b, se[H] = F[G] + U, se[H + 1] = F[G + 1] + U, se[H + 2] = k[G] + U, se[H + 3] = k[G] + U, se[H + 4] = F[G + 1] + U, se[H + 5] = k[G + 1] + U, z.faceidx += 6;
+ }
+ if (a) {
+ var Ee = n ? 0 : O / 2, be = e ? O + 1 : O / 2 + 1, Le, ae, pe, we, Ge, We, je, Fe, ze, Be, Ie, Te, Re, ke, Ne, X, K, q, fe, ue, De, Se, Z, de, me, Pe, oe, Ce, j, Oe, He, I;
+ for (J = Ee; J < be; J++)
+ if (J !== O / 2) {
+ var ge = J <= O / 2 ? u : r, ve = C.getVerticesForRadius(o, n, "to"), $ = C.getVerticesForRadius(o, e, "from");
+ for (ge === u ? (T = ve.vertices, B = ve.normals, W = ve.verticesRows) : ge == r && (T = $.vertices, B = $.normals, W = $.verticesRows), Y = 0; Y < D; Y++)
+ H = z.faceidx, Le = W[J][Y + 1], j = (Le + U) * 3, ae = W[J][Y], Oe = (ae + U) * 3, pe = W[J + 1][Y], He = (pe + U) * 3, we = W[J + 1][Y + 1], I = (we + U) * 3, Ge = p[0] * T[Le].x + p[3] * T[Le].y + p[6] * T[Le].z, We = p[0] * T[ae].x + p[3] * T[ae].y + p[6] * T[ae].z, je = p[0] * T[pe].x + p[3] * T[pe].y + p[6] * T[pe].z, Fe = p[0] * T[we].x + p[3] * T[we].y + p[6] * T[we].z, ze = p[1] * T[Le].x + p[4] * T[Le].y + p[7] * T[Le].z, Be = p[1] * T[ae].x + p[4] * T[ae].y + p[7] * T[ae].z, Ie = p[1] * T[pe].x + p[4] * T[pe].y + p[7] * T[pe].z, Te = p[1] * T[we].x + p[4] * T[we].y + p[7] * T[we].z, Re = p[5] * T[Le].y + p[8] * T[Le].z, ke = p[5] * T[ae].y + p[8] * T[ae].z, Ne = p[5] * T[pe].y + p[8] * T[pe].z, X = p[5] * T[we].y + p[8] * T[we].z, le[j] = Ge + ge.x, le[Oe] = We + ge.x, le[He] = je + ge.x, le[I] = Fe + ge.x, le[j + 1] = ze + ge.y, le[Oe + 1] = Be + ge.y, le[He + 1] = Ie + ge.y, le[I + 1] = Te + ge.y, le[j + 2] = Re + ge.z, le[Oe + 2] = ke + ge.z, le[He + 2] = Ne + ge.z, le[I + 2] = X + ge.z, xe[j] = l.r, xe[Oe] = l.r, xe[He] = l.r, xe[I] = l.r, xe[j + 1] = l.g, xe[Oe + 1] = l.g, xe[He + 1] = l.g, xe[I + 1] = l.g, xe[j + 2] = l.b, xe[Oe + 2] = l.b, xe[He + 2] = l.b, xe[I + 2] = l.b, K = p[0] * B[Le].x + p[3] * B[Le].y + p[6] * B[Le].z, q = p[0] * B[ae].x + p[3] * B[ae].y + p[6] * B[ae].z, fe = p[0] * B[pe].x + p[3] * B[pe].y + p[6] * B[pe].z, ue = p[0] * B[we].x + p[3] * B[we].y + p[6] * B[we].z, De = p[1] * B[Le].x + p[4] * B[Le].y + p[7] * B[Le].z, Se = p[1] * B[ae].x + p[4] * B[ae].y + p[7] * B[ae].z, Z = p[1] * B[pe].x + p[4] * B[pe].y + p[7] * B[pe].z, de = p[1] * B[we].x + p[4] * B[we].y + p[7] * B[we].z, me = p[5] * B[Le].y + p[8] * B[Le].z, Pe = p[5] * B[ae].y + p[8] * B[ae].z, oe = p[5] * B[pe].y + p[8] * B[pe].z, Ce = p[5] * B[we].y + p[8] * B[we].z, J === 0 ? (ie[j] = K, ie[He] = fe, ie[I] = ue, ie[j + 1] = De, ie[He + 1] = Z, ie[I + 1] = de, ie[j + 2] = me, ie[He + 2] = oe, ie[I + 2] = Ce, se[H] = Le + U, se[H + 1] = pe + U, se[H + 2] = we + U, z.faceidx += 3) : J === be - 1 ? (ie[j] = K, ie[Oe] = q, ie[He] = fe, ie[j + 1] = De, ie[Oe + 1] = Se, ie[He + 1] = Z, ie[j + 2] = me, ie[Oe + 2] = Pe, ie[He + 2] = oe, se[H] = Le + U, se[H + 1] = ae + U, se[H + 2] = pe + U, z.faceidx += 3) : (ie[j] = K, ie[Oe] = q, ie[I] = ue, ie[j + 1] = De, ie[Oe + 1] = Se, ie[I + 1] = de, ie[j + 2] = me, ie[Oe + 2] = Pe, ie[I + 2] = Ce, ie[Oe] = q, ie[He] = fe, ie[I] = ue, ie[Oe + 1] = Se, ie[He + 1] = Z, ie[I + 1] = de, ie[Oe + 2] = Pe, ie[He + 2] = oe, ie[I + 2] = Ce, se[H] = Le + U, se[H + 1] = ae + U, se[H + 2] = we + U, se[H + 3] = ae + U, se[H + 4] = pe + U, se[H + 5] = we + U, z.faceidx += 6);
+ }
+ }
+ z.vertices += R;
+ }
+ }
+ A.drawCylinder = c;
+ function S(t, r, u, o, l) {
+ if (!r || !u)
+ return;
+ l = l || { r: 0, g: 0, b: 0 };
+ let e = new v.Vector3(u.x - r.x, u.y - r.y, u.z - r.z);
+ var n = h(e.x, e.y, e.z);
+ e = e.normalize();
+ var a = C.basisVectors.length, p = C.basisVectors, x = a + 2, D = t.updateGeoGroup(x), O = D.vertices, R, z, T, B, W, k, F = D.vertexArray, U = D.normalArray, V = D.colorArray, H = D.faceArray;
+ for (R = O * 3, F[R] = r.x, F[R + 1] = r.y, F[R + 2] = r.z, U[R] = -e.x, U[R + 1] = -e.y, U[R + 2] = -e.z, V[R] = l.r, V[R + 1] = l.g, V[R + 2] = l.b, F[R + 3] = u.x, F[R + 4] = u.y, F[R + 5] = u.z, U[R + 3] = e.x, U[R + 4] = e.y, U[R + 5] = e.z, V[R + 3] = l.r, V[R + 4] = l.g, V[R + 5] = l.b, R += 6, T = 0; T < a; ++T) {
+ var G = p[T].clone();
+ G.multiplyScalar(o), B = n[0] * G.x + n[3] * G.y + n[6] * G.z, W = n[1] * G.x + n[4] * G.y + n[7] * G.z, k = n[5] * G.y + n[8] * G.z, F[R] = B + r.x, F[R + 1] = W + r.y, F[R + 2] = k + r.z, U[R] = B, U[R + 1] = W, U[R + 2] = k, V[R] = l.r, V[R + 1] = l.g, V[R + 2] = l.b, R += 3;
+ }
+ for (D.vertices += a + 2, z = D.faceidx, T = 0; T < a; T++) {
+ var Y = O + 2 + T, J = O + 2 + (T + 1) % a;
+ H[z] = Y, H[z + 1] = J, H[z + 2] = O, z += 3, H[z] = Y, H[z + 1] = J, H[z + 2] = O + 1, z += 3;
+ }
+ D.faceidx += 6 * a;
+ }
+ A.drawCone = S;
+ class y {
+ constructor() {
+ this.cache = /* @__PURE__ */ new Map();
+ }
+ getVerticesForRadius(r, u) {
+ u = u || 2, this.cache.has(u) || this.cache.set(u, /* @__PURE__ */ new Map());
+ let o = this.cache.get(u);
+ if (o.has(r))
+ return o.get(r);
+ var l = {
+ vertices: [],
+ verticesRows: [],
+ normals: []
+ }, e = 16 * u, n = 10 * u;
+ r < 1 && (e = 10 * u, n = 8 * u);
+ var a = 0, p = Math.PI * 2, x = 0, D = Math.PI, O, R;
+ for (R = 0; R <= n; R++) {
+ let T = [];
+ for (O = 0; O <= e; O++) {
+ let B = O / e, W = R / n, k = -r * Math.cos(a + B * p) * Math.sin(x + W * D), F = r * Math.cos(x + W * D), U = r * Math.sin(a + B * p) * Math.sin(x + W * D);
+ var z = new v.Vector3(k, F, U);
+ z.normalize(), l.vertices.push({ x: k, y: F, z: U }), l.normals.push(z), T.push(l.vertices.length - 1);
+ }
+ l.verticesRows.push(T);
+ }
+ return o.set(r, l), l;
+ }
+ }
+ var b = new y();
+ function w(t, r, u, o, l) {
+ var e = b.getVerticesForRadius(u, l), n = e.vertices, a = e.normals, p = t.updateGeoGroup(n.length), x = p.vertices, D = p.vertexArray, O = p.colorArray, R = p.faceArray, z = p.lineArray, T = p.normalArray;
+ for (let k = 0, F = n.length; k < F; ++k) {
+ let U = 3 * (x + k), V = n[k];
+ D[U] = V.x + r.x, D[U + 1] = V.y + r.y, D[U + 2] = V.z + r.z, O[U] = o.r, O[U + 1] = o.g, O[U + 2] = o.b;
+ }
+ p.vertices += n.length;
+ let B = e.verticesRows, W = B.length - 1;
+ for (let k = 0; k < W; k++) {
+ let F = B[k].length - 1;
+ for (let U = 0; U < F; U++) {
+ let V = p.faceidx, H = p.lineidx, G = B[k][U + 1] + x, Y = G * 3, J = B[k][U] + x, re = J * 3, le = B[k + 1][U] + x, ie = le * 3, xe = B[k + 1][U + 1] + x, se = xe * 3, ce = a[G - x], Ee = a[J - x], be = a[le - x], Le = a[xe - x];
+ Math.abs(n[G - x].y) === u ? (T[Y] = ce.x, T[ie] = be.x, T[se] = Le.x, T[Y + 1] = ce.y, T[ie + 1] = be.y, T[se + 1] = Le.y, T[Y + 2] = ce.z, T[ie + 2] = be.z, T[se + 2] = Le.z, R[V] = G, R[V + 1] = le, R[V + 2] = xe, z[H] = G, z[H + 1] = le, z[H + 2] = G, z[H + 3] = xe, z[H + 4] = le, z[H + 5] = xe, p.faceidx += 3, p.lineidx += 6) : Math.abs(n[le - x].y) === u ? (T[Y] = ce.x, T[re] = Ee.x, T[ie] = be.x, T[Y + 1] = ce.y, T[re + 1] = Ee.y, T[ie + 1] = be.y, T[Y + 2] = ce.z, T[re + 2] = Ee.z, T[ie + 2] = be.z, R[V] = G, R[V + 1] = J, R[V + 2] = le, z[H] = G, z[H + 1] = J, z[H + 2] = G, z[H + 3] = le, z[H + 4] = J, z[H + 5] = le, p.faceidx += 3, p.lineidx += 6) : (T[Y] = ce.x, T[re] = Ee.x, T[se] = Le.x, T[Y + 1] = ce.y, T[re + 1] = Ee.y, T[se + 1] = Le.y, T[Y + 2] = ce.z, T[re + 2] = Ee.z, T[se + 2] = Le.z, T[re] = Ee.x, T[ie] = be.x, T[se] = Le.x, T[re + 1] = Ee.y, T[ie + 1] = be.y, T[se + 1] = Le.y, T[re + 2] = Ee.z, T[ie + 2] = be.z, T[se + 2] = Le.z, R[V] = G, R[V + 1] = J, R[V + 2] = xe, R[V + 3] = J, R[V + 4] = le, R[V + 5] = xe, z[H] = G, z[H + 1] = J, z[H + 2] = G, z[H + 3] = xe, z[H + 4] = J, z[H + 5] = le, z[H + 6] = le, z[H + 7] = xe, p.faceidx += 6, p.lineidx += 8);
+ }
+ }
+ }
+ A.drawSphere = w;
+ })(E || (E = {}));
+ }
+ ),
+ /***/
+ "./src/GLModel.ts": (
+ /*!************************!*\
+ !*** ./src/GLModel.ts ***!
+ \************************/
+ /***/
+ (P, _, s) => {
+ s.r(_), s.d(_, {
+ /* harmony export */
+ GLModel: () => (
+ /* binding */
+ r
+ )
+ /* harmony export */
+ });
+ var v = s(
+ /*! ./WebGL */
+ "./src/WebGL/index.ts"
+ ), M = s(
+ /*! ./WebGL/shapes */
+ "./src/WebGL/shapes/index.ts"
+ ), E = s(
+ /*! ./WebGL/math */
+ "./src/WebGL/math/index.ts"
+ ), A = s(
+ /*! ./colors */
+ "./src/colors.ts"
+ ), h = s(
+ /*! ./GLDraw */
+ "./src/GLDraw.ts"
+ ), g = s(
+ /*! ./glcartoon */
+ "./src/glcartoon.ts"
+ ), C = s(
+ /*! ./utilities */
+ "./src/utilities.ts"
+ ), c = s(
+ /*! ./Gradient */
+ "./src/Gradient.ts"
+ ), S = s(
+ /*! ./parsers */
+ "./src/parsers/index.ts"
+ ), y = s(
+ /*! netcdfjs */
+ "./node_modules/netcdfjs/lib-esm/index.js"
+ ), b = s(
+ /*! pako */
+ "./node_modules/pako/dist/pako.esm.mjs"
+ ), w = s(
+ /*! ./parsers/utils/assignBonds */
+ "./src/parsers/utils/assignBonds.ts"
+ );
+ function t(u) {
+ let o;
+ return typeof u == "string" ? o = new TextEncoder().encode(u) : o = new Uint8Array(u), (0, b.inflate)(o, {
+ to: "string"
+ });
+ }
+ class r {
+ // class functions
+ // return true if a and b represent the same style
+ static sameObj(o, l) {
+ return o && l ? JSON.stringify(o) == JSON.stringify(l) : o == l;
+ }
+ constructor(o, l) {
+ this.atoms = [], this.frames = [], this.box = null, this.atomdfs = null, this.id = 0, this.hidden = !1, this.molObj = null, this.renderedMolObj = null, this.lastColors = null, this.modelData = {}, this.modelDatas = null, this.idMatrix = new E.Matrix4(), this.dontDuplicateAtoms = !0, this.defaultColor = A.elementColors.defaultColor, this.defaultStickRadius = 0.25, this.options = l || {}, this.ElementColors = this.options.defaultcolors ? this.options.defaultcolors : A.elementColors.defaultColors, this.defaultSphereRadius = this.options.defaultSphereRadius ? this.options.defaultSphereRadius : 1.5, this.defaultCartoonQuality = this.options.cartoonQuality ? this.options.cartoonQuality : 10, this.id = o;
+ }
+ // return proper radius for atom given style
+ /**
+ *
+ * @param {AtomSpec} atom
+ * @param {atomstyle} style
+ * @return {number}
+ *
+ */
+ getRadiusFromStyle(o, l) {
+ var e = this.defaultSphereRadius;
+ if (typeof l.radius < "u")
+ e = l.radius;
+ else if (r.vdwRadii[o.elem])
+ e = r.vdwRadii[o.elem];
+ else if (o.elem.length > 1) {
+ let n = o.elem;
+ n = n[0].toUpperCase() + n[1].toLowerCase(), r.vdwRadii[n] && (e = r.vdwRadii[n]);
+ }
+ return typeof l.scale < "u" && (e *= l.scale), e;
+ }
+ // cross drawing
+ /**
+ *
+ * @param {AtomSpec} atom
+ * @param {Record} geos
+ */
+ drawAtomCross(o, l) {
+ if (o.style.cross) {
+ var e = o.style.cross;
+ if (!e.hidden) {
+ var n = e.linewidth || r.defaultlineWidth;
+ l[n] || (l[n] = new v.Geometry());
+ var a = l[n].updateGeoGroup(6), p = this.getRadiusFromStyle(o, e), x = [
+ [p, 0, 0],
+ [-p, 0, 0],
+ [0, p, 0],
+ [0, -p, 0],
+ [0, 0, p],
+ [0, 0, -p]
+ ], D = o.clickable || o.hoverable;
+ D && o.intersectionShape === void 0 && (o.intersectionShape = { sphere: [], cylinder: [], line: [] });
+ for (var O = (0, C.getColorFromStyle)(o, e), R = a.vertexArray, z = a.colorArray, T = 0; T < 6; T++) {
+ var B = a.vertices * 3;
+ if (a.vertices++, R[B] = o.x + x[T][0], R[B + 1] = o.y + x[T][1], R[B + 2] = o.z + x[T][2], z[B] = O.r, z[B + 1] = O.g, z[B + 2] = O.b, D) {
+ var W = new E.Vector3(x[T][0], x[T][1], x[T][2]);
+ W.multiplyScalar(0.1), W.set(W.x + o.x, W.y + o.y, W.z + o.z), o.intersectionShape.line.push(W);
+ }
+ }
+ }
+ }
+ }
+ getGoodCross(o, l, e, n) {
+ for (var a = null, p = -1, x = 0, D = o.bonds.length; x < D; x++)
+ if (o.bonds[x] != l.index) {
+ let R = o.bonds[x], z = this.atoms[R], B = new E.Vector3(z.x, z.y, z.z).clone();
+ B.sub(e);
+ let W = B.clone();
+ W.cross(n);
+ var O = W.lengthSq();
+ if (O > p && (p = O, a = W, p > 0.1))
+ return a;
+ }
+ return a;
+ }
+ //from atom, return a normalized vector v that is orthogonal and along which
+ //it is appropraite to draw multiple bonds
+ getSideBondV(o, l, e) {
+ var n, a, p, x, D, O = new E.Vector3(o.x, o.y, o.z), R = new E.Vector3(l.x, l.y, l.z), z = R.clone(), T = null;
+ if (z.sub(O), o.bonds.length === 1)
+ l.bonds.length === 1 ? (T = z.clone(), Math.abs(T.x) > 1e-4 ? T.y += 1 : T.x += 1) : (n = (e + 1) % l.bonds.length, a = l.bonds[n], p = this.atoms[a], x = new E.Vector3(p.x, p.y, p.z), D = x.clone(), D.sub(O), T = D.clone(), T.cross(z));
+ else if (T = this.getGoodCross(o, l, O, z), T.lengthSq() < 0.01) {
+ var B = this.getGoodCross(l, o, O, z);
+ B != null && (T = B);
+ }
+ return T.lengthSq() < 0.01 && (T = z.clone(), Math.abs(T.x) > 1e-4 ? T.y += 1 : T.x += 1), T.cross(z), T.normalize(), T;
+ }
+ addLine(o, l, e, n, a, p) {
+ o[e] = n.x, o[e + 1] = n.y, o[e + 2] = n.z, l[e] = p.r, l[e + 1] = p.g, l[e + 2] = p.b, o[e + 3] = a.x, o[e + 4] = a.y, o[e + 5] = a.z, l[e + 3] = p.r, l[e + 4] = p.g, l[e + 5] = p.b;
+ }
+ // bonds - both atoms must match bond style
+ // standardize on only drawing for lowest to highest
+ /**
+ *
+ * @param {AtomSpec}
+ * atom
+ * @param {AtomSpec[]} atoms
+ * @param {Record} geos
+ */
+ drawBondLines(o, l, e) {
+ if (o.style.line) {
+ var n = o.style.line;
+ if (!n.hidden) {
+ var a, p, x, D, O = n.linewidth || r.defaultlineWidth;
+ e[O] || (e[O] = new v.Geometry());
+ for (var R = e[O].updateGeoGroup(6 * o.bonds.length), z = R.vertexArray, T = R.colorArray, B = 0; B < o.bonds.length; B++) {
+ var W = o.bonds[B], k = l[W];
+ if (k.style.line && !(o.index >= k.index)) {
+ var F = new E.Vector3(o.x, o.y, o.z), U = new E.Vector3(k.x, k.y, k.z), V = F.clone().add(U).multiplyScalar(0.5), H = !1, G = o.clickable || o.hoverable, Y = k.clickable || k.hoverable;
+ (G || Y) && (G && (o.intersectionShape === void 0 && (o.intersectionShape = { sphere: [], cylinder: [], line: [], triangle: [] }), o.intersectionShape.line.push(F), o.intersectionShape.line.push(V)), Y && (k.intersectionShape === void 0 && (k.intersectionShape = { sphere: [], cylinder: [], line: [], triangle: [] }), k.intersectionShape.line.push(V), k.intersectionShape.line.push(U)));
+ var J = (0, C.getColorFromStyle)(o, o.style.line), re = (0, C.getColorFromStyle)(k, k.style.line);
+ if (o.bondStyles && o.bondStyles[B]) {
+ var le = o.bondStyles[B];
+ if (!le.iswire)
+ continue;
+ le.singleBond && (H = !0), typeof le.color1 < "u" && (J = A.CC.color(le.color1)), typeof le.color2 < "u" && (re = A.CC.color(le.color2));
+ }
+ var ie = R.vertices * 3, xe, se;
+ if (o.bondOrder[B] > 1 && o.bondOrder[B] < 4 && !H) {
+ var ce = this.getSideBondV(o, k, B), Ee = U.clone();
+ Ee.sub(F), o.bondOrder[B] == 2 ? (ce.multiplyScalar(0.1), a = F.clone(), a.add(ce), p = F.clone(), p.sub(ce), x = a.clone(), x.add(Ee), D = p.clone(), D.add(Ee), J == re ? (R.vertices += 4, this.addLine(z, T, ie, a, x, J), this.addLine(z, T, ie + 6, p, D, J)) : (R.vertices += 8, Ee.multiplyScalar(0.5), xe = a.clone(), xe.add(Ee), se = p.clone(), se.add(Ee), this.addLine(z, T, ie, a, xe, J), this.addLine(z, T, ie + 6, xe, x, re), this.addLine(z, T, ie + 12, p, se, J), this.addLine(z, T, ie + 18, se, D, re))) : o.bondOrder[B] == 3 && (ce.multiplyScalar(0.1), a = F.clone(), a.add(ce), p = F.clone(), p.sub(ce), x = a.clone(), x.add(Ee), D = p.clone(), D.add(Ee), J == re ? (R.vertices += 6, this.addLine(z, T, ie, F, U, J), this.addLine(z, T, ie + 6, a, x, J), this.addLine(z, T, ie + 12, p, D, J)) : (R.vertices += 12, Ee.multiplyScalar(0.5), xe = a.clone(), xe.add(Ee), se = p.clone(), se.add(Ee), this.addLine(z, T, ie, F, V, J), this.addLine(z, T, ie + 6, V, U, re), this.addLine(z, T, ie + 12, a, xe, J), this.addLine(z, T, ie + 18, xe, x, re), this.addLine(z, T, ie + 24, p, se, J), this.addLine(z, T, ie + 30, se, D, re)));
+ } else
+ J == re ? (R.vertices += 2, this.addLine(z, T, ie, F, U, J)) : (R.vertices += 4, this.addLine(z, T, ie, F, V, J), this.addLine(z, T, ie + 6, V, U, re));
+ }
+ }
+ }
+ }
+ }
+ //sphere drawing
+ //See also: drawCylinder
+ /**
+ *
+ * @param {AtomSpec} atom
+ * @param {Geometry} geo
+ */
+ drawAtomSphere(o, l) {
+ if (o.style.sphere) {
+ var e = o.style.sphere;
+ if (!e.hidden) {
+ var n = (0, C.getColorFromStyle)(o, e), a = this.getRadiusFromStyle(o, e);
+ if ((o.clickable === !0 || o.hoverable) && o.intersectionShape !== void 0) {
+ var p = new E.Vector3(o.x, o.y, o.z);
+ o.intersectionShape.sphere.push(new M.Sphere(p, a));
+ }
+ h.GLDraw.drawSphere(l, o, a, n);
+ }
+ }
+ }
+ /** Register atom shaped click handlers */
+ drawAtomClickSphere(o) {
+ if (o.style.clicksphere) {
+ var l = o.style.clicksphere;
+ if (!l.hidden) {
+ var e = this.getRadiusFromStyle(o, l);
+ if ((o.clickable === !0 || o.hoverable) && o.intersectionShape !== void 0) {
+ var n = new E.Vector3(o.x, o.y, o.z);
+ o.intersectionShape.sphere.push(new M.Sphere(n, e));
+ }
+ }
+ }
+ }
+ drawAtomInstanced(o, l) {
+ if (o.style.sphere) {
+ var e = o.style.sphere;
+ if (!e.hidden) {
+ var n = this.getRadiusFromStyle(o, e), a = (0, C.getColorFromStyle)(o, e), p = l.updateGeoGroup(1), x = p.vertices, D = x * 3, O = p.vertexArray, R = p.colorArray, z = p.radiusArray;
+ if (O[D] = o.x, O[D + 1] = o.y, O[D + 2] = o.z, R[D] = a.r, R[D + 1] = a.g, R[D + 2] = a.b, z[x] = n, (o.clickable === !0 || o.hoverable) && o.intersectionShape !== void 0) {
+ var T = new E.Vector3(o.x, o.y, o.z);
+ o.intersectionShape.sphere.push(new M.Sphere(T, n));
+ }
+ p.vertices += 1;
+ }
+ }
+ }
+ drawSphereImposter(o, l, e, n) {
+ var a = o.updateGeoGroup(4), p, x = a.vertices, D = x * 3, O = a.vertexArray, R = a.colorArray;
+ for (p = 0; p < 4; p++)
+ O[D + 3 * p] = l.x, O[D + 3 * p + 1] = l.y, O[D + 3 * p + 2] = l.z;
+ var z = a.normalArray;
+ for (p = 0; p < 4; p++)
+ R[D + 3 * p] = n.r, R[D + 3 * p + 1] = n.g, R[D + 3 * p + 2] = n.b;
+ z[D + 0] = -e, z[D + 1] = e, z[D + 2] = 0, z[D + 3] = -e, z[D + 4] = -e, z[D + 5] = 0, z[D + 6] = e, z[D + 7] = -e, z[D + 8] = 0, z[D + 9] = e, z[D + 10] = e, z[D + 11] = 0, a.vertices += 4;
+ var T = a.faceArray, B = a.faceidx;
+ T[B + 0] = x, T[B + 1] = x + 1, T[B + 2] = x + 2, T[B + 3] = x + 2, T[B + 4] = x + 3, T[B + 5] = x, a.faceidx += 6;
+ }
+ //dkoes - code for sphere imposters
+ drawAtomImposter(o, l) {
+ if (o.style.sphere) {
+ var e = o.style.sphere;
+ if (!e.hidden) {
+ var n = this.getRadiusFromStyle(o, e), a = (0, C.getColorFromStyle)(o, e);
+ if ((o.clickable === !0 || o.hoverable) && o.intersectionShape !== void 0) {
+ var p = new E.Vector3(o.x, o.y, o.z);
+ o.intersectionShape.sphere.push(new M.Sphere(p, n));
+ }
+ this.drawSphereImposter(l, o, n, a);
+ }
+ }
+ }
+ static drawStickImposter(o, l, e, n, a) {
+ for (var p = o.updateGeoGroup(4), x = p.vertices, D = x * 3, O = p.vertexArray, R = p.colorArray, z = p.radiusArray, T = p.normalArray, B = a.r, W = a.g, k = a.b, F = function(Y) {
+ var J = -Y;
+ return J == 0 && (J = -1e-4), J;
+ }, U = D, V = 0; V < 4; V++)
+ O[U] = l.x, T[U] = e.x, R[U] = B, U++, O[U] = l.y, T[U] = e.y, R[U] = W, U++, O[U] = l.z, T[U] = e.z, V < 2 ? R[U] = k : R[U] = F(k), U++;
+ p.vertices += 4, z[x] = -n, z[x + 1] = n, z[x + 2] = -n, z[x + 3] = n;
+ var H = p.faceArray, G = p.faceidx;
+ H[G + 0] = x, H[G + 1] = x + 1, H[G + 2] = x + 2, H[G + 3] = x + 2, H[G + 4] = x + 3, H[G + 5] = x, p.faceidx += 6;
+ }
+ // draws cylinders and small spheres (at bond radius)
+ drawBondSticks(o, l, e) {
+ if (o.style.stick) {
+ var n = o.style.stick;
+ if (!n.hidden) {
+ var a = n.radius || this.defaultStickRadius, p = n.doubleBondScaling || 0.4, x = n.tripleBondScaling || 0.25, D = a, O = n.singleBonds || !1, R = 0, z = 0, T, B, W, k, F, U, V, H, G, Y, J, re = (0, C.getColorFromStyle)(o, n), le, ie, xe;
+ !o.capDrawn && o.bonds.length < 4 && (R = 2);
+ var se = h.GLDraw.drawCylinder;
+ for (e.imposter && (se = r.drawStickImposter), W = 0; W < o.bonds.length; W++) {
+ var ce = o.bonds[W], Ee = l[ce];
+ if (le = ie = xe = null, o.index < Ee.index) {
+ var be = Ee.style;
+ if (!be.stick || be.stick.hidden)
+ continue;
+ var Le = (0, C.getColorFromStyle)(Ee, be.stick);
+ if (D = a, k = O, o.bondStyles && o.bondStyles[W]) {
+ if (F = o.bondStyles[W], F.iswire)
+ continue;
+ F.radius && (D = F.radius), F.singleBond && (k = !0), typeof F.color1 < "u" && (re = A.CC.color(F.color1)), typeof F.color2 < "u" && (Le = A.CC.color(F.color2));
+ }
+ var ae = new E.Vector3(o.x, o.y, o.z), pe = new E.Vector3(Ee.x, Ee.y, Ee.z);
+ if (o.bondOrder[W] <= 1 || k || o.bondOrder[W] > 3) {
+ if (o.bondOrder[W] < 1 && (D *= o.bondOrder[W]), !Ee.capDrawn && Ee.bonds.length < 4 && (z = 2), re != Le ? (le = new E.Vector3().addVectors(ae, pe).multiplyScalar(0.5), se(e, ae, le, D, re, R, 0), se(e, le, pe, D, Le, 0, z)) : se(e, ae, pe, D, re, R, z), T = o.clickable || o.hoverable, B = Ee.clickable || Ee.hoverable, T || B) {
+ if (le || (le = new E.Vector3().addVectors(ae, pe).multiplyScalar(0.5)), T) {
+ var we = new M.Cylinder(ae, le, D), Ge = new M.Sphere(ae, D);
+ o.intersectionShape.cylinder.push(we), o.intersectionShape.sphere.push(Ge);
+ }
+ if (B) {
+ var We = new M.Cylinder(pe, le, D), je = new M.Sphere(pe, D);
+ Ee.intersectionShape.cylinder.push(We), Ee.intersectionShape.sphere.push(je);
+ }
+ }
+ } else if (o.bondOrder[W] > 1) {
+ var Fe = 0, ze = 0;
+ D != a && (Fe = 2, ze = 2);
+ var Be = pe.clone(), Ie = null;
+ Be.sub(ae);
+ var Te, Re, ke, Ne, X;
+ Ie = this.getSideBondV(o, Ee, W), o.bondOrder[W] == 2 ? (Te = D * p, Ie.multiplyScalar(Te * 1.5), Re = ae.clone(), Re.add(Ie), ke = ae.clone(), ke.sub(Ie), Ne = Re.clone(), Ne.add(Be), X = ke.clone(), X.add(Be), re != Le ? (le = new E.Vector3().addVectors(Re, Ne).multiplyScalar(0.5), ie = new E.Vector3().addVectors(ke, X).multiplyScalar(0.5), se(e, Re, le, Te, re, Fe, 0), se(e, le, Ne, Te, Le, 0, ze), se(e, ke, ie, Te, re, Fe, 0), se(e, ie, X, Te, Le, 0, ze)) : (se(e, Re, Ne, Te, re, Fe, ze), se(e, ke, X, Te, re, Fe, ze)), T = o.clickable || o.hoverable, B = Ee.clickable || Ee.hoverable, (T || B) && (le || (le = new E.Vector3().addVectors(Re, Ne).multiplyScalar(0.5)), ie || (ie = new E.Vector3().addVectors(ke, X).multiplyScalar(0.5)), T && (U = new M.Cylinder(Re, le, Te), V = new M.Cylinder(ke, ie, Te), o.intersectionShape.cylinder.push(U), o.intersectionShape.cylinder.push(V)), B && (G = new M.Cylinder(Ne, le, Te), Y = new M.Cylinder(X, ie, Te), Ee.intersectionShape.cylinder.push(G), Ee.intersectionShape.cylinder.push(Y)))) : o.bondOrder[W] == 3 && (Te = D * x, Ie.cross(Be), Ie.normalize(), Ie.multiplyScalar(Te * 3), Re = ae.clone(), Re.add(Ie), ke = ae.clone(), ke.sub(Ie), Ne = Re.clone(), Ne.add(Be), X = ke.clone(), X.add(Be), re != Le ? (le = new E.Vector3().addVectors(Re, Ne).multiplyScalar(0.5), ie = new E.Vector3().addVectors(ke, X).multiplyScalar(0.5), xe = new E.Vector3().addVectors(ae, pe).multiplyScalar(0.5), se(e, Re, le, Te, re, Fe, 0), se(e, le, Ne, Te, Le, 0, ze), se(e, ae, xe, Te, re, R, 0), se(e, xe, pe, Te, Le, 0, z), se(e, ke, ie, Te, re, Fe, 0), se(e, ie, X, Te, Le, 0, ze)) : (se(e, Re, Ne, Te, re, Fe, ze), se(e, ae, pe, Te, re, R, z), se(e, ke, X, Te, re, Fe, ze)), T = o.clickable || o.hoverable, B = Ee.clickable || Ee.hoverable, (T || B) && (le || (le = new E.Vector3().addVectors(Re, Ne).multiplyScalar(0.5)), ie || (ie = new E.Vector3().addVectors(ke, X).multiplyScalar(0.5)), xe || (xe = new E.Vector3().addVectors(ae, pe).multiplyScalar(0.5)), T && (U = new M.Cylinder(Re.clone(), le.clone(), Te), V = new M.Cylinder(ke.clone(), ie.clone(), Te), H = new M.Cylinder(ae.clone(), xe.clone(), Te), o.intersectionShape.cylinder.push(U), o.intersectionShape.cylinder.push(V), o.intersectionShape.cylinder.push(H)), B && (G = new M.Cylinder(Ne.clone(), le.clone(), Te), Y = new M.Cylinder(X.clone(), ie.clone(), Te), J = new M.Cylinder(pe.clone(), xe.clone(), Te), Ee.intersectionShape.cylinder.push(G), Ee.intersectionShape.cylinder.push(Y), Ee.intersectionShape.cylinder.push(J))));
+ }
+ }
+ }
+ var K = !1, q = 0, fe = !1;
+ for (W = 0; W < o.bonds.length; W++)
+ k = O, o.bondStyles && o.bondStyles[W] && (F = o.bondStyles[W], F.singleBond && (k = !0), F.radius && F.radius != a && (fe = !0)), (k || o.bondOrder[W] == 1) && q++;
+ fe ? q > 0 && (K = !0) : q == 0 && (o.bonds.length > 0 || n.showNonBonded) && (K = !0), K && (D = a, e.imposter ? this.drawSphereImposter(e.sphereGeometry, o, D, re) : h.GLDraw.drawSphere(e, o, D, re));
+ }
+ }
+ }
+ // go through all the atoms and regenerate their geometries
+ // we try to have one geometry for each style since this is much much
+ // faster
+ // at some point we should optimize this to avoid unnecessary
+ // recalculation
+ /** param {AtomSpec[]} atoms */
+ createMolObj(o, l) {
+ l = l || {};
+ var e = new v.Object3D(), n = [], a = {}, p = {}, x = this.drawAtomSphere, D = null, O = null;
+ l.supportsImposters ? (x = this.drawAtomImposter, D = new v.Geometry(!0), D.imposter = !0, O = new v.Geometry(!0, !0), O.imposter = !0, O.sphereGeometry = new v.Geometry(!0), O.sphereGeometry.imposter = !0, O.drawnCaps = {}) : l.supportsAIA ? (x = this.drawAtomInstanced, D = new v.Geometry(!1, !0, !0), D.instanced = !0, O = new v.Geometry(!0)) : (D = new v.Geometry(!0), O = new v.Geometry(!0));
+ var R, z, T, B, W = {}, k = [Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY];
+ for (R = 0, T = o.length; R < T; R++) {
+ var F = o[R];
+ if (F && F.style) {
+ (F.clickable || F.hoverable) && F.intersectionShape === void 0 && (F.intersectionShape = { sphere: [], cylinder: [], line: [], triangle: [] }), B = { line: void 0, cross: void 0, stick: void 0, sphere: void 0 };
+ for (z in B)
+ F.style[z] ? F.style[z].opacity ? B[z] = parseFloat(F.style[z].opacity) : B[z] = 1 : B[z] = void 0, W[z] ? B[z] != null && W[z] != B[z] && (console.log("Warning: " + z + " opacity is ambiguous"), W[z] = 1) : W[z] = B[z];
+ x.call(this, F, D), this.drawAtomClickSphere(F), this.drawAtomCross(F, p), this.drawBondLines(F, o, a), this.drawBondSticks(F, o, O), typeof F.style.cartoon < "u" && !F.style.cartoon.hidden && (F.style.cartoon.color === "spectrum" && typeof F.resi == "number" && !F.hetflag && (F.resi < k[0] && (k[0] = F.resi), F.resi > k[1] && (k[1] = F.resi)), n.push(F));
+ }
+ }
+ if (n.length > 0 && (0, g.drawCartoon)(e, n, k, this.defaultCartoonQuality), D && D.vertices > 0) {
+ D.initTypedArrays();
+ var U = null, V = null;
+ D.imposter ? U = new v.SphereImposterMaterial({
+ ambient: 0,
+ vertexColors: !0,
+ reflectivity: 0
+ }) : D.instanced ? (V = new v.Geometry(!0), h.GLDraw.drawSphere(V, { x: 0, y: 0, z: 0 }, 1, new A.Color(0.5, 0.5, 0.5)), V.initTypedArrays(), U = new v.InstancedMaterial({
+ sphereMaterial: new v.MeshLambertMaterial({
+ ambient: 0,
+ vertexColors: !0,
+ reflectivity: 0
+ }),
+ sphere: V
+ })) : U = new v.MeshLambertMaterial({
+ ambient: 0,
+ vertexColors: !0,
+ reflectivity: 0
+ }), W.sphere < 1 && W.sphere >= 0 && (U.transparent = !0, U.opacity = W.sphere), V = new v.Mesh(D, U), e.add(V);
+ }
+ if (O.vertices > 0) {
+ var H = null, G = null, Y = O.sphereGeometry;
+ (!Y || typeof Y.vertices > "u" || Y.vertices == 0) && (Y = null), O.initTypedArrays(), Y && Y.initTypedArrays();
+ var J = { ambient: 0, vertexColors: !0, reflectivity: 0 };
+ O.imposter ? (H = new v.StickImposterMaterial(J), G = new v.SphereImposterMaterial(J)) : (H = new v.MeshLambertMaterial(J), G = new v.MeshLambertMaterial(J), H.wireframe && (O.setUpWireframe(), Y && Y.setUpWireframe())), W.stick < 1 && W.stick >= 0 && (H.transparent = !0, H.opacity = W.stick, G.transparent = !0, G.opacity = W.stick);
+ var re = new v.Mesh(O, H);
+ if (e.add(re), Y) {
+ var le = new v.Mesh(Y, G);
+ e.add(le);
+ }
+ }
+ var ie;
+ for (R in a)
+ if (a.hasOwnProperty(R)) {
+ ie = R;
+ var xe = new v.LineBasicMaterial({
+ linewidth: ie,
+ vertexColors: !0
+ });
+ W.line < 1 && W.line >= 0 && (xe.transparent = !0, xe.opacity = W.line), a[R].initTypedArrays();
+ var se = new v.Line(a[R], xe, v.LineStyle.LinePieces);
+ e.add(se);
+ }
+ for (R in p)
+ if (p.hasOwnProperty(R)) {
+ ie = R;
+ var ce = new v.LineBasicMaterial({
+ linewidth: ie,
+ vertexColors: !0
+ });
+ W.cross < 1 && W.cross >= 0 && (ce.transparent = !0, ce.opacity = W.cross), p[R].initTypedArrays();
+ var Ee = new v.Line(p[R], ce, v.LineStyle.LinePieces);
+ e.add(Ee);
+ }
+ if (this.dontDuplicateAtoms && this.modelData.symmetries && this.modelData.symmetries.length > 0) {
+ var be = new v.Object3D(), Le;
+ for (Le = 0; Le < this.modelData.symmetries.length; Le++) {
+ var ae = new v.Object3D();
+ ae = e.clone(), ae.matrix.copy(this.modelData.symmetries[Le]), ae.matrixAutoUpdate = !1, be.add(ae);
+ }
+ return be;
+ }
+ return e;
+ }
+ /**
+ * Return object representing internal state of
+ * the model appropriate for passing to setInternalState
+ *
+ */
+ getInternalState() {
+ return {
+ atoms: this.atoms,
+ frames: this.frames
+ };
+ }
+ /**
+ * Overwrite the internal model state with the passed state.
+ *
+ */
+ setInternalState(o) {
+ this.atoms = o.atoms, this.frames = o.frames, this.molObj = null;
+ }
+ /**
+ * Returns crystallographic information if present.
+ *
+ *
+ */
+ getCrystData() {
+ if (this.modelData.cryst) {
+ if (!this.modelData.cryst.matrix) {
+ const o = this.modelData.cryst;
+ this.modelData.cryst.matrix = (0, E.conversionMatrix3)(o.a, o.b, o.c, o.alpha, o.beta, o.gamma);
+ }
+ return this.modelData.cryst;
+ } else
+ return null;
+ }
+ /**
+ * Set crystallographic information using three angles and three lengths
+ *
+ * @param {number} a - length of unit cell side
+ * @param {number} b - length of unit cell side
+ * @param {number} c - length of unit cell side
+ * @param {number} alpha - unit cell angle in degrees (default 90)
+ * @param {number} beta - unit cell angle in degrees (default 90)
+ * @param {number} gamma - unit cell angle in degrees (default 90)
+
+ */
+ setCrystData(o, l, e, n, a, p) {
+ o = o || 1, l = l || 1, e = e || 1, n = n || 90, a = a || 90, p = p || 90;
+ const x = (0, E.conversionMatrix3)(o, l, e, n, a, p);
+ this.modelData.cryst = {
+ a: o,
+ b: l,
+ c: e,
+ alpha: n,
+ beta: a,
+ gamma: p,
+ matrix: x
+ };
+ }
+ /**
+ * Set the crystallographic matrix to the given matrix.
+ *
+ * This function removes `a`, `b`, `c`, `alpha`, `beta`, `gamma` from
+ * the crystal data.
+ *
+ * @param {Matrix3} matrix - unit cell matrix
+ */
+ setCrystMatrix(o) {
+ o = o || new E.Matrix3(1, 0, 0, 0, 1, 0, 0, 0, 1), this.modelData.cryst = {
+ matrix: o
+ };
+ }
+ /**
+ * Returns list of rotational/translational matrices if there is BIOMT data
+ * Otherwise returns a list of just the ID matrix
+ *
+ * @return {Array}
+ *
+ */
+ getSymmetries() {
+ return typeof this.modelData.symmetries > "u" && (this.modelData.symmetries = [this.idMatrix]), this.modelData.symmetries;
+ }
+ /**
+ * Sets symmetries based on specified matrices in list
+ *
+ * @param {Array} list
+ *
+ */
+ setSymmetries(o) {
+ typeof o > "u" ? this.modelData.symmetries = [this.idMatrix] : this.modelData.symmetries = o;
+ }
+ /**
+ * Returns model id number
+ *
+ * @return {number} Model ID
+ */
+ getID() {
+ return this.id;
+ }
+ /**
+ * Returns model's frames property, a list of atom lists
+ *
+ * @return {number}
+ */
+ getNumFrames() {
+ return this.frames.numFrames != null ? this.frames.numFrames : this.frames.length;
+ }
+ adjustCoord(o, l, e, n) {
+ var a = l - o;
+ return a < -e ? l + n : a > e ? l - n : l;
+ }
+ //go over current atoms in depth first order and ensure that connected
+ //attoms aren't split across the box
+ adjustCoordinatesToBox() {
+ if (this.box && this.atomdfs)
+ for (var o = this.box[0], l = this.box[1], e = this.box[2], n = o * 0.9, a = l * 0.9, p = e * 0.9, x = 0; x < this.atomdfs.length; x++)
+ for (var D = this.atomdfs[x], O = 1; O < D.length; O++) {
+ var R = this.atoms[D[O][0]], z = this.atoms[D[O][1]];
+ R.x = this.adjustCoord(z.x, R.x, n, o), R.y = this.adjustCoord(z.y, R.y, a, l), R.z = this.adjustCoord(z.z, R.z, p, e);
+ }
+ }
+ /**
+ * Sets model's atomlist to specified frame
+ * Sets to last frame if framenum out of range
+ *
+ * @param {number} framenum - model's atoms are set to this index in frames list
+ * @return {Promise}
+ */
+ setFrame(o, l) {
+ var e = this.getNumFrames();
+ let n = this;
+ return new Promise(function(a, p) {
+ if (e == 0 && a(), (o < 0 || o >= e) && (o = e - 1), n.frames.url != null) {
+ var x = n.frames.url;
+ (0, C.getbin)(x + "/traj/frame/" + o + "/" + n.frames.path, void 0, "POST", void 0).then(function(D) {
+ for (var O = new Float32Array(D, 44), R = 0, z = 0; z < n.atoms.length; z++)
+ n.atoms[z].x = O[R++], n.atoms[z].y = O[R++], n.atoms[z].z = O[R++];
+ n.box && n.atomdfs && n.adjustCoordinatesToBox(), a();
+ }).catch(p);
+ } else
+ n.atoms = n.frames[o], a();
+ n.molObj = null, n.modelDatas && o < n.modelDatas.length && (n.modelData = n.modelDatas[o], n.unitCellObjects && l && (l.removeUnitCell(n), l.addUnitCell(n)));
+ });
+ }
+ /**
+ * Add atoms as frames of model
+ *
+ * @param {AtomSpec[]} atoms - atoms to be added
+ */
+ addFrame(o) {
+ this.frames.push(o);
+ }
+ /**
+ * If model atoms have dx, dy, dz properties (in some xyz files), vibrate populates the model's frame property based on parameters.
+ * Model can then be animated
+ *
+ * @param {number} numFrames - number of frames to be created, default to 10
+ * @param {number} amplitude - amplitude of distortion, default to 1 (full)
+ * @param {boolean} bothWays - if true, extend both in positive and negative directions by numFrames
+ * @param {GLViewer} viewer - required if arrowSpec is provided
+ * @param {ArrowSpec} arrowSpec - specification for drawing animated arrows. If color isn't specified, atom color (sphere, stick, line preference) is used.
+ *@example
+
+ $3Dmol.download("pdb:4UAA",viewer,{},function(){
+ viewer.setStyle({},{stick:{}});
+ viewer.vibrate(10, 1);
+ viewer.animate({loop: "forward",reps: 1});
+
+ viewer.zoomTo();
+ viewer.render();
+ });
+ */
+ vibrate(o = 10, l = 1, e = !1, n, a) {
+ var p = 0, x = o;
+ e && (p = -o, x = o), this.frames !== void 0 && this.frames.origIndex !== void 0 ? this.setFrame(this.frames.origIndex) : this.setFrame(0), p < x && (this.frames = []), e && (this.frames.origIndex = o);
+ for (var D = p; D < x; D++) {
+ var O = [], R = this.frames.length;
+ if (D == 0 && !a) {
+ this.frames.push(this.atoms);
+ continue;
+ }
+ for (var z = 0; z < this.atoms.length; z++) {
+ var T = (0, C.getAtomProperty)(this.atoms[z], "dx"), B = (0, C.getAtomProperty)(this.atoms[z], "dy"), W = (0, C.getAtomProperty)(this.atoms[z], "dz"), k = new E.Vector3(T, B, W), F = new E.Vector3(this.atoms[z].x, this.atoms[z].y, this.atoms[z].z), U = D * l / o;
+ k.multiplyScalar(U), F.add(k);
+ var V = {};
+ for (var H in this.atoms[z])
+ V[H] = this.atoms[z][H];
+ if (V.x = F.x, V.y = F.y, V.z = F.z, O.push(V), n && a) {
+ var G = (0, C.extend)({}, a), Y = new E.Vector3(T, B, W);
+ if (Y.multiplyScalar(l), Y.add(F), G.start = F, G.end = Y, G.frame = R, !G.color) {
+ var J = V.style.sphere;
+ J || (J = V.style.stick), J || (J = V.style.line), G.color = (0, C.getColorFromStyle)(V, J);
+ }
+ n.addArrow(G);
+ }
+ }
+ this.frames.push(O);
+ }
+ }
+ // set default style and colors for atoms
+ setAtomDefaults(o) {
+ for (let l = 0; l < o.length; l++) {
+ let e = o[l];
+ e && (e.style = e.style || (0, C.deepCopy)(r.defaultAtomStyle), e.color = e.color || this.ElementColors[e.elem] || this.defaultColor, e.model = this.id, (e.clickable || e.hoverable) && (e.intersectionShape = { sphere: [], cylinder: [], line: [], triangle: [] }));
+ }
+ }
+ /** add atoms to this model from molecular data string
+ *
+ * @param {string|ArrayBuffer} data - atom structure file input data string, for gzipped input use ArrayBuffer
+ * @param {string} format - input file string format (e.g 'pdb', 'sdf', 'sdf.gz', etc.)
+ * @param {ParserOptionsSpec} options - format dependent options. Attributes depend on the input format
+ */
+ addMolData(o, l, e = {}) {
+ var n = r.parseMolData(o, l, e);
+ this.dontDuplicateAtoms = !e.duplicateAssemblyAtoms;
+ var a = n.modelData;
+ if (a && (Array.isArray(a) ? (this.modelData = a[0], e.frames && (this.modelDatas = a)) : this.modelData = a), n.box ? this.box = n.box : this.box = null, this.frames.length == 0) {
+ for (let x = 0; x < n.length; x++)
+ n[x].length != 0 && this.frames.push(n[x]);
+ this.frames[0] && (this.atoms = this.frames[0]);
+ } else if (e.frames)
+ for (let x = 0; x < n.length; x++)
+ this.frames.push(n[x]);
+ else
+ for (var p = 0; p < n.length; p++)
+ this.addAtoms(n[p]);
+ for (let x = 0; x < this.frames.length; x++)
+ this.setAtomDefaults(this.frames[x]);
+ e.vibrate && e.vibrate.frames && e.vibrate.amplitude && this.vibrate(e.vibrate.frames, e.vibrate.amplitude), e.style && this.setStyle({}, e.style);
+ }
+ setDontDuplicateAtoms(o) {
+ this.dontDuplicateAtoms = o;
+ }
+ setModelData(o) {
+ this.modelData = o;
+ }
+ //return true if atom value matches property val
+ propertyMatches(o, l) {
+ if (o == l)
+ return !0;
+ if (typeof l == "string" && typeof o == "number") {
+ var e = l.match(/(-?\d+)\s*-\s*(-?\d+)/);
+ if (e) {
+ var n = parseInt(e[1]), a = parseInt(e[2]);
+ if (e && o >= n && o <= a)
+ return !0;
+ }
+ }
+ return !1;
+ }
+ // make a deep copy of a selection object and create caches of expensive
+ // selections. We create a copy so caches are not attached to user
+ // supplied objects where the user might change them invalidating the cache.
+ // This does not support arbitrary
+ // javascript objects, but support enough for eveything that is
+ // used in selections: number, string, boolean, functions; as well
+ // as arrays and nested objects with values of the aformentioned
+ // types.
+ static deepCopyAndCache(o, l) {
+ if (typeof o != "object" || o == null || o.__cache_created)
+ return o;
+ const e = {};
+ for (const n in o) {
+ const a = o[n];
+ if (Array.isArray(a)) {
+ e[n] = [];
+ for (let p = 0; p < a.length; p++)
+ e[n].push(r.deepCopyAndCache(a[p], l));
+ } else
+ typeof a == "object" && n != "properties" && n != "model" ? e[n] = r.deepCopyAndCache(a, l) : e[n] = a;
+ if (n == "and" || n == "or") {
+ const p = [];
+ for (const x of e[n]) {
+ const D = /* @__PURE__ */ new Set();
+ for (const O of l.selectedAtoms(x))
+ D.add(O.index);
+ p.push(D);
+ }
+ if (n == "and") {
+ const x = function(O, R) {
+ const z = /* @__PURE__ */ new Set();
+ for (const T of R)
+ O.has(T) && z.add(T);
+ return z;
+ };
+ let D = new Set(p[0]);
+ for (const O of p.splice(1))
+ D = x(D, O);
+ e[n].__cached_results = D;
+ } else if (n == "or") {
+ const x = /* @__PURE__ */ new Set();
+ for (const D of p)
+ for (const O of D)
+ x.add(O);
+ e[n].__cached_results = x;
+ }
+ }
+ }
+ return e.__cache_created = !0, e;
+ }
+ /** given a selection specification, return true if atom is selected.
+ * Does not support context-aware selectors like expand/within/byres.
+ *
+ * @param {AtomSpec} atom
+ * @param {AtomSelectionSpec} sel
+ * @return {boolean}
+ */
+ atomIsSelected(o, l) {
+ if (typeof l > "u")
+ return !0;
+ var e = !!l.invert, n = !0;
+ for (var a in l)
+ if (a == "and" || a == "or" || a == "not") {
+ if (a == "not") {
+ if (this.atomIsSelected(o, l[a])) {
+ n = !1;
+ break;
+ }
+ } else if (l[a].__cached_results === void 0 && (l = r.deepCopyAndCache(l, this)), n = l[a].__cached_results.has(o.index), !n)
+ break;
+ } else if (a === "predicate") {
+ if (!l.predicate(o)) {
+ n = !1;
+ break;
+ }
+ } else if (a == "properties" && o[a]) {
+ for (var p in l.properties)
+ if (!p.startsWith("__cache")) {
+ if (typeof o.properties[p] > "u") {
+ n = !1;
+ break;
+ }
+ if (o.properties[p] != l.properties[p]) {
+ n = !1;
+ break;
+ }
+ }
+ } else if (l.hasOwnProperty(a) && !r.ignoredKeys.has(a) && !a.startsWith("__cache")) {
+ if (typeof o[a] > "u") {
+ n = !1;
+ break;
+ }
+ var x = !1;
+ if (a === "bonds") {
+ var D = l[a];
+ if (D != o.bonds.length) {
+ n = !1;
+ break;
+ }
+ } else if (Array.isArray(l[a])) {
+ var O = l[a], R = o[a];
+ for (let z = 0; z < O.length; z++)
+ if (this.propertyMatches(R, O[z])) {
+ x = !0;
+ break;
+ }
+ if (!x) {
+ n = !1;
+ break;
+ }
+ } else {
+ let z = l[a];
+ if (!this.propertyMatches(o[a], z)) {
+ n = !1;
+ break;
+ }
+ }
+ }
+ return e ? !n : n;
+ }
+ static squaredDistance(o, l) {
+ var e = l.x - o.x, n = l.y - o.y, a = l.z - o.z;
+ return e * e + n * n + a * a;
+ }
+ /** returns a list of atoms in the expanded bounding box, but not in the current one
+ *
+ * Bounding box:
+ *
+ * [ [ xmin, ymin, zmin ],
+ * [ xmax, ymax, zmax ],
+ * [ xctr, yctr, zctr ] ]
+ *
+ **/
+ expandAtomList(o, l) {
+ if (l <= 0)
+ return o;
+ for (var e = (0, C.getExtent)(o, void 0), n = [[], [], []], a = 0; a < 3; a++)
+ n[0][a] = e[0][a] - l, n[1][a] = e[1][a] + l, n[2][a] = e[2][a];
+ var p = [];
+ for (let R = 0; R < this.atoms.length; R++) {
+ var x = this.atoms[R].x, D = this.atoms[R].y, O = this.atoms[R].z;
+ x >= n[0][0] && x <= n[1][0] && D >= n[0][1] && D <= n[1][1] && O >= n[0][2] && O <= n[1][2] && (x >= e[0][0] && x <= e[1][0] && D >= e[0][1] && D <= e[1][1] && O >= e[0][2] && O <= e[1][2] || p.push(this.atoms[R]));
+ }
+ return p;
+ }
+ static getFloat(o) {
+ return typeof o == "number" ? o : parseFloat(o);
+ }
+ /** return list of atoms selected by sel, this is specific to glmodel
+ *
+ * @param {AtomSelectionSpec} sel
+ * @return {Object[]}
+ * @example
+ $3Dmol.download("pdb:4wwy",viewer,{},function(){
+ var atoms = viewer.selectedAtoms({chain:'A'});
+ for(var i = 0, n = atoms.length; i < n; i++) {
+ atoms[i].b = 0.0;
+ }
+ viewer.setStyle({cartoon:{colorscheme:{prop:'b',gradient: 'roygb',min:0,max:30}}});
+ viewer.render();
+ });
+ */
+ selectedAtoms(o, l) {
+ var e = [];
+ o = r.deepCopyAndCache(o || {}, this), l || (l = this.atoms);
+ for (var n = l.length, a = 0; a < n; a++) {
+ var p = l[a];
+ p && this.atomIsSelected(p, o) && e.push(p);
+ }
+ if (o.hasOwnProperty("expand")) {
+ const V = r.getFloat(o.expand);
+ let H = this.expandAtomList(e, V), G = e.length;
+ const Y = V * V;
+ for (let J = 0; J < H.length; J++)
+ for (let re = 0; re < G; re++) {
+ var x = r.squaredDistance(H[J], e[re]);
+ x < Y && x > 0 && e.push(H[J]);
+ }
+ }
+ if (o.hasOwnProperty("within") && o.within.hasOwnProperty("sel") && o.within.hasOwnProperty("distance")) {
+ var D = this.selectedAtoms(o.within.sel, this.atoms), O = {};
+ const V = r.getFloat(o.within.distance), H = V * V;
+ for (let G = 0; G < D.length; G++)
+ for (let Y = 0; Y < e.length; Y++) {
+ let J = r.squaredDistance(D[G], e[Y]);
+ J < H && J > 0 && (O[Y] = 1);
+ }
+ var R = [];
+ if (o.within.invert)
+ for (let G = 0; G < e.length; G++)
+ O[G] || R.push(e[G]);
+ else
+ for (let G in O)
+ R.push(e[G]);
+ e = R;
+ }
+ if (o.hasOwnProperty("byres")) {
+ var z = {}, T = [], B = [];
+ for (let V = 0; V < e.length; V++) {
+ let H = e[V];
+ var W = H.chain, k = H.resi;
+ if (z[W] === void 0 && (z[W] = {}), H.hasOwnProperty("resi") && z[W][k] === void 0) {
+ for (z[W][k] = !0, B.push(H); B.length > 0; )
+ if (H = B.pop(), W = H.chain, k = H.resi, T[H.index] === void 0) {
+ T[H.index] = !0;
+ for (var F = 0; F < H.bonds.length; F++) {
+ var U = this.atoms[H.bonds[F]];
+ T[U.index] === void 0 && U.hasOwnProperty("resi") && U.chain == W && U.resi == k && (B.push(U), e.push(U));
+ }
+ }
+ }
+ }
+ }
+ return e;
+ }
+ /** Add list of new atoms to model. Adjusts bonds appropriately.
+ *
+ * @param {AtomSpec[]} newatoms
+ * @example
+ * var atoms = [{elem: 'C', x: 0, y: 0, z: 0, bonds: [1,2], bondOrder: [1,2]}, {elem: 'O', x: -1.5, y: 0, z: 0, bonds: [0]},{elem: 'O', x: 1.5, y: 0, z: 0, bonds: [0], bondOrder: [2]}];
+
+ viewer.setBackgroundColor(0xffffffff);
+ var m = viewer.addModel();
+ m.addAtoms(atoms);
+ m.setStyle({},{stick:{}});
+ viewer.zoomTo();
+ viewer.render();
+ */
+ addAtoms(o) {
+ this.molObj = null;
+ var l = this.atoms.length, e = [], n;
+ for (n = 0; n < o.length; n++)
+ typeof o[n].index > "u" && (o[n].index = n), typeof o[n].serial > "u" && (o[n].serial = n), e[o[n].index] = l + n;
+ for (n = 0; n < o.length; n++) {
+ var a = o[n], p = e[a.index], x = (0, C.extend)({}, a);
+ x.index = p, x.bonds = [], x.bondOrder = [], x.model = this.id, x.style = x.style || (0, C.deepCopy)(r.defaultAtomStyle), typeof x.color > "u" && (x.color = this.ElementColors[x.elem] || this.defaultColor);
+ for (var D = a.bonds ? a.bonds.length : 0, O = 0; O < D; O++) {
+ var R = e[a.bonds[O]];
+ typeof R < "u" && (x.bonds.push(R), x.bondOrder.push(a.bondOrder ? a.bondOrder[O] : 1));
+ }
+ this.atoms.push(x);
+ }
+ }
+ /** Assign bonds based on atomic coordinates.
+ * This currently uses a primitive distance-based algorithm that does not
+ * consider valence constraints and will only create single bonds.
+ */
+ assignBonds() {
+ (0, w.assignBonds)(this.atoms);
+ }
+ /** Remove specified atoms from model
+ *
+ * @param {AtomSpec[]} badatoms - list of atoms
+ */
+ removeAtoms(o) {
+ this.molObj = null;
+ var l = [], e;
+ for (e = 0; e < o.length; e++)
+ l[o[e].index] = !0;
+ var n = [];
+ for (e = 0; e < this.atoms.length; e++) {
+ var a = this.atoms[e];
+ l[a.index] || n.push(a);
+ }
+ this.atoms = [], this.addAtoms(n);
+ }
+ /** Set atom style of selected atoms
+ *
+ * @param {AtomSelectionSpec} sel
+ * @param {AtomStyleSpec} style
+ * @param {boolean} add - if true, add to current style, don't replace
+ @example
+ $3Dmol.download("pdb:4UB9",viewer,{},function(){
+ viewer.setBackgroundColor(0xffffffff);
+
+ viewer.setStyle({chain:'A'},{line:{hidden:true,colorscheme:{prop:'b',gradient: new $3Dmol.Gradient.Sinebow($3Dmol.getPropertyRange(viewer.selectedAtoms(),'b'))}}});
+ viewer.setStyle({chain:'B'},{line:{colorscheme:{prop:'b',gradient: new $3Dmol.Gradient.Sinebow($3Dmol.getPropertyRange(viewer.selectedAtoms(),'b'))}}});
+ viewer.setStyle({chain:'C'},{cross:{hidden:true,colorscheme:{prop:'b',gradient: new $3Dmol.Gradient.Sinebow($3Dmol.getPropertyRange(viewer.selectedAtoms(),'b'))}}});
+ viewer.setStyle({chain:'D'},{cross:{colorscheme:{prop:'b',gradient: new $3Dmol.Gradient.RWB($3Dmol.getPropertyRange(viewer.selectedAtoms(),'b'))}}});
+ viewer.setStyle({chain:'E'},{cross:{radius:2.0,colorscheme:{prop:'b',gradient: new $3Dmol.Gradient.RWB($3Dmol.getPropertyRange(viewer.selectedAtoms(),'b'))}}});
+ viewer.setStyle({chain:'F'},{stick:{hidden:true,colorscheme:{prop:'b',gradient: new $3Dmol.Gradient.RWB($3Dmol.getPropertyRange(viewer.selectedAtoms(),'b'))}}});
+ viewer.setStyle({chain:'G'},{stick:{radius:0.8,colorscheme:{prop:'b',gradient: new $3Dmol.Gradient.ROYGB($3Dmol.getPropertyRange(viewer.selectedAtoms(),'b'))}}});
+ viewer.setStyle({chain:'H'},{stick:{singleBonds:true,colorscheme:{prop:'b',gradient: new $3Dmol.Gradient.ROYGB($3Dmol.getPropertyRange(viewer.selectedAtoms(),'b'))}}});
+ viewer.render();
+ });
+ */
+ setStyle(o, l, e) {
+ typeof l > "u" && typeof e > "u" && (l = o, o = {}), o = o, typeof l == "string" && (l = (0, C.specStringToObject)(l));
+ var n = !1, a = this, p = function(D) {
+ var O = a.selectedAtoms(o, D);
+ for (let R = 0; R < D.length; R++)
+ D[R] && (D[R].capDrawn = !1);
+ for (let R = 0; R < O.length; R++) {
+ n = !0, (O[R].clickable || O[R].hoverable) && (O[R].intersectionShape = { sphere: [], cylinder: [], line: [], triangle: [] }), e || (O[R].style = {});
+ for (let z in l)
+ l.hasOwnProperty(z) && (O[R].style[z] = O[R].style[z] || {}, Object.assign(O[R].style[z], l[z]));
+ }
+ };
+ if (o.frame !== void 0 && o.frame < this.frames.length) {
+ let D = o.frame;
+ D < 0 && (D = this.frames.length + D), p(this.frames[D]);
+ } else {
+ p(this.atoms);
+ for (var x = 0; x < this.frames.length; x++)
+ this.frames[x] !== this.atoms && p(this.frames[x]);
+ }
+ n && (this.molObj = null);
+ }
+ /** Set clickable and callback of selected atoms
+ *
+ * @param {AtomSelectionSpec} sel - atom selection to apply clickable settings to
+ * @param {boolean} clickable - whether click-handling is enabled for the selection
+ * @param {function} callback - function called when an atom in the selection is clicked
+
+ */
+ setClickable(o, l, e) {
+ if (l = !!l, e = (0, C.makeFunction)(e), e === null) {
+ console.log("Callback is not a function");
+ return;
+ }
+ var n = this.selectedAtoms(o, this.atoms), a = n.length;
+ for (let p = 0; p < a; p++)
+ n[p].intersectionShape = { sphere: [], cylinder: [], line: [], triangle: [] }, n[p].clickable = l, e && (n[p].callback = e);
+ a > 0 && (this.molObj = null);
+ }
+ /** Set hoverable and callback of selected atoms
+ *
+ * @param {AtomSelectionSpec} sel - atom selection to apply hoverable settings to
+ * @param {boolean} hoverable - whether hover-handling is enabled for the selection
+ * @param {function} hover_callback - function called when an atom in the selection is hovered over
+ * @param {function} unhover_callback - function called when the mouse moves out of the hover area
+ */
+ setHoverable(o, l, e, n) {
+ if (l = !!l, e = (0, C.makeFunction)(e), n = (0, C.makeFunction)(n), e === null) {
+ console.log("Hover_callback is not a function");
+ return;
+ }
+ if (n === null) {
+ console.log("Unhover_callback is not a function");
+ return;
+ }
+ var a = this.selectedAtoms(o, this.atoms), p = a.length;
+ for (let x = 0; x < p; x++)
+ a[x].intersectionShape = { sphere: [], cylinder: [], line: [], triangle: [] }, a[x].hoverable = l, e && (a[x].hover_callback = e), n && (a[x].unhover_callback = n);
+ p > 0 && (this.molObj = null);
+ }
+ /** enable context menu of selected atoms
+ *
+ * @param {AtomSelectionSpec} sel - atom selection to apply hoverable settings to
+ * @param {boolean} contextMenuEnabled - whether contextMenu-handling is enabled for the selection
+ */
+ enableContextMenu(o, l) {
+ l = !!l;
+ var e, n = this.selectedAtoms(o, this.atoms), a = n.length;
+ for (e = 0; e < a; e++)
+ n[e].intersectionShape = { sphere: [], cylinder: [], line: [], triangle: [] }, n[e].contextMenuEnabled = l;
+ a > 0 && (this.molObj = null);
+ }
+ /** given a mapping from element to color, set atom colors
+ *
+ * @param {AtomSelectionSpec} sel
+ * @param {object} colors
+ */
+ setColorByElement(o, l) {
+ if (!(this.molObj !== null && r.sameObj(l, this.lastColors))) {
+ this.lastColors = l;
+ var e = this.selectedAtoms(o, e);
+ e.length > 0 && (this.molObj = null);
+ for (var n = 0; n < e.length; n++) {
+ var a = e[n];
+ typeof l[a.elem] < "u" && (a.color = l[a.elem]);
+ }
+ }
+ }
+ /**
+ * @param {AtomSelectionSpec} sel
+ * @param {string} prop
+ * @param {Gradient|string} scheme
+ */
+ setColorByProperty(o, l, e, n) {
+ var a, p, x = this.selectedAtoms(o, x);
+ for (this.lastColors = null, x.length > 0 && (this.molObj = null), typeof e == "string" && typeof c.Gradient.builtinGradients[e] < "u" && (e = new c.Gradient.builtinGradients[e]()), e = e, n || (n = e.range()), n || (n = (0, C.getPropertyRange)(x, l)), a = 0; a < x.length; a++) {
+ p = x[a];
+ var D = (0, C.getAtomProperty)(p, l);
+ D != null && (p.color = e.valueToHex(parseFloat(p.properties[l]), n));
+ }
+ }
+ /**
+ * @deprecated use setStyle and colorfunc attribute
+ * @param {AtomSelectionSpec} sel - selection object
+ * @param {function} func - function to be used to set the color
+ @example
+ $3Dmol.download("pdb:4UAA",viewer,{},function(){
+ viewer.setBackgroundColor(0xffffffff);
+ var colorAsSnake = function(atom) {
+ return atom.resi % 2 ? 'white': 'green'
+ };
+
+ viewer.setStyle( {}, { cartoon: {colorfunc: colorAsSnake }});
+
+ viewer.render();
+ });
+
+ */
+ setColorByFunction(o, l) {
+ var e = this.selectedAtoms(o, e);
+ if (typeof l == "function") {
+ this.lastColors = null, e.length > 0 && (this.molObj = null);
+ for (let n = 0; n < e.length; n++) {
+ let a = e[n];
+ a.color = l(a);
+ }
+ }
+ }
+ /** Convert the model into an object in the format of a ChemDoodle JSON model.
+ *
+ * @param {boolean} whether or not to include style information. Defaults to false.
+ * @return {Object}
+ */
+ toCDObject(o = !1) {
+ var l = { a: [], b: [] };
+ o && (l.s = []);
+ for (let n = 0; n < this.atoms.length; n++) {
+ let a = {}, p = this.atoms[n];
+ if (a.x = p.x, a.y = p.y, a.z = p.z, p.elem != "C" && (a.l = p.elem), o) {
+ for (var e = 0; e < l.s.length && JSON.stringify(p.style) !== JSON.stringify(l.s[e]); )
+ e++;
+ e === l.s.length && l.s.push(p.style), e !== 0 && (a.s = e);
+ }
+ l.a.push(a);
+ for (let x = 0; x < p.bonds.length; x++) {
+ let D = n, O = p.bonds[x];
+ if (D >= O)
+ continue;
+ let R = {
+ b: D,
+ e: O
+ }, z = p.bondOrder[x];
+ z != 1 && (R.o = z), l.b.push(R);
+ }
+ }
+ return l;
+ }
+ /** manage the globj for this model in the possed modelGroup - if it has to be regenerated, remove and add
+ *
+ * @param {Object3D} group
+ * @param Object options
+ */
+ globj(o, l) {
+ (this.molObj === null || l.regen) && (this.molObj = this.createMolObj(this.atoms, l), this.renderedMolObj && (o.remove(this.renderedMolObj), this.renderedMolObj = null), this.renderedMolObj = this.molObj.clone(), this.hidden && (this.renderedMolObj.setVisible(!1), this.molObj.setVisible(!1)), o.add(this.renderedMolObj));
+ }
+ /** return a VRML string representation of the model. Does not include VRML header information
+ * @return VRML
+ */
+ exportVRML() {
+ var o = this.createMolObj(this.atoms, { supportsImposters: !1, supportsAIA: !1 });
+ return o.vrml();
+ }
+ /** Remove any renderable mol object from scene
+ *
+ * @param {Object3D} group
+ */
+ removegl(o) {
+ this.renderedMolObj && (this.renderedMolObj.geometry !== void 0 && this.renderedMolObj.geometry.dispose(), this.renderedMolObj.material !== void 0 && this.renderedMolObj.material.dispose(), o.remove(this.renderedMolObj), this.renderedMolObj = null), this.molObj = null;
+ }
+ /**
+ * Don't show this model in future renderings. Keep all styles and state
+ * so it can be efficiencly shown again.
+ *
+ * * @see GLModel#show
+
+ * @example
+ $3Dmol.download("pdb:3ucr",viewer,{},function(){
+ viewer.setStyle({},{stick:{}});
+ viewer.getModel().hide();
+ viewer.render();
+ });
+ */
+ hide() {
+ this.hidden = !0, this.renderedMolObj && this.renderedMolObj.setVisible(!1), this.molObj && this.molObj.setVisible(!1);
+ }
+ /**
+ * Unhide a hidden model
+ * @see GLModel#hide
+ * @example
+ $3Dmol.download("pdb:3ucr",viewer,{},function(){
+ viewer.setStyle({},{stick:{}});
+ viewer.getModel().hide();
+ viewer.render( )
+ viewer.getModel().show()
+ viewer.render();
+ });
+ */
+ show() {
+ this.hidden = !1, this.renderedMolObj && this.renderedMolObj.setVisible(!0), this.molObj && this.molObj.setVisible(!0);
+ }
+ /** Create labels for atoms that show the value of the passed property.
+ *
+ * @param {String} prop - property name
+ * @param {AtomSelectionSpec} sel
+ * @param {GLViewer} viewer
+ * @param {LabelSpec} options
+ */
+ addPropertyLabels(o, l, e, n) {
+ for (var a = this.selectedAtoms(l, a), p = (0, C.deepCopy)(n), x = 0; x < a.length; x++) {
+ var D = a[x], O = null;
+ typeof D[o] < "u" ? O = String(D[o]) : typeof D.properties[o] < "u" && (O = String(D.properties[o])), O != null && (p.position = D, e.addLabel(O, p));
+ }
+ }
+ /** Create labels for residues of selected atoms.
+ * Will create a single label at the center of mass of all atoms
+ * with the same chain,resn, and resi.
+ *
+ * @param {AtomSelectionSpec} sel
+ * @param {GLViewer} viewer
+ * @param {LabelSpec} options
+ * @param {boolean} byframe - if true, create labels for every individual frame, not just current; frames must be loaded already
+ */
+ addResLabels(o, l, e, n = !1) {
+ var a = [], p = function(D, O) {
+ for (var R = D.selectedAtoms(o, R), z = {}, T = 0; T < R.length; T++) {
+ var B = R[T], W = B.chain, k = B.resn, F = B.resi, U = k + "" + F;
+ z[W] || (z[W] = {}), z[W][U] || (z[W][U] = []), z[W][U].push(B);
+ }
+ var V = (0, C.deepCopy)(e);
+ for (let G in z)
+ if (z.hasOwnProperty(G)) {
+ var H = z[G];
+ for (let Y in H)
+ if (H.hasOwnProperty(Y)) {
+ let J = H[Y], re = new E.Vector3(0, 0, 0);
+ for (let ie = 0; ie < J.length; ie++) {
+ let xe = J[ie];
+ re.x += xe.x, re.y += xe.y, re.z += xe.z;
+ }
+ re.divideScalar(J.length), V.position = re, V.frame = O;
+ let le = l.addLabel(Y, V, void 0, !0);
+ a.push(le);
+ }
+ }
+ };
+ if (n) {
+ var x = this.getNumFrames();
+ let D = this.atoms;
+ for (let O = 0; O < x; O++)
+ this.frames[O] && (this.atoms = this.frames[O], p(this, O));
+ this.atoms = D;
+ } else
+ p(this);
+ return a;
+ }
+ //recurse over the current atoms to establish a depth first order
+ setupDFS() {
+ this.atomdfs = [];
+ var o = this, l = new Int8Array(this.atoms.length);
+ l.fill(0);
+ for (var e = function(x, D, O) {
+ O.push([x, D]);
+ var R = o.atoms[x];
+ l[x] = 1;
+ for (var z = 0; z < R.bonds.length; z++) {
+ var T = R.bonds[z];
+ o.atoms[T] && !l[T] && e(T, x, O);
+ }
+ }, n = 0; n < this.atoms.length; n++) {
+ var a = this.atoms[n];
+ if (a && !l[n]) {
+ var p = [];
+ e(n, -1, p), this.atomdfs.push(p);
+ }
+ }
+ }
+ /**
+ * Set coordinates from remote trajectory file.
+ * @param {string} url - contains the url where mdsrv has been hosted
+ * @param {string} path - contains the path of the file (/filename)
+ * @return {Promise}
+ */
+ setCoordinatesFromURL(o, l) {
+ this.frames = [];
+ var e = this;
+ return this.box && this.setupDFS(), o.startsWith("http") || (o = "http://" + o), (0, C.get)(o + "/traj/numframes/" + l, function(n) {
+ if (!isNaN(parseInt(n)))
+ return e.frames.push(e.atoms), e.frames.numFrames = n, e.frames.url = o, e.frames.path = l, e.setFrame(0);
+ });
+ }
+ /**
+ * Set coordinates for the atoms from provided trajectory file.
+ * @param {string|ArrayBuffer} str - contains the data of the file
+ * @param {string} format - contains the format of the file (mdcrd, inpcrd, pdb, netcdf, or array). Arrays should be TxNx3 where T is the number of timesteps and N the number of atoms.
+ @example
+ let m = viewer.addModel() //create an empty model
+ m.addAtoms([{x:0,y:0,z:0,elem:'C'},{x:2,y:0,z:0,elem:'C'}]) //provide a list of dictionaries representing the atoms
+ viewer.setStyle({'sphere':{}})
+ m.setCoordinates([[[0.0, 0.0, 0.0], [2.0, 0.0, 0.0]], [[0.0, 0.0, 0.0], [2.8888888359069824, 0.0, 0.0]], [[0.0, 0.0, 0.0], [3.777777671813965, 0.0, 0.0]], [[0.0, 0.0, 0.0], [4.666666507720947, 0.0, 0.0]], [[0.0, 0.0, 0.0], [5.55555534362793, 0.0, 0.0]], [[0.0, 0.0, 0.0], [6.44444465637207, 0.0, 0.0]], [[0.0, 0.0, 0.0], [7.333333492279053, 0.0, 0.0]], [[0.0, 0.0, 0.0], [8.222222328186035, 0.0, 0.0]], [[0.0, 0.0, 0.0], [9.11111068725586, 0.0, 0.0]], [[0.0, 0.0, 0.0], [10.0, 0.0, 0.0]]],'array');
+ viewer.animate({loop: "forward",reps: 1});
+ viewer.zoomTo();
+ viewer.zoom(0.5);
+ viewer.render();
+ */
+ setCoordinates(o, l) {
+ if (l = l || "", !o)
+ return [];
+ if (/\.gz$/.test(l)) {
+ l = l.replace(/\.gz$/, "");
+ try {
+ o = t(o);
+ } catch (z) {
+ console.log(z);
+ }
+ }
+ var e = { mdcrd: "", inpcrd: "", pdb: "", netcdf: "", array: "" };
+ if (e.hasOwnProperty(l)) {
+ this.frames = [];
+ for (var n = this.atoms.length, a = r.parseCrd(o, l), p = 0; p < a.length; ) {
+ for (var x = [], D = 0; D < n; D++) {
+ var O = {};
+ for (var R in this.atoms[D])
+ O[R] = this.atoms[D][R];
+ x[D] = O, x[D].x = a[p++], x[D].y = a[p++], x[D].z = a[p++];
+ }
+ this.frames.push(x);
+ }
+ return this.atoms = this.frames[0], this.frames;
+ }
+ return [];
+ }
+ /**
+ * add atomSpecs to validAtomSelectionSpecs
+ * @deprecated
+ * @param {Array} customAtomSpecs - array of strings that can be used as atomSelectionSpecs
+ * this is to prevent the 'Unknown Selector x' message on the console for the strings passed.
+ * These messages are no longer generated as, in theory, typescript will catch problems at compile time.
+ * In practice, there may still be issues at run-time but we don't check for them...
+ *
+ * What we should do is use something like https://github.com/woutervh-/typescript-is to do runtime
+ * type checking, but it currently doesn't work with our types...
+ */
+ addAtomSpecs(o) {
+ }
+ static parseCrd(o, l) {
+ var e = [], n = 0;
+ if (l == "pdb")
+ for (var a = o.indexOf(`
+ATOM`); a != -1; ) {
+ for (; o.slice(a, a + 5) == `
+ATOM` || o.slice(a, a + 7) == `
+HETATM`; )
+ e[n++] = parseFloat(o.slice(a + 31, a + 39)), e[n++] = parseFloat(o.slice(a + 39, a + 47)), e[n++] = parseFloat(o.slice(a + 47, a + 55)), a = o.indexOf(`
+`, a + 54), o.slice(a, a + 4) == `
+TER` && (a = o.indexOf(`
+`, a + 5));
+ a = o.indexOf(`
+ATOM`, a);
+ }
+ else if (l == "netcdf") {
+ var p = new y.NetCDFReader(o);
+ e = [].concat.apply([], p.getDataVariable("coordinates"));
+ } else {
+ if (l == "array" || Array.isArray(o))
+ return o.flat(2);
+ {
+ let x = o.indexOf(`
+`);
+ l == "inpcrd" && (x = o.indexOf(`
+`, x + 1)), o = o.slice(x + 1), e = o.match(/\S+/g).map(parseFloat);
+ }
+ }
+ return e;
+ }
+ static parseMolData(o, l = "", e) {
+ if (!o)
+ return [];
+ if (/\.gz$/.test(l)) {
+ l = l.replace(/\.gz$/, "");
+ try {
+ o = t(o);
+ } catch (p) {
+ console.log(p);
+ }
+ }
+ typeof S.Parsers[l] > "u" && (l = l.split(".").pop(), typeof S.Parsers[l] > "u" && (console.log("Unknown format: " + l), o instanceof Uint8Array ? l = "mmtf" : o.match(/^@MOLECULE/gm) ? l = "mol2" : o.match(/^data_/gm) && o.match(/^loop_/gm) ? l = "cif" : o.match(/^HETATM/gm) || o.match(/^ATOM/gm) ? l = "pdb" : o.match(/ITEM: TIMESTEP/gm) ? l = "lammpstrj" : o.match(/^.*\n.*\n.\s*(\d+)\s+(\d+)/gm) ? l = "sdf" : o.match(/^%VERSION\s+VERSION_STAMP/gm) ? l = "prmtop" : l = "xyz", console.log("Best guess: " + l)));
+ var n = S.Parsers[l], a = n(o, e);
+ return a;
+ }
+ }
+ r.defaultAtomStyle = {
+ line: {}
+ }, r.defaultlineWidth = 1, r.vdwRadii = {
+ H: 1.2,
+ He: 1.4,
+ Li: 1.82,
+ Be: 1.53,
+ B: 1.92,
+ C: 1.7,
+ N: 1.55,
+ O: 1.52,
+ F: 1.47,
+ Ne: 1.54,
+ Na: 2.27,
+ Mg: 1.73,
+ Al: 1.84,
+ Si: 2.1,
+ P: 1.8,
+ S: 1.8,
+ Cl: 1.75,
+ Ar: 1.88,
+ K: 2.75,
+ Ca: 2.31,
+ Ni: 1.63,
+ Cu: 1.4,
+ Zn: 1.39,
+ Ga: 1.87,
+ Ge: 2.11,
+ As: 1.85,
+ Se: 1.9,
+ Br: 1.85,
+ Kr: 2.02,
+ Rb: 3.03,
+ Sr: 2.49,
+ Pd: 1.63,
+ Ag: 1.72,
+ Cd: 1.58,
+ In: 1.93,
+ Sn: 2.17,
+ Sb: 2.06,
+ Te: 2.06,
+ I: 1.98,
+ Xe: 2.16,
+ Cs: 3.43,
+ Ba: 2.68,
+ Pt: 1.75,
+ Au: 1.66,
+ Hg: 1.55,
+ Tl: 1.96,
+ Pb: 2.02,
+ Bi: 2.07,
+ Po: 1.97,
+ At: 2.02,
+ Rn: 2.2,
+ Fr: 3.48,
+ Ra: 2.83,
+ U: 1.86
+ }, r.ignoredKeys = /* @__PURE__ */ new Set(["props", "invert", "model", "frame", "byres", "expand", "within", "and", "or", "not"]);
+ }
+ ),
+ /***/
+ "./src/GLShape.ts": (
+ /*!************************!*\
+ !*** ./src/GLShape.ts ***!
+ \************************/
+ /***/
+ (P, _, s) => {
+ s.r(_), s.d(_, {
+ /* harmony export */
+ GLShape: () => (
+ /* binding */
+ y
+ ),
+ /* harmony export */
+ splitMesh: () => (
+ /* binding */
+ b
+ )
+ /* harmony export */
+ });
+ var v = s(
+ /*! ./WebGL */
+ "./src/WebGL/index.ts"
+ ), M = s(
+ /*! ./WebGL/shapes */
+ "./src/WebGL/shapes/index.ts"
+ ), E = s(
+ /*! ./WebGL/math */
+ "./src/WebGL/math/index.ts"
+ ), A = s(
+ /*! ./colors */
+ "./src/colors.ts"
+ ), h = s(
+ /*! ./ProteinSurface4 */
+ "./src/ProteinSurface4.ts"
+ ), g = s(
+ /*! ./VolumeData */
+ "./src/VolumeData.ts"
+ ), C = s(
+ /*! ./GLDraw */
+ "./src/GLDraw.ts"
+ ), c = s(
+ /*! ./glcartoon */
+ "./src/glcartoon.ts"
+ ), S = s(
+ /*! ./utilities */
+ "./src/utilities.ts"
+ );
+ class y {
+ static finalizeGeo(t) {
+ var r = t.updateGeoGroup(0);
+ r.vertices > 0 && r.truncateArrayBuffers(!0, !0);
+ }
+ /*
+ *
+ * @param {Geometry}
+ * geo
+ * @param {Color | colorlike} color
+ */
+ static updateColor(t, r) {
+ r = r || A.CC.color(r), t.colorsNeedUpdate = !0;
+ var u, o, l;
+ r.constructor !== Array && (u = r.r, o = r.g, l = r.b);
+ for (let e in t.geometryGroups) {
+ let n = t.geometryGroups[e], a = n.colorArray;
+ for (let p = 0, x = n.vertices; p < x; ++p) {
+ if (r.constructor === Array) {
+ let D = r[p];
+ u = D.r, o = D.g, l = D.b;
+ }
+ a[p * 3] = u, a[p * 3 + 1] = o, a[p * 3 + 2] = l;
+ }
+ }
+ }
+ /*
+ * @param {GLShape}
+ * shape
+ * @param {geometryGroup}
+ * geoGroup
+ * @param {ArrowSpec}
+ * spec
+ */
+ static drawArrow(t, r, u) {
+ var o = u.start, l = u.end, e = u.radius, n = u.radiusRatio, a = u.mid, p = u.midpos;
+ if (!(o && l))
+ return;
+ var x = r.updateGeoGroup(51), D = new E.Vector3(l.x, l.y, l.z).sub(o);
+ if (p) {
+ let oe = D.length();
+ p > 0 ? a = p / oe : a = (oe + p) / oe;
+ }
+ D.multiplyScalar(a);
+ var O = new E.Vector3(o.x, o.y, o.z).add(D), R = D.clone().negate();
+ let z = new E.Vector3(o.x, o.y, o.z);
+ t.intersectionShape.cylinder.push(new M.Cylinder(z, O.clone(), e)), t.intersectionShape.sphere.push(new M.Sphere(z, e));
+ var T = [];
+ T[0] = D.clone(), Math.abs(T[0].x) > 1e-4 ? T[0].y += 1 : T[0].x += 1, T[0].cross(D), T[0].normalize(), T[4] = T[0].clone(), T[4].crossVectors(T[0], D), T[4].normalize(), T[8] = T[0].clone().negate(), T[12] = T[4].clone().negate(), T[2] = T[0].clone().add(T[4]).normalize(), T[6] = T[4].clone().add(T[8]).normalize(), T[10] = T[8].clone().add(T[12]).normalize(), T[14] = T[12].clone().add(T[0]).normalize(), T[1] = T[0].clone().add(T[2]).normalize(), T[3] = T[2].clone().add(T[4]).normalize(), T[5] = T[4].clone().add(T[6]).normalize(), T[7] = T[6].clone().add(T[8]).normalize(), T[9] = T[8].clone().add(T[10]).normalize(), T[11] = T[10].clone().add(T[12]).normalize(), T[13] = T[12].clone().add(T[14]).normalize(), T[15] = T[14].clone().add(T[0]).normalize();
+ var B = x.vertices, W = x.vertexArray, k = x.faceArray, F = x.normalArray, U = x.lineArray, V, H, G;
+ for (H = 0, G = T.length; H < G; ++H) {
+ V = 3 * (B + 3 * H);
+ var Y = T[H].clone().multiplyScalar(e).add(o), J = T[H].clone().multiplyScalar(e).add(O), re = T[H].clone().multiplyScalar(e * n).add(O);
+ if (W[V] = Y.x, W[V + 1] = Y.y, W[V + 2] = Y.z, W[V + 3] = J.x, W[V + 4] = J.y, W[V + 5] = J.z, W[V + 6] = re.x, W[V + 7] = re.y, W[V + 8] = re.z, H > 0) {
+ var le = W[V - 3], ie = W[V - 2], xe = W[V - 1], se = new E.Vector3(le, ie, xe), ce = new E.Vector3(l.x, l.y, l.z), Ee = O.clone(), be = new E.Vector3(re.x, re.y, re.z);
+ t.intersectionShape.triangle.push(new M.Triangle(be, ce, se)), t.intersectionShape.triangle.push(new M.Triangle(se.clone(), Ee, be.clone()));
+ }
+ }
+ x.vertices += 48, V = x.vertices * 3, W[V] = o.x, W[V + 1] = o.y, W[V + 2] = o.z, W[V + 3] = O.x, W[V + 4] = O.y, W[V + 5] = O.z, W[V + 6] = l.x, W[V + 7] = l.y, W[V + 8] = l.z, x.vertices += 3;
+ var Le, ae, pe, we, Ge, We, je, Fe, ze, Be, Ie, Te, Re, ke, Ne, X, K, q, fe, ue = x.vertices - 3, De = x.vertices - 2, Se = x.vertices - 1, Z = ue * 3, de = De * 3, me = Se * 3;
+ for (H = 0, G = T.length - 1; H < G; ++H) {
+ var Pe = B + 3 * H;
+ V = Pe * 3, ae = x.faceidx, pe = x.lineidx, we = Pe, Be = we * 3, Ge = Pe + 1, Ie = Ge * 3, We = Pe + 2, Te = We * 3, je = Pe + 4, Re = je * 3, Fe = Pe + 5, ke = Fe * 3, ze = Pe + 3, Ne = ze * 3, X = K = T[H], q = fe = T[H + 1], F[Be] = X.x, F[Ie] = K.x, F[Ne] = fe.x, F[Be + 1] = X.y, F[Ie + 1] = K.y, F[Ne + 1] = fe.y, F[Be + 2] = X.z, F[Ie + 2] = K.z, F[Ne + 2] = fe.z, F[Ie] = K.x, F[Re] = q.x, F[Ne] = fe.x, F[Ie + 1] = K.y, F[Re + 1] = q.y, F[Ne + 1] = fe.y, F[Ie + 2] = K.z, F[Re + 2] = q.z, F[Ne + 2] = fe.z, F[Te] = K.x, F[ke] = q.x, F[Te + 1] = K.y, F[ke + 1] = q.y, F[Te + 2] = K.z, F[ke + 2] = q.z, k[ae] = we, k[ae + 1] = Ge, k[ae + 2] = ze, k[ae + 3] = Ge, k[ae + 4] = je, k[ae + 5] = ze, k[ae + 6] = we, k[ae + 7] = ze, k[ae + 8] = ue, k[ae + 9] = We, k[ae + 10] = De, k[ae + 11] = Fe, k[ae + 12] = We, k[ae + 13] = Se, k[ae + 14] = Fe, U[pe] = we, U[pe + 1] = Ge, U[pe + 2] = we, U[pe + 3] = ze, U[pe + 4] = je, U[pe + 5] = ze, U[pe + 6] = we, U[pe + 7] = ze, U[pe + 8] = We, U[pe + 9] = Ge, U[pe + 10] = We, U[pe + 11] = Fe, U[pe + 12] = je, U[pe + 13] = Fe, U[pe + 14] = We, U[pe + 15] = Se, U[pe + 16] = We, U[pe + 17] = Fe, U[pe + 18] = Se, U[pe + 19] = Fe, x.faceidx += 15, x.lineidx += 20;
+ }
+ Le = [
+ B + 45,
+ B + 46,
+ B + 1,
+ B,
+ B + 47,
+ B + 2
+ ], ae = x.faceidx, pe = x.lineidx, we = Le[0], Be = we * 3, Ge = Le[1], Ie = Ge * 3, We = Le[4], Te = We * 3, je = Le[2], Re = je * 3, Fe = Le[5], ke = Fe * 3, ze = Le[3], Ne = ze * 3, X = K = T[15], q = fe = T[0], F[Be] = X.x, F[Ie] = K.x, F[Ne] = fe.x, F[Be + 1] = X.y, F[Ie + 1] = K.y, F[Ne + 1] = fe.y, F[Be + 2] = X.z, F[Ie + 2] = K.z, F[Ne + 2] = fe.z, F[Ie] = K.x, F[Re] = q.x, F[Ne] = fe.x, F[Ie + 1] = K.y, F[Re + 1] = q.y, F[Ne + 1] = fe.y, F[Ie + 2] = K.z, F[Re + 2] = q.z, F[Ne + 2] = fe.z, F[Te] = K.x, F[ke] = q.x, F[Te + 1] = K.y, F[ke + 1] = q.y, F[Te + 2] = K.z, F[ke + 2] = q.z, D.normalize(), R.normalize(), F[Z] = R.x, F[de] = F[me] = D.x, F[Z + 1] = R.y, F[de + 1] = F[me + 1] = D.y, F[Z + 2] = R.z, F[de + 2] = F[me + 2] = D.z, k[ae] = we, k[ae + 1] = Ge, k[ae + 2] = ze, k[ae + 3] = Ge, k[ae + 4] = je, k[ae + 5] = ze, k[ae + 6] = we, k[ae + 7] = ze, k[ae + 8] = ue, k[ae + 9] = We, k[ae + 10] = De, k[ae + 11] = Fe, k[ae + 12] = We, k[ae + 13] = Se, k[ae + 14] = Fe, U[pe] = we, U[pe + 1] = Ge, U[pe + 2] = we, U[pe + 3] = ze, U[pe + 4] = je, U[pe + 5] = ze, U[pe + 6] = we, U[pe + 7] = ze, U[pe + 8] = We, U[pe + 9] = Ge, U[pe + 10] = We, U[pe + 11] = Fe, U[pe + 12] = je, U[pe + 13] = Fe, U[pe + 14] = We, U[pe + 15] = Se, U[pe + 16] = We, U[pe + 17] = Fe, U[pe + 18] = Se, U[pe + 19] = Fe, x.faceidx += 15, x.lineidx += 20;
+ }
+ // Update a bounding sphere's position and radius
+ // from list of centroids and new points
+ /*
+ * @param {Sphere}
+ * sphere
+ * @param {Object}
+ * components, centroid of all objects in shape
+ * @param {Array}
+ * points, flat array of all points in shape
+ * @param {int} numPoints, number of valid poitns in points
+ */
+ static updateBoundingFromPoints(t, r, u, o) {
+ t.center.set(0, 0, 0);
+ let l = 1 / 0, e = 1 / 0, n = 1 / 0, a = -1 / 0, p = -1 / 0, x = -1 / 0;
+ t.box && (l = t.box.min.x, a = t.box.max.x, e = t.box.min.y, p = t.box.max.y, n = t.box.min.z, x = t.box.max.z);
+ for (let z = 0, T = o; z < T; z++) {
+ var D = u[z * 3], O = u[z * 3 + 1], R = u[z * 3 + 2];
+ D < l && (l = D), O < e && (e = O), R < n && (n = R), D > a && (a = D), O > p && (p = O), R > x && (x = R);
+ }
+ t.center.set((a + l) / 2, (p + e) / 2, (x + n) / 2), t.radius = t.center.distanceTo({ x: a, y: p, z: x }), t.box = { min: { x: l, y: e, z: n }, max: { x: a, y: p, z: x } };
+ }
+ //helper function for adding an appropriately sized mesh
+ static addCustomGeo(t, r, u, o, l) {
+ var e = r.addGeoGroup(), n = u.vertexArr, a = u.normalArr, p = u.faceArr;
+ e.vertices = n.length, e.faceidx = p.length;
+ var x, D, O, R, z, T, B, W, k, F = e.vertexArray, U = e.colorArray;
+ for (o.constructor !== Array && (W = o.r, k = o.g, R = o.b), T = 0, B = e.vertices; T < B; ++T)
+ x = T * 3, D = n[T], F[x] = D.x, F[x + 1] = D.y, F[x + 2] = D.z, o.constructor === Array && (z = o[T], W = z.r, k = z.g, R = z.b), U[x] = W, U[x + 1] = k, U[x + 2] = R;
+ if (l)
+ for (T = 0, B = e.faceidx / 3; T < B; ++T) {
+ x = T * 3, O = p[x], R = p[x + 1], z = p[x + 2];
+ var V = new E.Vector3(), H = new E.Vector3(), G = new E.Vector3();
+ t.intersectionShape.triangle.push(new M.Triangle(V.copy(n[O]), H.copy(n[R]), G.copy(n[z])));
+ }
+ if (l) {
+ var Y = new E.Vector3(0, 0, 0), J = 0;
+ for (let ie = 0; ie < r.geometryGroups.length; ie++)
+ Y.add(r.geometryGroups[ie].getCentroid()), J++;
+ Y.divideScalar(J), y.updateBoundingFromPoints(t.boundingSphere, { centroid: Y }, F, e.vertices);
+ }
+ if (e.faceArray = new Uint16Array(p), e.truncateArrayBuffers(!0, !0), a.length < e.vertices)
+ e.setNormals();
+ else {
+ var re = e.normalArray = new Float32Array(e.vertices * 3), le;
+ for (T = 0, B = e.vertices; T < B; ++T)
+ x = T * 3, le = a[T], re[x] = le.x, re[x + 1] = le.y, re[x + 2] = le.z;
+ }
+ e.setLineIndices(), e.lineidx = e.lineArray.length;
+ }
+ /*
+ *
+ * @param {$3Dmol.GLShape}
+ * shape
+ * @param {ShapeSpec}
+ * stylespec
+ * @returns {undefined}
+ */
+ static updateFromStyle(t, r) {
+ typeof r.color < "u" ? (t.color = r.color || new A.Color(), r.color instanceof A.Color || (t.color = A.CC.color(r.color))) : t.color = A.CC.color(0), t.wireframe = !!r.wireframe, t.opacity = r.alpha ? (0, E.clamp)(r.alpha, 0, 1) : 1, typeof r.opacity < "u" && (t.opacity = (0, E.clamp)(r.opacity, 0, 1)), t.side = r.side !== void 0 ? r.side : v.DoubleSide, t.linewidth = typeof r.linewidth > "u" ? 1 : r.linewidth, t.clickable = !!r.clickable, t.callback = (0, S.makeFunction)(r.callback), t.hoverable = !!r.hoverable, t.hover_callback = (0, S.makeFunction)(r.hover_callback), t.unhover_callback = (0, S.makeFunction)(r.unhover_callback), t.hidden = r.hidden, t.frame = r.frame;
+ }
+ /**
+ * Custom renderable shape
+ *
+ * @constructor
+ *
+ * @param {ShapeSpec} stylespec
+ */
+ constructor(t) {
+ this.color = 16777215, this.hidden = !1, this.wireframe = !1, this.opacity = 1, this.linewidth = 1, this.clickable = !1, this.hoverable = !1, this.side = v.DoubleSide, this.stylespec = t || {}, this.boundingSphere = new M.Sphere(), this.intersectionShape = {
+ sphere: [],
+ cylinder: [],
+ line: [],
+ triangle: []
+ }, y.updateFromStyle(this, this.stylespec), this.components = [], this.shapeObj = null, this.renderedShapeObj = null, this.geo = new v.Geometry(!0), this.linegeo = new v.Geometry(!0);
+ }
+ /** Update shape with new style specification
+ * @param {ShapeSpec} newspec
+ @example
+ let sphere = viewer.addSphere({center:{x:0,y:0,z:0},radius:10.0,color:'red'});
+ sphere.updateStyle({color:'yellow',opacity:0.5});
+ viewer.render();
+ */
+ updateStyle(t) {
+ for (var r in t)
+ this.stylespec[r] = t[r];
+ if (y.updateFromStyle(this, this.stylespec), t.voldata && t.volscheme) {
+ (0, S.adjustVolumeStyle)(t);
+ const u = t.volscheme, o = t.voldata, l = A.CC, e = u.range() || [-1, 1];
+ this.geo.setColors(function(n, a, p) {
+ let x = o.getVal(n, a, p);
+ return l.color(u.valueToHex(x, e));
+ }), delete this.color;
+ }
+ }
+ /**
+ * Creates a custom shape from supplied vertex and face arrays
+ * @param {CustomShapeSpec} customSpec
+ */
+ addCustom(t) {
+ t.vertexArr = t.vertexArr || [], t.faceArr = t.faceArr || [], t.normalArr = t.normalArr || [], y.drawCustom(this, this.geo, t);
+ }
+ /**
+ * Creates a sphere shape
+ * @param {SphereSpec} sphereSpec
+ @example
+ viewer.addSphere({center:{x:0,y:0,z:0},radius:10.0,color:'red'});
+
+ viewer.render();
+ */
+ addSphere(t) {
+ t.center || (t.center = new E.Vector3(0, 0, 0)), t.radius = t.radius ? (0, E.clamp)(t.radius, 0, 1 / 0) : 1.5, t.color = A.CC.color(t.color), this.intersectionShape.sphere.push(new M.Sphere(t.center, t.radius)), C.GLDraw.drawSphere(this.geo, t.center, t.radius, t.color, t.quality), this.components.push({
+ centroid: new E.Vector3(t.center.x, t.center.y, t.center.z)
+ });
+ var r = this.geo.updateGeoGroup(0);
+ y.updateBoundingFromPoints(this.boundingSphere, this.components, r.vertexArray, r.vertices);
+ }
+ /**
+ * Creates a box
+ * @param {BoxSpec} boxSpec
+ @example
+ var shape = viewer.addShape({color:'red'});
+ shape.addBox({corner: {x:1,y:2,z:0}, dimensions: {w: 4, h: 2, d: 6}});
+ shape.addBox({corner: {x:-5,y:-3,z:0},
+ dimensions: { w: {x:1,y:1,z:0},
+ h: {x:-1,y:1,z:0},
+ d: {x:0,y:0,z:1} }});
+ viewer.zoomTo();
+ viewer.rotate(30);
+ viewer.render();
+ */
+ addBox(t) {
+ var r = t.dimensions || { w: 1, h: 1, d: 1 }, u;
+ typeof r.w == "number" ? u = { x: r.w, y: 0, z: 0 } : u = r.w;
+ var o;
+ typeof r.h == "number" ? o = { x: 0, y: r.h, z: 0 } : o = r.h;
+ var l;
+ typeof r.d == "number" ? l = { x: 0, y: 0, z: r.d } : l = r.d;
+ var e = t.corner;
+ e == null && (t.center !== void 0 ? e = {
+ x: t.center.x - 0.5 * (u.x + o.x + l.x),
+ y: t.center.y - 0.5 * (u.y + o.y + l.y),
+ z: t.center.z - 0.5 * (u.z + o.z + l.z)
+ } : e = { x: 0, y: 0, z: 0 });
+ var n = [
+ { x: e.x, y: e.y, z: e.z },
+ { x: e.x + u.x, y: e.y + u.y, z: e.z + u.z },
+ { x: e.x + o.x, y: e.y + o.y, z: e.z + o.z },
+ { x: e.x + u.x + o.x, y: e.y + u.y + o.y, z: e.z + u.z + o.z },
+ { x: e.x + l.x, y: e.y + l.y, z: e.z + l.z },
+ { x: e.x + u.x + l.x, y: e.y + u.y + l.y, z: e.z + u.z + l.z },
+ { x: e.x + o.x + l.x, y: e.y + o.y + l.y, z: e.z + o.z + l.z },
+ { x: e.x + u.x + o.x + l.x, y: e.y + u.y + o.y + l.y, z: e.z + u.z + o.z + l.z }
+ ], a = [], p = [];
+ a.splice(a.length, 0, n[0], n[1], n[2], n[3]), p.splice(p.length, 0, 0, 2, 1, 1, 2, 3);
+ var x = 4;
+ a.splice(a.length, 0, n[2], n[3], n[6], n[7]), p.splice(p.length, 0, x + 0, x + 2, x + 1, x + 1, x + 2, x + 3), x += 4, a.splice(a.length, 0, n[4], n[5], n[0], n[1]), p.splice(p.length, 0, x + 0, x + 2, x + 1, x + 1, x + 2, x + 3), x += 4, a.splice(a.length, 0, n[6], n[7], n[4], n[5]), p.splice(p.length, 0, x + 0, x + 2, x + 1, x + 1, x + 2, x + 3), x += 4, a.splice(a.length, 0, n[3], n[1], n[7], n[5]), p.splice(p.length, 0, x + 0, x + 2, x + 1, x + 1, x + 2, x + 3), x += 4, a.splice(a.length, 0, n[2], n[6], n[0], n[4]), p.splice(p.length, 0, x + 0, x + 2, x + 1, x + 1, x + 2, x + 3), x += 4;
+ var D = (0, S.extend)({}, t);
+ D.vertexArr = a, D.faceArr = p, D.normalArr = [], y.drawCustom(this, this.geo, D);
+ var O = new E.Vector3();
+ this.components.push({
+ centroid: O.addVectors(n[0], n[7]).multiplyScalar(0.5)
+ });
+ var R = this.geo.updateGeoGroup(0);
+ y.updateBoundingFromPoints(this.boundingSphere, this.components, R.vertexArray, R.vertices);
+ }
+ /**
+ * Creates a cylinder shape
+ * @param {CylinderSpec} cylinderSpec
+ @example
+ viewer.addCylinder({start:{x:0.0,y:0.0,z:0.0},
+ end:{x:10.0,y:0.0,z:0.0},
+ radius:1.0,
+ fromCap:1,
+ toCap:2,
+ color:'red',
+ hoverable:true,
+ clickable:true,
+ callback:function(){ this.color.setHex(0x00FFFF00);viewer.render( );},
+ hover_callback: function(){ viewer.render( );},
+ unhover_callback: function(){ this.color.setHex(0xFF000000);viewer.render( );}
+ });
+ viewer.addCylinder({start:{x:0.0,y:2.0,z:0.0},
+ end:{x:0.0,y:10.0,z:0.0},
+ radius:0.5,
+ fromCap:false,
+ toCap:true,
+ color:'teal'});
+ viewer.addCylinder({start:{x:15.0,y:0.0,z:0.0},
+ end:{x:20.0,y:0.0,z:0.0},
+ radius:1.0,
+ color:'black',
+ fromCap:false,
+ toCap:false});
+ viewer.render();
+ */
+ addCylinder(t) {
+ var r, u;
+ t.start ? r = new E.Vector3(t.start.x || 0, t.start.y || 0, t.start.z || 0) : r = new E.Vector3(0, 0, 0), t.end ? (u = new E.Vector3(t.end.x, t.end.y || 0, t.end.z || 0), typeof u.x > "u" && (u.x = 3)) : u = new E.Vector3(0, 0, 0);
+ var o = t.radius || 0.1, l = A.CC.color(t.color);
+ this.intersectionShape.cylinder.push(new M.Cylinder(r, u, o)), C.GLDraw.drawCylinder(this.geo, r, u, o, l, t.fromCap, t.toCap);
+ var e = new E.Vector3();
+ this.components.push({
+ centroid: e.addVectors(r, u).multiplyScalar(0.5)
+ });
+ var n = this.geo.updateGeoGroup(0);
+ y.updateBoundingFromPoints(this.boundingSphere, this.components, n.vertexArray, n.vertices);
+ }
+ /**
+ * Creates a dashed cylinder shape
+ * @param {CylinderSpec} cylinderSpec
+ */
+ addDashedCylinder(t) {
+ t.dashLength = t.dashLength || 0.25, t.gapLength = t.gapLength || 0.25;
+ var r;
+ t.start ? r = new E.Vector3(t.start.x || 0, t.start.y || 0, t.start.z || 0) : r = new E.Vector3(0, 0, 0);
+ var u;
+ t.end ? (u = new E.Vector3(t.end.x, t.end.y || 0, t.end.z || 0), typeof u.x > "u" && (u.x = 3)) : u = new E.Vector3(3, 0, 0);
+ for (var o = t.radius || 0.1, l = A.CC.color(t.color), e = Math.sqrt(Math.pow(r.x - u.x, 2) + Math.pow(r.y - u.y, 2) + Math.pow(r.z - u.z, 2)), n = e / (t.gapLength + t.dashLength), a = new E.Vector3(t.start.x || 0, t.start.y || 0, t.start.z || 0), p = new E.Vector3(t.end.x, t.end.y || 0, t.end.z || 0), x = new E.Vector3((u.x - r.x) / (e / t.gapLength), (u.y - r.y) / (e / t.gapLength), (u.z - r.z) / (e / t.gapLength)), D = new E.Vector3((u.x - r.x) / (e / t.dashLength), (u.y - r.y) / (e / t.dashLength), (u.z - r.z) / (e / t.dashLength)), O = 0; O < n; O++)
+ p = new E.Vector3(a.x + D.x, a.y + D.y, a.z + D.z), this.intersectionShape.cylinder.push(new M.Cylinder(a, p, o)), C.GLDraw.drawCylinder(this.geo, a, p, o, l, t.fromCap, t.toCap), a = new E.Vector3(p.x + x.x, p.y + x.y, p.z + x.z);
+ var R = new E.Vector3();
+ this.components.push({
+ centroid: R.addVectors(r, u).multiplyScalar(0.5)
+ });
+ var z = this.geo.updateGeoGroup(0);
+ y.updateBoundingFromPoints(this.boundingSphere, this.components, z.vertexArray, z.vertices);
+ }
+ /**
+ * Creates a curved shape
+ * @param {CurveSpec} curveSpec
+ */
+ addCurve(t) {
+ t.points = t.points || [], t.smooth = t.smooth || 10, typeof t.fromCap > "u" && (t.fromCap = 2), typeof t.toCap > "u" && (t.toCap = 2);
+ var r = (0, c.subdivide_spline)(t.points, t.smooth);
+ if (r.length < 3) {
+ console.log("Too few points in addCurve");
+ return;
+ }
+ var u = t.radius || 0.1, o = A.CC.color(t.color), l = 0, e = r.length - 1, n = r[0].distanceTo(r[1]), a = Math.ceil(2 * u / n);
+ if (t.toArrow) {
+ e -= a;
+ let O = {
+ start: r[e],
+ end: r[r.length - 1],
+ radius: u,
+ color: o,
+ mid: 1e-4
+ };
+ this.addArrow(O);
+ }
+ if (t.fromArrow) {
+ l += a;
+ let O = {
+ start: r[l],
+ end: r[0],
+ radius: u,
+ color: o,
+ mid: 1e-4
+ };
+ this.addArrow(O);
+ }
+ for (var p = Math.ceil(r.length / 2), x = { radius: u, color: o, fromCap: 2, toCap: 2 }, D = l; D < e; D++)
+ x.start = r[D], x.end = r[D + 1], x.fromCap = 2, x.toCap = 2, D < p ? (x.fromCap = 2, x.toCap = 0) : D > p ? (x.fromCap = 0, x.toCap = 2) : (x.fromCap = 2, x.toCap = 2), this.addCylinder(x);
+ }
+ /**
+ * Creates a line shape
+ * @param {LineSpec} lineSpec
+ @example
+ $3Dmol.download("pdb:2ABJ",viewer,{},function(){
+ viewer.addLine({dashed:true,start:{x:0,y:0,z:0},end:{x:100,y:100,z:100}});
+ viewer.render(callback);
+ });
+
+ */
+ addLine(t) {
+ var r, u;
+ t.start ? r = new E.Vector3(t.start.x || 0, t.start.y || 0, t.start.z || 0) : r = new E.Vector3(0, 0, 0), t.end ? (u = new E.Vector3(t.end.x, t.end.y || 0, t.end.z || 0), typeof u.x > "u" && (u.x = 3)) : u = new E.Vector3(3, 0, 0);
+ var o = this.geo.updateGeoGroup(2), l = o.vertices, e = l * 3, n = o.vertexArray;
+ n[e] = r.x, n[e + 1] = r.y, n[e + 2] = r.z, n[e + 3] = u.x, n[e + 4] = u.y, n[e + 5] = u.z, o.vertices += 2;
+ var a = o.lineArray, p = o.lineidx;
+ a[p] = l, a[p + 1] = l + 1, o.lineidx += 2;
+ var x = new E.Vector3();
+ this.components.push({
+ centroid: x.addVectors(r, u).multiplyScalar(0.5)
+ }), o = this.geo.updateGeoGroup(0), y.updateBoundingFromPoints(this.boundingSphere, this.components, o.vertexArray, o.vertices);
+ }
+ /**
+ * Creates an arrow shape
+ * @param {ArrowSpec} arrowSpec
+ @example
+ $3Dmol.download("pdb:4DM7",viewer,{},function(){
+ viewer.setBackgroundColor(0xffffffff);
+ viewer.addArrow({
+ start: {x:-10.0, y:0.0, z:0.0},
+ end: {x:0.0, y:-10.0, z:0.0},
+ radius: 1.0,
+ radiusRadio:1.0,
+ mid:1.0,
+ clickable:true,
+ callback:function(){
+ this.color.setHex(0xFF0000FF);
+ viewer.render( );
+ }
+ });
+ viewer.render();
+ });
+ */
+ addArrow(t) {
+ if (t.start ? t.start = new E.Vector3(t.start.x || 0, t.start.y || 0, t.start.z || 0) : t.start = new E.Vector3(0, 0, 0), t.dir instanceof E.Vector3 && typeof t.length == "number") {
+ var r = t.dir.clone().multiplyScalar(t.length).add(t.start);
+ t.end = r;
+ } else
+ t.end ? (t.end = new E.Vector3(t.end.x, t.end.y || 0, t.end.z || 0), typeof t.end.x > "u" && (t.end.x = 3)) : t.end = new E.Vector3(3, 0, 0);
+ t.radius = t.radius || 0.1, t.radiusRatio = t.radiusRatio || 1.618034, t.mid = 0 < t.mid && t.mid < 1 ? t.mid : 0.618034, y.drawArrow(this, this.geo, t);
+ var u = new E.Vector3();
+ this.components.push({
+ centroid: u.addVectors(t.start, t.end).multiplyScalar(0.5)
+ });
+ var o = this.geo.updateGeoGroup(0);
+ y.updateBoundingFromPoints(this.boundingSphere, this.components, o.vertexArray, o.vertices);
+ }
+ static distance_from(t, r) {
+ return Math.sqrt(Math.pow(t.x - r.x, 2) + Math.pow(t.y - r.y, 2) + Math.pow(t.z - r.z, 2));
+ }
+ static inSelectedRegion(t, r, u) {
+ for (var o = 0; o < r.length; o++)
+ if (y.distance_from(r[o], t) <= u)
+ return !0;
+ return !1;
+ }
+ /**
+ * Create isosurface from voluemetric data.
+ * @param {VolumeData} data - volumetric input data
+ * @param {IsoSurfaceSpec} isoSpec - volumetric data shape specification
+ * @example //the user can specify a selected region for the isosurface
+ $.get('../test_structs/benzene-homo.cube', function(data){
+ var voldata = new $3Dmol.VolumeData(data, "cube");
+ viewer.addIsosurface(voldata, {isoval: 0.01,
+ color: "blue",
+ alpha: 0.5,
+ smoothness: 10});
+ viewer.addIsosurface(voldata, {isoval: -0.01,
+ color: "red",
+ smoothness: 5,
+ opacity:0.5,
+ wireframe:true,
+ clickable:true,
+ callback:
+ function() {
+ this.opacity = 0.0;
+ viewer.render( );
+ }});
+ viewer.setStyle({}, {stick:{}});
+ viewer.zoomTo();
+ viewer.render();
+ });
+ */
+ addIsosurface(t, r, u) {
+ var o = r.isoval !== void 0 && typeof r.isoval == "number" ? r.isoval : 0, l = !!r.voxel, e = r.smoothness === void 0 ? 1 : r.smoothness, n = t.size.x, a = t.size.y, p = t.size.z, x = new Int16Array(n * a * p), D = t.data, O, R;
+ for (O = 0, R = x.length; O < R; ++O)
+ x[O] = -1;
+ var z = new Uint8Array(n * a * p);
+ for (O = 0, R = D.length; O < R; ++O) {
+ var T = o >= 0 ? D[O] - o : o - D[O];
+ T > 0 && (z[O] |= y.ISDONE);
+ }
+ var B = [], W = [];
+ h.MarchingCube.march(z, B, W, {
+ fulltable: !0,
+ voxel: l,
+ unitCube: t.unit,
+ origin: t.origin,
+ matrix: t.matrix,
+ nX: n,
+ nY: a,
+ nZ: p
+ }), !l && e > 0 && h.MarchingCube.laplacianSmooth(e, B, W);
+ var k = [], F = [], U = [];
+ if (r.selectedRegion && r.coords === void 0 && (r.coords = r.selectedRegion), r.coords !== void 0) {
+ var V = r.coords[0].x, H = r.coords[0].y, G = r.coords[0].z, Y = r.coords[0].x, J = r.coords[0].y, re = r.coords[0].z;
+ for (let ae = 0; ae < r.coords.length; ae++)
+ r.coords[ae].x > V ? V = r.coords[ae].x : r.coords[ae].x < Y && (Y = r.coords[ae].x), r.coords[ae].y > H ? H = r.coords[ae].y : r.coords[ae].y < J && (J = r.coords[ae].y), r.coords[ae].z > G ? G = r.coords[ae].z : r.coords[ae].z < re && (re = r.coords[ae].z);
+ var le = 2;
+ r.radius !== void 0 && (le = r.radius), r.selectedOffset !== void 0 && (le = r.selectedOffset), r.seldist !== void 0 && (le = r.seldist), Y -= le, V += le, J -= le, H += le, re -= le, G += le;
+ for (let ae = 0; ae < B.length; ae++)
+ B[ae].x > Y && B[ae].x < V && B[ae].y > J && B[ae].y < H && B[ae].z > re && B[ae].z < G && y.inSelectedRegion(B[ae], r.coords, le) ? (k.push(F.length), F.push(B[ae])) : k.push(-1);
+ for (let ae = 0; ae + 2 < W.length; ae += 3)
+ k[W[ae]] !== -1 && k[W[ae + 1]] !== -1 && k[W[ae + 2]] !== -1 && (U.push(W[ae] - (W[ae] - k[W[ae]])), U.push(W[ae + 1] - (W[ae + 1] - k[W[ae + 1]])), U.push(W[ae + 2] - (W[ae + 2] - k[W[ae + 2]])));
+ B = F, W = U;
+ }
+ y.drawCustom(this, this.geo, {
+ vertexArr: B,
+ faceArr: W,
+ normalArr: [],
+ clickable: r.clickable,
+ hoverable: r.hoverable
+ }), this.updateStyle(r);
+ var ie = new E.Vector3(t.origin.x, t.origin.y, t.origin.z), xe = new E.Vector3(t.size.x * t.unit.x, t.size.y * t.unit.y, t.size.z * t.unit.z), se = new E.Vector3(0, 0, 0), ce = ie.clone(), Ee = ie.clone().add(xe);
+ for (let ae = 0; ae < B.length; ae++)
+ se.add(B[ae]), ce.max(B[ae]), Ee.min(B[ae]);
+ se.divideScalar(B.length);
+ var be = se.distanceTo(Ee), Le = se.distanceTo(ce);
+ this.boundingSphere.center = se, this.boundingSphere.radius = Math.max(be, Le), typeof u == "function" && u();
+ }
+ /**
+ * @deprecated Use addIsosurface instead
+ * Creates custom shape from volumetric data
+ * @param {string} data - Volumetric input data
+ * @param {string} fmt - Input data format (e.g. 'cube' for cube file format)
+ * @param {IsoSurfaceSpec} isoSpec - Volumetric data shape specification
+ */
+ addVolumetricData(t, r, u) {
+ t = new g.VolumeData(t, r), this.addIsosurface(t, u);
+ }
+ //for internal use, truncate buffers to save memory
+ finalize() {
+ return y.finalizeGeo(this.geo), this.geo.initTypedArrays(), this.geo;
+ }
+ /*
+ * Initialize webgl objects for rendering
+ * @param {$3Dmol.Object3D} group
+ *
+ */
+ globj(t) {
+ if (this.renderedShapeObj && (t.remove(this.renderedShapeObj), this.renderedShapeObj = null), !this.hidden) {
+ y.finalizeGeo(this.geo), this.geo.initTypedArrays(), this.wireframe && this.geo.setUpWireframe(), typeof this.color < "u" && y.updateColor(this.geo, this.color), this.shapeObj = new v.Object3D();
+ var r = null;
+ this.side == v.DoubleSide ? r = new v.MeshDoubleLambertMaterial({
+ wireframe: this.wireframe,
+ side: this.side,
+ transparent: this.opacity < 1,
+ opacity: this.opacity,
+ wireframeLinewidth: this.linewidth,
+ vertexColors: v.Coloring.VertexColors
+ }) : r = new v.MeshLambertMaterial({
+ wireframe: this.wireframe,
+ side: this.side,
+ transparent: this.opacity < 1,
+ opacity: this.opacity,
+ wireframeLinewidth: this.linewidth,
+ vertexColors: v.Coloring.VertexColors
+ });
+ var u = new v.Mesh(this.geo, r);
+ this.shapeObj.add(u);
+ var o = new v.LineBasicMaterial({
+ linewidth: this.linewidth,
+ color: this.color
+ }), l = new v.Line(this.linegeo, o, v.LineStyle.LinePieces);
+ this.shapeObj.add(l), this.renderedShapeObj = this.shapeObj.clone(), t.add(this.renderedShapeObj);
+ }
+ }
+ removegl(t) {
+ this.renderedShapeObj && (this.renderedShapeObj.geometry !== void 0 && this.renderedShapeObj.geometry.dispose(), this.renderedShapeObj.material !== void 0 && this.renderedShapeObj.material.dispose(), t.remove(this.renderedShapeObj), this.renderedShapeObj = null), this.shapeObj = null;
+ }
+ get position() {
+ return this.boundingSphere.center;
+ }
+ get x() {
+ return this.boundingSphere.center.x;
+ }
+ get y() {
+ return this.boundingSphere.center.y;
+ }
+ get z() {
+ return this.boundingSphere.center.z;
+ }
+ }
+ y.ISDONE = 2, y.drawCustom = function(w, t, r) {
+ var u = r, o = u.vertexArr, l = u.faceArr;
+ (o.length === 0 || l.length === 0) && console.warn("Error adding custom shape component: No vertices and/or face indices supplied!");
+ var e = r.color;
+ typeof e > "u" && (e = w.color), e = A.CC.color(e);
+ for (var n = b(u), a = 0, p = n.length; a < p; a++)
+ y.addCustomGeo(w, t, n[a], n[a].colorArr ? n[a].colorArr : e, r.clickable);
+ };
+ function b(w) {
+ var t = 64e3;
+ if (w.vertexArr.length < t)
+ return [w];
+ var r = [{ vertexArr: [], normalArr: [], faceArr: [] }];
+ w.colorArr && (r.colorArr = []);
+ var u = [], o = [], l = 0, e = w.faceArr;
+ for (let a = 0, p = e.length; a < p; a += 3) {
+ let x = r[l];
+ for (let D = 0; D < 3; D++) {
+ var n = e[a + D];
+ u[n] !== l && (u[n] = l, o[n] = x.vertexArr.length, x.vertexArr.push(w.vertexArr[n]), w.normalArr && w.normalArr[n] && x.normalArr.push(w.normalArr[n]), w.colorArr && w.colorArr[n] && x.colorArr.push(w.colorArr[n])), x.faceArr.push(o[n]);
+ }
+ x.vertexArr.length >= t && (r.push({ vertexArr: [], normalArr: [], faceArr: [] }), w.colorArr && (r.colorArr = []), l++);
+ }
+ return r;
+ }
+ }
+ ),
+ /***/
+ "./src/GLViewer.ts": (
+ /*!*************************!*\
+ !*** ./src/GLViewer.ts ***!
+ \*************************/
+ /***/
+ (P, _, s) => {
+ s.r(_), s.d(_, {
+ /* harmony export */
+ GLViewer: () => (
+ /* binding */
+ t
+ ),
+ /* harmony export */
+ createStereoViewer: () => (
+ /* binding */
+ o
+ ),
+ /* harmony export */
+ createViewer: () => (
+ /* binding */
+ r
+ ),
+ /* harmony export */
+ createViewerGrid: () => (
+ /* binding */
+ u
+ )
+ /* harmony export */
+ });
+ var v = s(
+ /*! ./WebGL */
+ "./src/WebGL/index.ts"
+ ), M = s(
+ /*! ./WebGL/math */
+ "./src/WebGL/math/index.ts"
+ ), E = s(
+ /*! ./colors */
+ "./src/colors.ts"
+ ), A = s(
+ /*! ./utilities */
+ "./src/utilities.ts"
+ ), h = s(
+ /*! ./Gradient */
+ "./src/Gradient.ts"
+ ), g = s(
+ /*! ./GLModel */
+ "./src/GLModel.ts"
+ ), C = s(
+ /*! ./Label */
+ "./src/Label.ts"
+ ), c = s(
+ /*! ./GLShape */
+ "./src/GLShape.ts"
+ ), S = s(
+ /*! ./VolumeData */
+ "./src/VolumeData.ts"
+ ), y = s(
+ /*! ./ProteinSurface4 */
+ "./src/ProteinSurface4.ts"
+ ), b = s(
+ /*! ./VolumetricRender */
+ "./src/VolumetricRender.ts"
+ ), w = s(
+ /*! upng-js */
+ "./node_modules/upng-js/UPNG.js"
+ );
+ class t {
+ //reimplement jquery getwidth/height
+ getRect() {
+ let e = this.container, n = e.getBoundingClientRect();
+ if (n.width == 0 && n.height == 0 && e.style.display === "none") {
+ let a = e.style.position, p = e.style.visibility;
+ e.style.display = "block", e.style.visibility = "hidden", e.style.position = "absolute", n = e.getBoundingClientRect(), e.style.display = "none", e.style.visibility = p, e.style.position = a;
+ }
+ return n;
+ }
+ getWidth() {
+ return this.getRect().width;
+ }
+ getHeight() {
+ return this.getRect().height;
+ }
+ setupRenderer() {
+ this.renderer = new v.Renderer({
+ antialias: this.config.antialias,
+ preserveDrawingBuffer: !0,
+ premultipliedAlpha: !1,
+ id: this.config.id,
+ row: this.config.row,
+ col: this.config.col,
+ rows: this.config.rows,
+ cols: this.config.cols,
+ canvas: this.config.canvas,
+ //cannot initialize with zero size
+ containerWidth: this.WIDTH || 1,
+ containerHeight: this.HEIGHT || 1
+ }), this.renderer.domElement.style.width = "100%", this.renderer.domElement.style.height = "100%", this.renderer.domElement.style.padding = "0", this.renderer.domElement.style.position = "absolute", this.renderer.domElement.style.top = "0px", this.renderer.domElement.style.left = "0px", this.renderer.domElement.style.zIndex = "0";
+ }
+ initializeScene() {
+ this.scene = new v.Scene(), this.scene.fog = new v.Fog(this.bgColor, 100, 200), this.modelGroup = new v.Object3D(), this.rotationGroup = new v.Object3D(), this.rotationGroup.useQuaternion = !0, this.rotationGroup.quaternion = new M.Quaternion(0, 0, 0, 1), this.rotationGroup.add(this.modelGroup), this.scene.add(this.rotationGroup);
+ var e = new v.Light(16777215);
+ e.position = new M.Vector3(0.2, 0.2, 1).normalize(), e.intensity = 1, this.scene.add(e);
+ }
+ initContainer(e) {
+ this.container = e, this.WIDTH = this.getWidth(), this.HEIGHT = this.getHeight(), this.ASPECT = this.renderer.getAspect(this.WIDTH, this.HEIGHT), this.renderer.setSize(this.WIDTH, this.HEIGHT), this.container.append(this.renderer.domElement), this.glDOM = this.renderer.domElement, this.nomouse || (this.glDOM.addEventListener("mousedown", this._handleMouseDown.bind(this), { passive: !1 }), this.glDOM.addEventListener("touchstart", this._handleMouseDown.bind(this), { passive: !1 }), this.glDOM.addEventListener("wheel", this._handleMouseScroll.bind(this), { passive: !1 }), this.glDOM.addEventListener("mousemove", this._handleMouseMove.bind(this), { passive: !1 }), this.glDOM.addEventListener("touchmove", this._handleMouseMove.bind(this), { passive: !1 }), this.glDOM.addEventListener("contextmenu", this._handleContextMenu.bind(this), { passive: !1 }));
+ }
+ decAnim() {
+ this.animated--, this.animated < 0 && (this.animated = 0);
+ }
+ incAnim() {
+ this.animated++;
+ }
+ nextSurfID() {
+ var e = 0;
+ for (let a in this.surfaces)
+ if (this.surfaces.hasOwnProperty(a)) {
+ var n = parseInt(a);
+ isNaN(n) || n > e && (e = n);
+ }
+ return e + 1;
+ }
+ setSlabAndFog() {
+ let e = this.camera.position.z - this.rotationGroup.position.z;
+ e < 1 && (e = 1), this.camera.near = e + this.slabNear, this.camera.near < 1 && (this.camera.near = 1), this.camera.far = e + this.slabFar, this.camera.near + 1 > this.camera.far && (this.camera.far = this.camera.near + 1), this.camera.fov = this.fov, this.camera.right = e * Math.tan(Math.PI / 180 * this.fov), this.camera.left = -this.camera.right, this.camera.top = this.camera.right / this.ASPECT, this.camera.bottom = -this.camera.top, this.camera.updateProjectionMatrix(), this.scene.fog.near = this.camera.near + this.fogStart * (this.camera.far - this.camera.near), this.scene.fog.far = this.camera.far, this.config.disableFog && (this.scene.fog.near = this.scene.fog.far);
+ }
+ // display scene
+ //if nolink is set/true, don't propagate changes to linked viewers
+ show(e) {
+ if (this.renderer.setViewport(), !!this.scene && (this.setSlabAndFog(), this.renderer.render(this.scene, this.camera), this.viewChangeCallback && this.viewChangeCallback(this._viewer.getView()), !e && this.linkedViewers.length > 0))
+ for (var n = this._viewer.getView(), a = 0; a < this.linkedViewers.length; a++) {
+ var p = this.linkedViewers[a];
+ p.setView(n, !0);
+ }
+ }
+ //regenerate the list of clickables
+ //also updates hoverables
+ updateClickables() {
+ this.clickables.splice(0, this.clickables.length), this.hoverables.splice(0, this.hoverables.length), this.contextMenuEnabledAtoms.splice(0, this.contextMenuEnabledAtoms.length);
+ for (let e = 0, n = this.models.length; e < n; e++) {
+ let a = this.models[e];
+ if (a) {
+ let p = a.selectedAtoms({
+ clickable: !0
+ }), x = a.selectedAtoms({
+ hoverable: !0
+ }), D = a.selectedAtoms({ contextMenuEnabled: !0 });
+ for (let O = 0; O < x.length; O++)
+ this.hoverables.push(x[O]);
+ for (let O = 0; O < p.length; O++)
+ this.clickables.push(p[O]);
+ for (let O = 0; O < D.length; O++)
+ this.contextMenuEnabledAtoms.push(D[O]);
+ }
+ }
+ for (let e = 0, n = this.shapes.length; e < n; e++) {
+ let a = this.shapes[e];
+ a && a.clickable && this.clickables.push(a), a && a.hoverable && this.hoverables.push(a);
+ }
+ }
+ // Checks for selection intersects on mousedown
+ handleClickSelection(e, n, a) {
+ let p = this.targetedObjects(e, n, this.clickables);
+ if (p.length) {
+ var x = p[0].clickable;
+ x.callback !== void 0 && (typeof x.callback != "function" && (x.callback = (0, A.makeFunction)(x.callback)), typeof x.callback == "function" && x.callback(x, this._viewer, a, this.container, p));
+ }
+ }
+ //return offset of container
+ canvasOffset() {
+ let e = this.glDOM, n = e.getBoundingClientRect(), a = e.ownerDocument, p = a.documentElement, x = a.defaultView;
+ return {
+ top: n.top + x.pageYOffset - p.clientTop,
+ left: n.left + x.pageXOffset - p.clientLeft
+ };
+ }
+ //set current_hover to sel (which can be null), calling appropraite callbacks
+ setHover(e, n, a) {
+ this.current_hover != e && (this.current_hover && (typeof this.current_hover.unhover_callback != "function" && (this.current_hover.unhover_callback = (0, A.makeFunction)(this.current_hover.unhover_callback)), this.current_hover.unhover_callback(this.current_hover, this._viewer, n, this.container, a)), this.current_hover = e, e && e.hover_callback !== void 0 && (typeof e.hover_callback != "function" && (e.hover_callback = (0, A.makeFunction)(e.hover_callback)), typeof e.hover_callback == "function" && e.hover_callback(e, this._viewer, n, this.container, a)));
+ }
+ //checks for selection intersects on hover
+ handleHoverSelection(e, n, a) {
+ if (this.hoverables.length == 0)
+ return;
+ let p = this.targetedObjects(e, n, this.hoverables);
+ if (p.length) {
+ var x = p[0].clickable;
+ this.setHover(x, a, p), this.current_hover = x;
+ } else
+ this.setHover(null);
+ }
+ //sees if the mouse is still on the object that invoked a hover event and if not then the unhover callback is called
+ handleHoverContinue(e, n) {
+ let a = this.targetedObjects(e, n, this.hoverables);
+ (a.length == 0 || a[0] === void 0) && this.setHover(null), a[0] !== void 0 && a[0].clickable !== this.current_hover && this.setHover(null);
+ }
+ /**
+ * Determine if a positioned event is "close enough" to mouseStart to be considered a click.
+ * With a mouse, the position should be exact, but allow a slight delta for a touch interface.
+ * @param {Event} event
+ * @param {{ allowTolerance, tolerance: number }} options
+ */
+ closeEnoughForClick(e, { allowTolerance: n = e.targetTouches, tolerance: a = 5 } = {}) {
+ const p = this.getX(e), x = this.getY(e);
+ if (n) {
+ const D = Math.abs(p - this.mouseStartX), O = Math.abs(x - this.mouseStartY);
+ return D <= a && O <= a;
+ } else
+ return p === this.mouseStartX && x === this.mouseStartY;
+ }
+ calcTouchDistance(e) {
+ var n = e.targetTouches[0].pageX - e.targetTouches[1].pageX, a = e.targetTouches[0].pageY - e.targetTouches[1].pageY;
+ return Math.hypot(n, a);
+ }
+ //check targetTouches as well
+ getX(e) {
+ var n = e.pageX;
+ return n == null && (n = e.pageX), e.targetTouches && e.targetTouches[0] ? n = e.targetTouches[0].pageX : e.changedTouches && e.changedTouches[0] && (n = e.changedTouches[0].pageX), n;
+ }
+ getY(e) {
+ var n = e.pageY;
+ return n == null && (n = e.pageY), e.targetTouches && e.targetTouches[0] ? n = e.targetTouches[0].pageY : e.changedTouches && e.changedTouches[0] && (n = e.changedTouches[0].pageY), n;
+ }
+ //for grid viewers, return true if point is in this viewer
+ isInViewer(e, n) {
+ if (this.viewers != null) {
+ var a = this.WIDTH / this.cols, p = this.HEIGHT / this.rows, x = this.canvasOffset(), D = e - x.left, O = n - x.top, R = this.rows - Math.floor(O / p) - 1, z = Math.floor(D / a);
+ if (R != this.row || z != this.col)
+ return !1;
+ }
+ return !0;
+ }
+ //if the user has specify zoom limits, readjust to fit within them
+ //also, make sure we don't go past CAMERA_Z
+ adjustZoomToLimits(e) {
+ if (this.config.lowerZoomLimit && this.config.lowerZoomLimit > 0) {
+ let n = this.CAMERA_Z - this.config.lowerZoomLimit;
+ e > n && (e = n);
+ }
+ if (this.config.upperZoomLimit && this.config.upperZoomLimit > 0) {
+ let n = this.CAMERA_Z - this.config.upperZoomLimit;
+ e < n && (e = n);
+ }
+ return e > this.CAMERA_Z - 1 && (e = this.CAMERA_Z - 1), e;
+ }
+ //interpolate between two normalized quaternions (t between 0 and 1)
+ //https://en.wikipedia.org/wiki/Slerp
+ static slerp(e, n, a) {
+ if (a == 1)
+ return n.clone();
+ if (a == 0)
+ return e.clone();
+ let p = e.x * n.x + e.y * n.y + e.z * n.z + e.w * n.w;
+ if (p > 0.9995) {
+ let B = new M.Quaternion(e.x + a * (n.x - e.x), e.y + a * (n.y - e.y), e.z + a * (n.z - e.z), e.w + a * (n.w - e.w));
+ return B.normalize(), B;
+ }
+ p < 0 && (n = n.clone().multiplyScalar(-1), p = -p), p > 1 ? p = 1 : p < -1 && (p = -1);
+ var x = Math.acos(p), D = x * a, O = n.clone();
+ O.sub(e.clone().multiplyScalar(p)), O.normalize();
+ var R = Math.cos(D), z = Math.sin(D), T = new M.Quaternion(e.x * R + O.x * z, e.y * R + O.y * z, e.z * R + O.z * z, e.w * R + O.w * z);
+ return T.normalize(), T;
+ }
+ /* @param {Object} element HTML element within which to create viewer
+ * @param {ViewerSpec} config Object containing optional configuration for the viewer
+ */
+ constructor(e, n = {}) {
+ this.nomouse = !1, this.glDOM = null, this.models = [], this.surfaces = {}, this.shapes = [], this.labels = [], this.clickables = [], this.hoverables = [], this.contextMenuEnabledAtoms = [], this.current_hover = null, this.hoverDuration = 500, this.viewer_frame = 0, this.viewChangeCallback = null, this.stateChangeCallback = null, this.NEAR = 1, this.FAR = 800, this.CAMERA_Z = 150, this.fov = 20, this.linkedViewers = [], this.renderer = null, this.control_all = !1, this.scene = null, this.rotationGroup = null, this.modelGroup = null, this.fogStart = 0.4, this.slabNear = -50, this.slabFar = 50, this.cq = new M.Quaternion(0, 0, 0, 1), this.dq = new M.Quaternion(0, 0, 0, 1), this.animated = 0, this.animationTimers = /* @__PURE__ */ new Set(), this.isDragging = !1, this.mouseStartX = 0, this.mouseStartY = 0, this.touchDistanceStart = 0, this.touchHold = !1, this.currentModelPos = 0, this.cz = 0, this.cslabNear = 0, this.cslabFar = 0, this.userContextMenuHandler = null, this.config = n, this.callback = this.config.callback, this.defaultcolors = this.config.defaultcolors, this.defaultcolors || (this.defaultcolors = E.elementColors.defaultColors), this.nomouse = this.config.nomouse, this.bgColor = 0, this.config.backgroundColor = this.config.backgroundColor || "#ffffff", typeof this.config.backgroundColor < "u" && (this.bgColor = E.CC.color(this.config.backgroundColor).getHex()), this.config.backgroundAlpha = this.config.backgroundAlpha == null ? 1 : this.config.backgroundAlpha, this.camerax = 0, typeof this.config.camerax < "u" && (this.camerax = parseFloat(this.config.camerax)), this._viewer = this, this.container = e, this.config.hoverDuration != null && (this.hoverDuration = this.config.hoverDuration), this.config.antialias === void 0 && (this.config.antialias = !0), this.config.cartoonQuality === void 0 && (this.config.cartoonQuality = 10), this.WIDTH = this.getWidth(), this.HEIGHT = this.getHeight(), this.setupRenderer(), this.row = this.config.row == null ? 0 : this.config.row, this.col = this.config.col == null ? 0 : this.config.col, this.cols = this.config.cols, this.rows = this.config.rows, this.viewers = this.config.viewers, this.control_all = this.config.control_all, this.ASPECT = this.renderer.getAspect(this.WIDTH, this.HEIGHT), this.camera = new v.Camera(this.fov, this.ASPECT, this.NEAR, this.FAR, this.config.orthographic), this.camera.position = new M.Vector3(this.camerax, 0, this.CAMERA_Z), this.lookingAt = new M.Vector3(), this.camera.lookAt(this.lookingAt), this.raycaster = new v.Raycaster(new M.Vector3(0, 0, 0), new M.Vector3(0, 0, 0)), this.projector = new v.Projector(), this.initializeScene(), this.renderer.setClearColorHex(this.bgColor, this.config.backgroundAlpha), this.scene.fog.color = E.CC.color(this.bgColor), document.body.addEventListener("mouseup", this._handleMouseUp.bind(this)), document.body.addEventListener("touchend", this._handleMouseUp.bind(this)), this.initContainer(this.container), this.config.style && this.setViewStyle(this.config), window.addEventListener("resize", this.resize.bind(this)), typeof window.ResizeObserver < "u" && (this.divwatcher = new window.ResizeObserver(this.resize.bind(this)), this.divwatcher.observe(this.container));
+ try {
+ typeof this.callback == "function" && this.callback(this);
+ } catch (a) {
+ console.log("error with glviewer callback: " + a);
+ }
+ }
+ /**
+ * Return a list of objects that intersect that at the specified viewer position.
+ *
+ * @param x - x position in screen coordinates
+ * @param y - y position in screen coordinates
+ * @param {Object[]} - list of objects or selection object specifying what object to check for targeting
+ */
+ targetedObjects(e, n, a) {
+ var p = {
+ x: e,
+ y: n,
+ z: -1
+ };
+ return Array.isArray(a) || (a = this.selectedAtoms(a)), a.length == 0 ? [] : (this.raycaster.setFromCamera(p, this.camera), this.raycaster.intersectObjects(this.modelGroup, a));
+ }
+ /** Convert model coordinates to screen coordinates.
+ * @param {object | list} - an object or list of objects with x,y,z attributes (e.g. an atom)
+ * @return {object | list} - and object or list of {x: screenX, y: screenY}
+ */
+ modelToScreen(e) {
+ let n = !1;
+ Array.isArray(e) || (e = [e], n = !0);
+ let a = this.renderer.getXRatio(), p = this.renderer.getYRatio(), x = this.col, D = this.row, O = x * (this.WIDTH / a), R = (p - D - 1) * (this.HEIGHT / p), z = [], T = this.canvasOffset();
+ return e.forEach((B) => {
+ let W = new M.Vector3(B.x, B.y, B.z);
+ W.applyMatrix4(this.modelGroup.matrixWorld), this.projector.projectVector(W, this.camera);
+ let k = this.WIDTH / a * (W.x + 1) / 2 + T.left + O, F = -(this.HEIGHT / p) * (W.y - 1) / 2 + T.top + R;
+ z.push({ x: k, y: F });
+ }), n && (z = z[0]), z;
+ }
+ /**
+ * For a given screen (x,y) displacement return model displacement
+ * @param{x} x displacement in screen coordinates
+ * @param{y} y displacement in screen corodinates
+ * @param{modelz} z coordinate in model coordinates to compute offset for, default is model axis
+ */
+ screenOffsetToModel(e, n, a) {
+ var p = e / this.WIDTH, x = n / this.HEIGHT, D = a === void 0 ? this.rotationGroup.position.z : a, O = this.rotationGroup.quaternion, R = new M.Vector3(0, 0, D);
+ return this.projector.projectVector(R, this.camera), R.x += p * 2, R.y -= x * 2, this.projector.unprojectVector(R, this.camera), R.z = 0, R.applyQuaternion(O), R;
+ }
+ /**
+ * Distance from screen coordinate to model coordinate assuming screen point
+ * is projected to the same depth as model coordinate
+ * @param{screen} xy screen coordinate
+ * @param{model} xyz model coordinate
+ */
+ screenToModelDistance(e, n) {
+ let a = this.canvasOffset(), p = new M.Vector3(n.x, n.y, n.z);
+ p.applyMatrix4(this.modelGroup.matrixWorld);
+ let x = p.clone();
+ this.projector.projectVector(p, this.camera);
+ let D = new M.Vector3((e.x - a.left) * 2 / this.WIDTH - 1, (e.y - a.top) * 2 / -this.HEIGHT + 1, p.z);
+ return this.projector.unprojectVector(D, this.camera), D.distanceTo(x);
+ }
+ /**
+ * Set a callback to call when the view has potentially changed.
+ *
+ */
+ setViewChangeCallback(e) {
+ (typeof e == "function" || e == null) && (this.viewChangeCallback = e);
+ }
+ /**
+ * Set a callback to call when the view has potentially changed.
+ *
+ */
+ setStateChangeCallback(e) {
+ (typeof e == "function" || e == null) && (this.stateChangeCallback = e);
+ }
+ /**
+ * Return configuration of viewer
+ */
+ getConfig() {
+ return this.config;
+ }
+ /**
+ * Set the configuration object. Note that some setting may only
+ * have an effect at viewer creation time.
+ */
+ setConfig(e) {
+ this.config = e;
+ }
+ /**
+ * Return object representing internal state of
+ * the viewer appropriate for passing to setInternalState
+ *
+ */
+ getInternalState() {
+ var e = { models: [], surfaces: [], shapes: [], labels: [] };
+ for (let n = 0; n < this.models.length; n++)
+ this.models[n] && (e.models[n] = this.models[n].getInternalState());
+ return e;
+ }
+ /**
+ * Overwrite internal state of the viewer with passed object
+ * which should come from getInternalState.
+ *
+ */
+ setInternalState(e) {
+ this.clear();
+ var n = e.models;
+ for (let a = 0; a < n.length; a++)
+ n[a] && (this.models[a] = new g.GLModel(a), this.models[a].setInternalState(n[a]));
+ this.render();
+ }
+ /**
+ * Set lower and upper limit stops for zoom.
+ *
+ * @param {lower} - limit on zoom in (positive number). Default 0.
+ * @param {upper} - limit on zoom out (positive number). Default infinite.
+ * @example
+ $3Dmol.get("data/set1_122_complex.mol2", function(moldata) {
+ var m = viewer.addModel(moldata);
+ viewer.setStyle({stick:{colorscheme:"Jmol"}});
+ viewer.setZoomLimits(100,200);
+ viewer.zoomTo();
+ viewer.zoom(10); //will not zoom all the way
+ viewer.render();
+ });
+ */
+ setZoomLimits(e, n) {
+ typeof e < "u" && (this.config.lowerZoomLimit = e), n && (this.config.upperZoomLimit = n), this.rotationGroup.position.z = this.adjustZoomToLimits(this.rotationGroup.position.z), this.show();
+ }
+ /**
+ * Set camera parameters (distance to the origin and field of view)
+ *
+ * @param {parameters} - new camera parameters, with possible fields
+ * being fov for the field of view, z for the
+ * distance to the origin, and orthographic (boolean)
+ * for kind of projection (default false).
+ * @example
+ $3Dmol.get("data/set1_122_complex.mol2", function(data) {
+ var m = viewer.addModel(data);
+ viewer.setStyle({stick:{}});
+ viewer.zoomTo();
+ viewer.setCameraParameters({ fov: 10 , z: 300 });
+ viewer.render();
+ });
+ */
+ setCameraParameters(e) {
+ e.fov !== void 0 && (this.fov = e.fov, this.camera.fov = this.fov), e.z !== void 0 && (this.CAMERA_Z = e.z, this.camera.z = this.CAMERA_Z), e.orthographic !== void 0 && (this.camera.ortho = e.orthographic);
+ }
+ _handleMouseDown(e) {
+ if (e.preventDefault(), !this.scene)
+ return;
+ var n = this.getX(e), a = this.getY(e);
+ if (n === void 0)
+ return;
+ this.isDragging = !0, this.mouseButton = e.which, this.mouseStartX = n, this.mouseStartY = a, this.touchHold = !0, this.touchDistanceStart = 0, e.targetTouches && e.targetTouches.length == 2 && (this.touchDistanceStart = this.calcTouchDistance(e)), this.cq = this.rotationGroup.quaternion.clone(), this.cz = this.rotationGroup.position.z, this.currentModelPos = this.modelGroup.position.clone(), this.cslabNear = this.slabNear, this.cslabFar = this.slabFar;
+ let p = this;
+ setTimeout(function() {
+ e.targetTouches && p.touchHold == !0 && (p.glDOM = p.renderer.domElement, p.glDOM.dispatchEvent(new Event("contextmenu")));
+ }, 1e3);
+ }
+ _handleMouseUp(e) {
+ if (this.touchHold = !1, this.isDragging && this.scene) {
+ var n = this.getX(e), a = this.getY(e);
+ if (this.closeEnoughForClick(e) && this.isInViewer(n, a)) {
+ let p = this.mouseXY(n, a);
+ this.handleClickSelection(p.x, p.y, e);
+ }
+ }
+ this.isDragging = !1;
+ }
+ _handleMouseScroll(e) {
+ if (e.preventDefault(), !!this.scene) {
+ var n = this.getX(e), a = this.getY(e);
+ if (n !== void 0 && !(!this.control_all && !this.isInViewer(n, a))) {
+ var p = (this.CAMERA_Z - this.rotationGroup.position.z) * 0.85, x = 1;
+ if (e.ctrlKey && (x = -1), e.detail)
+ this.rotationGroup.position.z += x * p * e.detail / 10;
+ else if (e.wheelDelta) {
+ let D = e.wheelDelta * 600 / (e.wheelDelta + 600);
+ this.rotationGroup.position.z -= x * p * D / 400;
+ }
+ this.rotationGroup.position.z = this.adjustZoomToLimits(this.rotationGroup.position.z), this.show();
+ }
+ }
+ }
+ /**
+ * Return image URI of viewer contents (base64 encoded). *
+ */
+ pngURI() {
+ return this.getCanvas().toDataURL("image/png");
+ }
+ /**
+ * Return a promise that resolves to an animated PNG image URI of
+ viewer contents (base64 encoded) for nframes of viewer changes.
+ * @return {Promise}
+ */
+ apngURI(e) {
+ let n = this;
+ return e = e || 1, new Promise(function(a) {
+ let p = 0, x = n.viewChangeCallback, D = [], O = [], R = Date.now();
+ n.viewChangeCallback = function() {
+ O.push(Date.now() - R), R = Date.now(), D.push(new Promise((z) => {
+ n.getCanvas().toBlob(function(T) {
+ T.arrayBuffer().then(z);
+ }, "image/png");
+ })), p += 1, p == e && (n.viewChangeCallback = x, Promise.all(D).then((z) => {
+ let T = [];
+ for (let V = 0; V < z.length; V++) {
+ let H = (0, w.decode)(z[V]);
+ T.push((0, w.toRGBA8)(H)[0]);
+ }
+ let B = n.getCanvas().width, W = n.getCanvas().height, k = (0, w.encode)(T, B, W, 0, O), F = new Blob([k], { type: "image/png" }), U = new FileReader();
+ U.onload = function(V) {
+ a(V.target.result);
+ }, U.readAsDataURL(F);
+ }));
+ };
+ });
+ }
+ /**
+ * Return underlying canvas element.
+ */
+ getCanvas() {
+ return this.glDOM;
+ }
+ /**
+ * Return renderer element.
+ */
+ getRenderer() {
+ return this.renderer;
+ }
+ /**
+ * Set the duration of the hover delay
+ *
+ * @param {number}
+ * [hoverDuration] - an optional parameter that denotes
+ * the duration of the hover delay (in milliseconds) before the hover action is called
+ *
+ */
+ setHoverDuration(e) {
+ this.hoverDuration = e;
+ }
+ mouseXY(e, n) {
+ let a = this.canvasOffset(), p = this.renderer.getXRatio(), x = this.renderer.getYRatio(), D = this.col, O = this.row, R = D * (this.WIDTH / p), z = (x - O - 1) * (this.HEIGHT / x), T = (e - a.left - R) / (this.WIDTH / p) * 2 - 1, B = -((n - a.top - z) / (this.HEIGHT / x)) * 2 + 1;
+ return { x: T, y: B };
+ }
+ _handleMouseMove(e) {
+ clearTimeout(this.hoverTimeout), e.preventDefault();
+ let n = this.getX(e), a = this.getY(e);
+ if (n === void 0)
+ return;
+ let p = this.renderer.getXRatio(), x = this.renderer.getYRatio(), D = this.mouseXY(n, a), O = this;
+ this.current_hover !== null && this.handleHoverContinue(D.x, D.y);
+ var R = 0;
+ if (!(!this.control_all && !this.isInViewer(n, a)) && this.scene && (this.hoverables.length > 0 && (this.hoverTimeout = setTimeout(function() {
+ O.handleHoverSelection(D.x, D.y, e);
+ }, this.hoverDuration)), !!this.isDragging)) {
+ var z = (n - this.mouseStartX) / this.WIDTH, T = (a - this.mouseStartY) / this.HEIGHT;
+ if (this.touchDistanceStart != 0 && e.targetTouches && e.targetTouches.length == 2) {
+ var B = this.calcTouchDistance(e);
+ R = 2, T = (B - this.touchDistanceStart) * 2 / (this.WIDTH + this.HEIGHT);
+ } else
+ e.targetTouches && e.targetTouches.length == 3 && (R = 1);
+ z *= p, T *= x;
+ var W = Math.hypot(z, T), k;
+ if (R == 3 || this.mouseButton == 3 && e.ctrlKey)
+ this.slabNear = this.cslabNear + z * 100, this.slabFar = this.cslabFar - T * 100;
+ else if (R == 2 || this.mouseButton == 3 || e.shiftKey)
+ k = (this.CAMERA_Z - this.rotationGroup.position.z) * 0.85, k < 80 && (k = 80), this.rotationGroup.position.z = this.cz + T * k, this.rotationGroup.position.z = this.adjustZoomToLimits(this.rotationGroup.position.z);
+ else if (R == 1 || this.mouseButton == 2 || e.ctrlKey) {
+ var F = this.screenOffsetToModel(p * (n - this.mouseStartX), x * (a - this.mouseStartY));
+ this.modelGroup.position.addVectors(this.currentModelPos, F);
+ } else if ((R === 0 || this.mouseButton == 1) && W !== 0) {
+ var U = Math.sin(W * Math.PI) / W;
+ this.dq.x = Math.cos(W * Math.PI), this.dq.y = 0, this.dq.z = U * z, this.dq.w = -U * T, this.rotationGroup.quaternion.set(1, 0, 0, 0), this.rotationGroup.quaternion.multiply(this.dq), this.rotationGroup.quaternion.multiply(this.cq);
+ }
+ this.show();
+ }
+ }
+ _handleContextMenu(e) {
+ e.preventDefault();
+ var n = this.getX(e), a = this.getY(e);
+ if (!(n != this.mouseStartX || a != this.mouseStartY)) {
+ var D = this.mouseStartX, O = this.mouseStartY, x = this.canvasOffset();
+ let R = this.mouseXY(D, O), z = R.x, T = R.y, B = this.targetedObjects(z, T, this.contextMenuEnabledAtoms);
+ var p = null;
+ B.length && (p = B[0].clickable);
+ var x = this.canvasOffset(), D = this.mouseStartX - x.left, O = this.mouseStartY - x.top;
+ this.userContextMenuHandler && this.userContextMenuHandler(p, D, O, B);
+ }
+ }
+ /**
+ * Change the viewer's container element
+ * Also useful if the original container element was removed from the DOM.
+ *
+ * @param {Object | string} element
+ * Either HTML element or string identifier. Defaults to the element used to initialize the viewer.
+
+ */
+ setContainer(e) {
+ let n = (0, A.getElement)(e) || this.container;
+ return this.initContainer(n), this;
+ }
+ /**
+ * Set the background color (default white)
+ *
+ * @param {number}
+ * hex Hexcode specified background color, or standard color spec
+ * @param {number}
+ * a Alpha level (default 1.0)
+ *
+ * @example
+ *
+ * viewer.setBackgroundColor(0x000000);
+
+
+ *
+ */
+ setBackgroundColor(e, n) {
+ (typeof n > "u" || n < 0 || n > 1) && (n = 1);
+ var a = E.CC.color(e);
+ return this.scene.fog.color = a, this.bgColor = a.getHex(), this.renderer.setClearColorHex(a.getHex(), n), this.show(), this;
+ }
+ /**
+ * Set view projection scheme. Either orthographic or perspective.
+ * Default is perspective. Orthographic can also be enabled on viewer creation
+ * by setting orthographic to true in the config object.
+ *
+ *
+ * @example
+ viewer.setViewStyle({style:"outline"});
+ $3Dmol.get('data/1fas.pqr', function(data){
+ viewer.addModel(data, "pqr");
+ $3Dmol.get("data/1fas.cube",function(volumedata){
+ viewer.addSurface($3Dmol.SurfaceType.VDW, {opacity:0.85,voldata: new $3Dmol.VolumeData(volumedata, "cube"), volscheme: new $3Dmol.Gradient.RWB(-10,10)},{});
+ });
+ viewer.zoomTo();
+
+ viewer.setProjection("orthographic");
+ viewer.render(callback);
+ });
+ *
+ */
+ setProjection(e) {
+ this.camera.ortho = e === "orthographic", this.setSlabAndFog();
+ }
+ /**
+ * Set global view styles.
+ *
+ * @example
+ * viewer.setViewStyle({style:"outline"});
+ $3Dmol.get('data/1fas.pqr', function(data){
+ viewer.addModel(data, "pqr");
+ $3Dmol.get("data/1fas.cube",function(volumedata){
+ viewer.addSurface($3Dmol.SurfaceType.VDW, {opacity:0.85,voldata: new $3Dmol.VolumeData(volumedata, "cube"), volscheme: new $3Dmol.Gradient.RWB(-10,10)},{});
+ });
+ viewer.zoomTo();
+ viewer.render(callback);
+ });
+ *
+ */
+ setViewStyle(e) {
+ if (e.style === "outline") {
+ var n = {};
+ e.color && (n.color = E.CC.color(e.color)), e.width && (n.width = e.width), this.renderer.enableOutline(n);
+ } else
+ this.renderer.disableOutline();
+ return this;
+ }
+ updateSize() {
+ this.renderer.setSize(this.WIDTH, this.HEIGHT), this.ASPECT = this.renderer.getAspect(this.WIDTH, this.HEIGHT), this.renderer.setSize(this.WIDTH, this.HEIGHT), this.camera.aspect = this.ASPECT, this.camera.updateProjectionMatrix();
+ }
+ /**
+ * Set viewer width independently of the HTML container. This is probably not what you want.
+ *
+ * @param {number} w Width in pixels
+ */
+ setWidth(e) {
+ return this.WIDTH = e || this.WIDTH, this.updateSize(), this;
+ }
+ /**
+ * Set viewer height independently of the HTML container. This is probably not what you want.
+ *
+ * @param {number} h Height in pixels
+ */
+ setHeight(e) {
+ return this.HEIGHT = e || this.HEIGHT, this.updateSize(), this;
+ }
+ /**
+ * Resize viewer according to containing HTML element's dimensions
+ *
+ */
+ resize() {
+ this.WIDTH = this.getWidth(), this.HEIGHT = this.getHeight();
+ let e = !1;
+ if (this.renderer.isLost() && this.WIDTH > 0 && this.HEIGHT > 0 && (this.container.querySelector("canvas").remove(), this.setupRenderer(), this.initContainer(this.container), e = !0), this.WIDTH == 0 || this.HEIGHT == 0 ? this.animated && this._viewer.pauseAnimate() : this.animated && this._viewer.resumeAnimate(), this.updateSize(), e) {
+ let n = this.renderer.supportedExtensions();
+ n.regen = !0, this._viewer.render(null, n);
+ } else
+ this.show();
+ return this;
+ }
+ /**
+ * Return specified model
+ *
+ * @param {number}
+ * [id=last model id] - Retrieve model with specified id
+ * @default Returns last model added to viewer or null if there are no models
+ * @return {GLModel}
+ *
+ * @example // Retrieve reference to first GLModel added var m =
+ * $3Dmol.download("pdb:1UBQ",viewer,{},function(m1){
+ $3Dmol.download("pdb:1UBI", viewer,{}, function(m2) {
+ viewer.zoomTo();
+ m1.setStyle({cartoon: {color:'green'}});
+ //could use m2 here as well
+ viewer.getModel().setStyle({cartoon: {color:'blue'}});
+ viewer.render();
+ })
+ });
+ */
+ getModel(e) {
+ return e === void 0 ? this.models.length == 0 ? null : this.models[this.models.length - 1] : e instanceof g.GLModel ? e : e in this.models ? this.models[e] : this.models.length == 0 ? null : this.models[this.models.length - 1];
+ }
+ /**
+ * Continuously rotate a scene around the specified axis.
+ *
+ * Call `spin(false)` to stop spinning.
+ *
+ * @param {string|boolean|Array} axis
+ * [axis] - Axis ("x", "y", "z", "vx", "vy", or "vz") to rotate around.
+ * Default "y". View relative (rather than model relative) axes are prefixed with v.
+ * @param {number} speed
+ * [speed] - Speed multiplier for spinning the viewer. 1 is default and a negative
+ * value reverses the direction of the spin.
+ *
+ */
+ spin(e, n = 1) {
+ if (clearInterval(this.spinInterval), typeof e > "u" && (e = "y"), typeof e == "boolean")
+ if (e)
+ e = "y";
+ else
+ return;
+ Array.isArray(e) && (e = { x: e[0], y: e[1], z: e[2] });
+ var a = this;
+ this.spinInterval = setInterval(function() {
+ !a.getCanvas().isConnected && a.renderer.isLost() && clearInterval(a.spinInterval), a.rotate(1 * n, e);
+ }, 25);
+ }
+ //animate motion between current position and passed position
+ // can set some parameters to null
+ //if fixed is true will enforce the request animation, otherwise
+ //does relative updates
+ //positions objects have modelggroup position, rotation group position.z,
+ //and rotationgroup quaternion
+ //return array includes final position, but not current
+ //the returned array includes an animate method
+ animateMotion(e, n, a, p, x, D) {
+ var O = 20, R = Math.ceil(e / O);
+ R < 1 && (R = 1), this.incAnim();
+ var z = {
+ mpos: this.modelGroup.position.clone(),
+ rz: this.rotationGroup.position.z,
+ rot: this.rotationGroup.quaternion.clone(),
+ cam: this.lookingAt.clone()
+ };
+ if (n) {
+ let W = new Array(R);
+ for (let V = 0; V < R; V++) {
+ let H = (V + 1) / R, G = { mpos: z.mpos, rz: z.rz, rot: z.rot };
+ G.mpos = a.clone().sub(z.mpos).multiplyScalar(H).add(z.mpos), G.rz = z.rz + H * (p - z.rz), G.rot = t.slerp(z.rot, x, H), G.cam = D.clone().sub(z.cam).multiplyScalar(H).add(z.cam), W[V] = G;
+ }
+ let k = 0, F = this, U = function() {
+ var V = W[k];
+ k += 1, F.modelGroup.position = V.mpos, F.rotationGroup.position.z = V.rz, F.rotationGroup.quaternion = V.rot, F.camera.lookAt(V.cam), k < W.length ? setTimeout(U, O) : F.decAnim(), F.show();
+ };
+ setTimeout(U, O);
+ } else {
+ var T = {};
+ let W = 1 / R;
+ if (a && (T.mpos = a.clone().sub(z.mpos).multiplyScalar(W)), typeof p < "u" && p != null && (T.rz = W * (p - z.rz)), x) {
+ var B = t.slerp(z.rot, x, W);
+ T.rot = z.rot.clone().inverse().multiply(B);
+ }
+ D && (T.cam = D.clone().sub(z.cam).multiplyScalar(W));
+ let k = 0, F = this, U = function() {
+ k += 1, T.mpos && F.modelGroup.position.add(T.mpos), T.rz && (F.rotationGroup.position.z += T.rz), T.rot && F.rotationGroup.quaternion.multiply(T.rot), T.cam && (F.lookingAt.add(T.cam), F.camera.lookAt(F.lookingAt)), k < R ? setTimeout(U, O) : F.decAnim(), F.show();
+ };
+ setTimeout(U, O);
+ }
+ }
+ /**
+ * Rotate scene by angle degrees around axis
+ *
+ * @param {number}
+ * [angle] - Angle, in degrees, to rotate by.
+ * @param {string}
+ * [axis] - Axis ("x", "y", "z", "vx", "vy", or "vz") to rotate around.
+ * Default "y". View relative (rather than model relative) axes are prefixed with v.
+ * Axis can also be specified as a vector.
+ * @param {number}
+ * [animationDuration] - an optional parameter that denotes
+ * the duration of the rotation animation. Default 0 (no animation)
+ * @param {boolean} [fixedPath] - if true animation is constrained to
+ * requested motion, overriding updates that happen during the animation *
+ * @example $3Dmol.download('cid:4000', viewer, {}, function() {
+ viewer.setStyle({stick:{}});
+ viewer.zoomTo();
+ viewer.rotate(90,'y',1);
+ viewer.render(callback);
+ });
+
+ *
+ */
+ rotate(e, n = "y", a = 0, p = !1) {
+ if (n == "x" ? n = { x: 1, y: 0, z: 0 } : n == "y" ? n = { x: 0, y: 1, z: 0 } : n == "z" && (n = { x: 0, y: 0, z: 1 }), n == "vx" ? n = { vx: 1, vy: 0, vz: 0 } : n == "vy" ? n = { vx: 0, vy: 1, vz: 0 } : n == "vz" && (n = { vx: 0, vy: 0, vz: 1 }), typeof n.vx < "u") {
+ var x = new M.Vector3(n.vx, n.vy, n.vz);
+ x.applyQuaternion(this.rotationGroup.quaternion), n = { x: x.x, y: x.y, z: x.z };
+ }
+ var D = function(T) {
+ var B = Math.sin(T / 2), W = Math.cos(T / 2), k = 0, F = 0, U = 0;
+ return k = n.x * B, F = n.y * B, U = n.z * B, new M.Quaternion(k, F, U, W).normalize();
+ }, O = Math.PI * e / 180, R = D(O);
+ if (a) {
+ var z = new M.Quaternion().copy(this.rotationGroup.quaternion).multiply(R);
+ this.animateMotion(a, p, this.modelGroup.position, this.rotationGroup.position.z, z, this.lookingAt);
+ } else
+ this.rotationGroup.quaternion.multiply(R), this.show();
+ return this;
+ }
+ surfacesFinished() {
+ for (var e in this.surfaces)
+ if (!this.surfaces[e][0].done)
+ return !1;
+ return !0;
+ }
+ /** Returns an array representing the current viewpoint.
+ * Translation, zoom, and rotation quaternion.
+ * @returns {Array.} [ pos.x, pos.y, pos.z, rotationGroup.position.z, q.x, q.y, q.z, q.w ]
+ * */
+ getView() {
+ if (!this.modelGroup)
+ return [0, 0, 0, 0, 0, 0, 0, 1];
+ var e = this.modelGroup.position, n = this.rotationGroup.quaternion;
+ return [
+ e.x,
+ e.y,
+ e.z,
+ this.rotationGroup.position.z,
+ n.x,
+ n.y,
+ n.z,
+ n.w
+ ];
+ }
+ /** Sets the view to the specified translation, zoom, and rotation.
+ *
+ * @param {Array.} arg Array formatted identically to the return value of getView */
+ setView(e, n) {
+ return e === void 0 || !(e instanceof Array || e.length !== 8) ? this : !this.modelGroup || !this.rotationGroup ? this : (this.modelGroup.position.x = e[0], this.modelGroup.position.y = e[1], this.modelGroup.position.z = e[2], this.rotationGroup.position.z = e[3], this.rotationGroup.quaternion.x = e[4], this.rotationGroup.quaternion.y = e[5], this.rotationGroup.quaternion.z = e[6], this.rotationGroup.quaternion.w = e[7], typeof e[8] < "u" && (this.rotationGroup.position.x = e[8], this.rotationGroup.position.y = e[9]), this.show(n), this);
+ }
+ // apply styles, models, etc in viewer
+ /**
+ * Render current state of viewer, after
+ * adding/removing models, applying styles, etc.
+ *
+ */
+ render(e, n) {
+ this.renderer.setViewport(), this.updateClickables();
+ var a = this.getView();
+ this.stateChangeCallback && this.stateChangeCallback(this.getInternalState());
+ var p, x;
+ for (n || (n = this.renderer.supportedExtensions()), p = 0; p < this.models.length; p++)
+ this.models[p] && this.models[p].globj(this.modelGroup, n);
+ for (p = 0; p < this.shapes.length; p++)
+ this.shapes[p] && (typeof this.shapes[p].frame > "u" || this.viewer_frame < 0 || this.shapes[p].frame < 0 || this.shapes[p].frame == this.viewer_frame ? this.shapes[p].globj(this.modelGroup, n) : this.shapes[p].removegl(this.modelGroup));
+ for (p = 0; p < this.labels.length; p++)
+ this.labels[p] && typeof this.labels[p].frame < "u" && this.labels[p].frame >= 0 && (this.modelGroup.remove(this.labels[p].sprite), (this.viewer_frame < 0 || this.labels[p].frame == this.viewer_frame) && this.modelGroup.add(this.labels[p].sprite));
+ for (p in this.surfaces)
+ if (this.surfaces.hasOwnProperty(p)) {
+ var D = this.surfaces[p];
+ for (x = 0; x < D.length; x++)
+ if (D.hasOwnProperty(x)) {
+ var O = D[x].geo;
+ if (!D[x].finished || n.regen) {
+ O.verticesNeedUpdate = !0, O.elementsNeedUpdate = !0, O.normalsNeedUpdate = !0, O.colorsNeedUpdate = !0, O.buffersNeedUpdate = !0, O.boundingSphere = null, D[x].done && (D[x].finished = !0), D[x].lastGL && this.modelGroup.remove(D[x].lastGL);
+ var R = null;
+ if (D[x].mat instanceof v.LineBasicMaterial ? R = new v.Line(O, D[x].mat) : R = new v.Mesh(O, D[x].mat), D[x].mat.transparent && D[x].mat.opacity == 0 ? R.visible = !1 : R.visible = !0, D[x].symmetries.length > 1 || D[x].symmetries.length == 1 && !D[x].symmetries[x].isIdentity()) {
+ var z, T = new v.Object3D();
+ for (z = 0; z < D[x].symmetries.length; z++) {
+ var B = R.clone();
+ B.matrix = D[x].symmetries[z], B.matrixAutoUpdate = !1, T.add(B);
+ }
+ D[x].lastGL = T, this.modelGroup.add(T);
+ } else
+ D[x].lastGL = R, this.modelGroup.add(R);
+ }
+ }
+ }
+ return this.setView(a), typeof e == "function" && e(this), this;
+ }
+ /* @param {AtomSelectionSpec|any} sel
+ * @return list of models specified by sel
+ */
+ getModelList(e) {
+ let n = [];
+ if (typeof e > "u" || typeof e.model > "u")
+ for (let p = 0; p < this.models.length; p++)
+ this.models[p] && n.push(this.models[p]);
+ else {
+ let p = e.model;
+ Array.isArray(p) || (p = [p]);
+ for (let x = 0; x < p.length; x++)
+ if (typeof p[x] == "number") {
+ var a = p[x];
+ a < 0 && (a += this.models.length), n.push(this.models[a]);
+ } else
+ n.push(p[x]);
+ }
+ return n;
+ }
+ /**
+ *
+ * @param {AtomSelectionSpec}
+ * sel
+ * @return {AtomSpec[]}
+ */
+ getAtomsFromSel(e) {
+ var n = [];
+ typeof e > "u" && (e = {});
+ var a = this.getModelList(e);
+ for (let p = 0; p < a.length; p++)
+ n = n.concat(a[p].selectedAtoms(e));
+ return n;
+ }
+ /**
+ *
+ * @param {AtomSpec}
+ * atom
+ * @param {AtomSelectionSpec}
+ * sel
+ * @return {boolean}
+ */
+ atomIsSelected(e, n) {
+ typeof n > "u" && (n = {});
+ for (var a = this.getModelList(n), p = 0; p < a.length; p++)
+ if (a[p].atomIsSelected(e, n))
+ return !0;
+ return !1;
+ }
+ /** return list of atoms selected by sel
+ *
+ * @param {AtomSelectionSpec} sel
+ * @return {AtomSpec[]}
+ */
+ selectedAtoms(e) {
+ return this.getAtomsFromSel(e);
+ }
+ /**
+ * Returns valid values for the specified attribute in the given selection
+ * @param {string} attribute
+ * @param {AtomSelectionSpec} sel
+ * @return {Array.