UNPKG

visual-graphql

Version:

A lightweight GraphQL schema visualization tool built with SolidJS

1,166 lines 151 kB
var _i = Object.defineProperty; var Jt = (u) => { throw TypeError(u); }; var Ri = (u, r, n) => r in u ? _i(u, r, { enumerable: !0, configurable: !0, writable: !0, value: n }) : u[r] = n; var X = (u, r, n) => Ri(u, typeof r != "symbol" ? r + "" : r, n), en = (u, r, n) => r.has(u) || Jt("Cannot " + n); var _ = (u, r, n) => (en(u, r, "read from private field"), n ? n.call(u) : r.get(u)), De = (u, r, n) => r.has(u) ? Jt("Cannot add the same private member more than once") : r instanceof WeakSet ? r.add(u) : r.set(u, n), tn = (u, r, n, s) => (en(u, r, "write to private field"), s ? s.call(u, n) : r.set(u, n), n); import { delegateEvents as Zi, template as Y, insert as R, createComponent as V, memo as $e, use as ki } from "solid-js/web"; import { createSignal as fn, Show as ne, For as we, onMount as dn, createEffect as Oi, onCleanup as qi } from "solid-js"; import { createStore as Gi } from "solid-js/store"; import { buildSchema as hn, buildClientSchema as Vi, lexicographicSortSchema as ji, isObjectType as Ne, isInterfaceType as Be, isUnionType as Le, isScalarType as Ve, getNamedType as Ui, introspectionFromSchema as Wi } from "graphql"; function Xi(u, r) { return u; } async function Yi(u, r) { try { let n, s = u; if (typeof u == "string") return n = hn(u), nn(n, r); if (u.data && u.data.__schema ? s = u.data : u.__schema && (s = u), !s.__schema) throw new Error("Invalid introspection data: missing __schema property"); if (!s.__schema.queryType) throw new Error("Invalid schema: missing queryType definition"); if (!s.__schema.types || !Array.isArray(s.__schema.types)) throw new Error("Invalid schema: missing or invalid types array"); const a = ["String", "Int", "Float", "Boolean", "ID"], f = s.__schema.types.filter((A) => A.kind === "SCALAR").map((A) => A.name), t = a.filter((A) => !f.includes(A)); t.length > 0 && console.warn(`Missing required scalar types: ${t.join(", ")}`); try { return n = Vi(s), nn(n, r); } catch (A) { throw console.error("Error building client schema:", A), A; } } catch (n) { throw console.error("Error processing schema:", n), n; } } function nn(u, r) { let n = u; const s = []; return r.skipRelay !== !1 && s.push(Hi), r.skipDeprecated !== !1 && s.push(Ki), r.sortByAlphabet === !0 && (n = ji(n)), s.length > 0 && (n = Xi(n)), n; } function Hi(u) { return u && u.name && (/.Connection$/.test(u.name) || /.Edge$/.test(u.name) || u.name === "PageInfo" || u.name === "Node") ? null : u; } function Ki(u) { if (u && u.getFields) try { const r = u.getFields(); if (Object.values(r).every( (s) => s.deprecationReason != null )) return null; } catch { } return u; } class Qi { constructor(r, n) { X(this, "schema"); X(this, "rootType"); X(this, "nodes"); // Map of type name to type object X(this, "edges"); // Map of source type name to array of edge objects X(this, "displayOptions"); if (this.schema = r, this.displayOptions = n, this.nodes = /* @__PURE__ */ new Map(), this.edges = /* @__PURE__ */ new Map(), n.rootType ? this.rootType = r.getType(n.rootType) : this.rootType = r.getQueryType(), !this.rootType) throw new Error("Root type not found in schema"); this.buildGraph(); } buildGraph() { var n; const r = this.schema.getTypeMap(); for (const s in r) { const a = r[s]; s.startsWith("__") || this.displayOptions.hideRoot && s === this.rootType.name || this.displayOptions.skipRelay && (s.endsWith("Connection") || s.endsWith("Edge") || s === "PageInfo") || this.nodes.set(s, a); } for (const [s, a] of this.nodes.entries()) if (Ne(a) || Be(a)) { this.edges.set(s, []); const f = a.getFields(); for (const t in f) { const A = f[t]; this.displayOptions.skipDeprecated && A.deprecationReason || (n = this.edges.get(s)) == null || n.push({ sourceType: a, targetType: A.type, fieldName: t }); } } } // Get connected types of a specific type getConnectedTypes(r) { const n = [], s = this.edges.get(r) || []; for (const a of s) { const f = this.getNamedType(a.targetType); n.includes(f) || n.push(f); } return n; } // Helper to get the named type from a wrapped type getNamedType(r) { return r.ofType ? this.getNamedType(r.ofType) : r; } } function Te(u) { return `TYPE-${u.replace(/[^_a-zA-Z0-9]/g, "_")}`; } var Ji = /* @__PURE__ */ Y("<div class=doc-explorer-back>← Back"), eo = /* @__PURE__ */ Y("<div class=doc-category><div class=doc-category-title>Schema Types"), to = /* @__PURE__ */ Y("<div class=doc-explorer><div class=doc-explorer-title-bar><div class=doc-explorer-title></div></div><div class=doc-explorer-contents>"), no = /* @__PURE__ */ Y("<div class=doc-type-description>"), ro = /* @__PURE__ */ Y("<div class=doc-category><div class=doc-category-title>Fields"), io = /* @__PURE__ */ Y("<div class=doc-category><div class=doc-category-title>Implements"), oo = /* @__PURE__ */ Y("<div class=doc-category><div class=doc-category-title>Possible Types"), uo = /* @__PURE__ */ Y("<div class=doc-category><div class=doc-category-title>Enum Values"), so = /* @__PURE__ */ Y("<div class=doc-category-item><span class=field-name></span>: <span class=type-name>"), ao = /* @__PURE__ */ Y("<span class=arg-name>"), lo = /* @__PURE__ */ Y("<span class=type-name>"), ut = /* @__PURE__ */ Y("<div class=doc-category-item><span class=type-name>"), co = /* @__PURE__ */ Y("<div class=enum-value-description>"), fo = /* @__PURE__ */ Y("<div class=doc-category-item><span class=field-name>"); const ho = (u) => { const [r, n] = fn([]), s = () => { if (!u.selectedTypeID || !u.typeGraph) return null; const A = u.selectedTypeID.replace(/^TYPE-/, ""); return u.typeGraph.nodes.get(A) || null; }, a = () => { const A = r(); if (A.length > 0) { const v = [...A]; v.pop(), n(v); const B = v.length > 0 ? v[v.length - 1] : null; u.onSelectNode(B); } }, f = (A) => { n([...r(), A]), u.onSelectNode(A); }, t = s(); return (() => { var A = to(), v = A.firstChild, B = v.firstChild, l = v.nextSibling; return R(v, V(ne, { get when() { return r().length > 0; }, get children() { var h = Ji(); return h.$$click = a, h; } }), B), R(B, () => t ? t.name : "Documentation Explorer"), R(l, V(ne, { when: t, children: (h) => [(() => { var C = no(); return R(C, () => h().description || `No description for ${h().name}`), C; })(), V(ne, { get when() { return $e(() => !!h().getFields)() && typeof h().getFields == "function"; }, get children() { var C = ro(); return C.firstChild, R(C, V(we, { get each() { return Object.values(h().getFields()); }, children: (y) => (() => { var m = so(), E = m.firstChild, S = E.nextSibling, M = S.nextSibling; return R(E, () => y.name), R(m, () => y.args && y.args.length > 0 ? "(" : "", S), R(m, V(we, { get each() { return y.args; }, children: (I, q) => [(() => { var O = ao(); return R(O, () => I.name), O; })(), ": ", (() => { var O = lo(); return O.$$click = () => f(I.type.name), R(O, () => I.type.toString()), O; })(), $e(() => q() < y.args.length - 1 ? ", " : "")] }), S), R(m, () => y.args && y.args.length > 0 ? ")" : "", S), M.$$click = () => { const I = y.type.toString().replace(/[[\]!]/g, ""); f(I); }, R(M, () => y.type.toString()), m; })() }), null), C; } }), V(ne, { get when() { return $e(() => !!(h().getInterfaces && typeof h().getInterfaces == "function"))() && h().getInterfaces().length > 0; }, get children() { var C = io(); return C.firstChild, R(C, V(we, { get each() { return h().getInterfaces(); }, children: (y) => (() => { var m = ut(), E = m.firstChild; return m.$$click = () => f(y.name), R(E, () => y.name), m; })() }), null), C; } }), V(ne, { get when() { return $e(() => !!(h().getTypes && typeof h().getTypes == "function"))() && h().getTypes().length > 0; }, get children() { var C = oo(); return C.firstChild, R(C, V(we, { get each() { return h().getTypes(); }, children: (y) => (() => { var m = ut(), E = m.firstChild; return m.$$click = () => f(y.name), R(E, () => y.name), m; })() }), null), C; } }), V(ne, { get when() { return $e(() => !!(h().getValues && typeof h().getValues == "function"))() && h().getValues().length > 0; }, get children() { var C = uo(); return C.firstChild, R(C, V(we, { get each() { return h().getValues(); }, children: (y) => (() => { var m = fo(), E = m.firstChild; return R(E, () => y.name), R(m, V(ne, { get when() { return y.description; }, get children() { var S = co(); return R(S, () => y.description), S; } }), null), m; })() }), null), C; } })] }), null), R(l, V(ne, { when: !t, get children() { var h = eo(); return h.firstChild, R(h, V(we, { get each() { return Array.from(u.typeGraph.nodes.values()); }, children: (C) => (() => { var y = ut(), m = y.firstChild; return y.$$click = () => f(C.name), R(m, () => C.name), y; })() }), null), h; } }), null), A; })(); }; Zi(["click"]); function po(u) { return u && u.__esModule && Object.prototype.hasOwnProperty.call(u, "default") ? u.default : u; } var st, rn; function go() { return rn || (rn = 1, st = function() { var u = "", r, n, s, a = [], f = { passive: !0 }, t = { passive: !1 }; window.addEventListener ? (r = "addEventListener", n = "removeEventListener") : (r = "attachEvent", n = "detachEvent", u = "on"), s = "onwheel" in document.createElement("div") ? "wheel" : ( // Modern browsers support "wheel" document.onmousewheel !== void 0 ? "mousewheel" : ( // Webkit and IE support at least "mousewheel" "DOMMouseScroll" ) ); function A(m, E) { var S = function(M) { !M && (M = window.event); var I = { // keep a ref to the original event object originalEvent: M, target: M.target || M.srcElement, type: "wheel", deltaMode: M.type == "MozMousePixelScroll" ? 0 : 1, deltaX: 0, delatZ: 0, preventDefault: function() { M.preventDefault ? M.preventDefault() : M.returnValue = !1; } }; return s == "mousewheel" ? (I.deltaY = -0.025 * M.wheelDelta, M.wheelDeltaX && (I.deltaX = -0.025 * M.wheelDeltaX)) : I.deltaY = M.detail, E(I); }; return a.push({ element: m, fn: S }), S; } function v(m) { for (var E = 0; E < a.length; E++) if (a[E].element === m) return a[E].fn; return function() { }; } function B(m) { for (var E = 0; E < a.length; E++) if (a[E].element === m) return a.splice(E, 1); } function l(m, E, S, M) { var I; s === "wheel" ? I = S : I = A(m, S), m[r]( u + E, I, M ? f : t ); } function h(m, E, S, M) { var I; s === "wheel" ? I = S : I = v(m), m[n]( u + E, I, M ? f : t ), B(m); } function C(m, E, S) { l(m, s, E, S), s == "DOMMouseScroll" && l(m, "MozMousePixelScroll", E, S); } function y(m, E, S) { h(m, s, E, S), s == "DOMMouseScroll" && h(m, "MozMousePixelScroll", E, S); } return { on: C, off: y }; }()), st; } var at, on; function gt() { if (on) return at; on = 1, at = { /** * Extends an object * * @param {Object} target object to extend * @param {Object} source object to take properties from * @return {Object} extended object */ extend: function(r, n) { r = r || {}; for (var s in n) this.isObject(n[s]) ? r[s] = this.extend(r[s], n[s]) : r[s] = n[s]; return r; }, /** * Checks if an object is a DOM element * * @param {Object} o HTML element or String * @return {Boolean} returns true if object is a DOM element */ isElement: function(r) { return r instanceof HTMLElement || r instanceof SVGElement || r instanceof SVGSVGElement || //DOM2 r && typeof r == "object" && r !== null && r.nodeType === 1 && typeof r.nodeName == "string"; }, /** * Checks if an object is an Object * * @param {Object} o Object * @return {Boolean} returns true if object is an Object */ isObject: function(r) { return Object.prototype.toString.call(r) === "[object Object]"; }, /** * Checks if variable is Number * * @param {Integer|Float} n * @return {Boolean} returns true if variable is Number */ isNumber: function(r) { return !isNaN(parseFloat(r)) && isFinite(r); }, /** * Search for an SVG element * * @param {Object|String} elementOrSelector DOM Element or selector String * @return {Object|Null} SVG or null */ getSvg: function(r) { var n, s; if (this.isElement(r)) n = r; else if (typeof r == "string" || r instanceof String) { if (n = document.querySelector(r), !n) throw new Error( "Provided selector did not find any elements. Selector: " + r ); } else throw new Error("Provided selector is not an HTML object nor String"); if (n.tagName.toLowerCase() === "svg") s = n; else if (n.tagName.toLowerCase() === "object") s = n.contentDocument.documentElement; else if (n.tagName.toLowerCase() === "embed") s = n.getSVGDocument().documentElement; else throw n.tagName.toLowerCase() === "img" ? new Error( 'Cannot script an SVG in an "img" element. Please use an "object" element or an in-line SVG.' ) : new Error("Cannot get SVG."); return s; }, /** * Attach a given context to a function * @param {Function} fn Function * @param {Object} context Context * @return {Function} Function with certain context */ proxy: function(r, n) { return function() { return r.apply(n, arguments); }; }, /** * Returns object type * Uses toString that returns [object SVGPoint] * And than parses object type from string * * @param {Object} o Any object * @return {String} Object type */ getType: function(r) { return Object.prototype.toString.apply(r).replace(/^\[object\s/, "").replace(/\]$/, ""); }, /** * If it is a touch event than add clientX and clientY to event object * * @param {Event} evt * @param {SVGSVGElement} svg */ mouseAndTouchNormalize: function(r, n) { if (r.clientX === void 0 || r.clientX === null) if (r.clientX = 0, r.clientY = 0, r.touches !== void 0 && r.touches.length) { if (r.touches[0].clientX !== void 0) r.clientX = r.touches[0].clientX, r.clientY = r.touches[0].clientY; else if (r.touches[0].pageX !== void 0) { var s = n.getBoundingClientRect(); r.clientX = r.touches[0].pageX - s.left, r.clientY = r.touches[0].pageY - s.top; } } else r.originalEvent !== void 0 && r.originalEvent.clientX !== void 0 && (r.clientX = r.originalEvent.clientX, r.clientY = r.originalEvent.clientY); }, /** * Check if an event is a double click/tap * TODO: For touch gestures use a library (hammer.js) that takes in account other events * (touchmove and touchend). It should take in account tap duration and traveled distance * * @param {Event} evt * @param {Event} prevEvt Previous Event * @return {Boolean} */ isDblClick: function(r, n) { if (r.detail === 2) return !0; if (n != null) { var s = r.timeStamp - n.timeStamp, a = Math.sqrt( Math.pow(r.clientX - n.clientX, 2) + Math.pow(r.clientY - n.clientY, 2) ); return s < 250 && a < 10; } return !1; }, /** * Returns current timestamp as an integer * * @return {Number} */ now: Date.now || function() { return (/* @__PURE__ */ new Date()).getTime(); }, // From underscore. // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. Normally, the throttled function will run // as much as it can, without ever going more than once per `wait` duration; // but if you'd like to disable the execution on the leading edge, pass // `{leading: false}`. To disable execution on the trailing edge, ditto. throttle: function(r, n, s) { var a = this, f, t, A, v = null, B = 0; s || (s = {}); var l = function() { B = s.leading === !1 ? 0 : a.now(), v = null, A = r.apply(f, t), v || (f = t = null); }; return function() { var h = a.now(); !B && s.leading === !1 && (B = h); var C = n - (h - B); return f = this, t = arguments, C <= 0 || C > n ? (clearTimeout(v), v = null, B = h, A = r.apply(f, t), v || (f = t = null)) : !v && s.trailing !== !1 && (v = setTimeout(l, C)), A; }; }, /** * Create a requestAnimationFrame simulation * * @param {Number|String} refreshRate * @return {Function} */ createRequestAnimationFrame: function(r) { var n = null; return r !== "auto" && r < 60 && r > 1 && (n = Math.floor(1e3 / r)), n === null ? window.requestAnimationFrame || u(33) : u(n); } }; function u(r) { return function(n) { window.setTimeout(n, r); }; } return at; } var Se, un; function mt() { if (un) return Se; un = 1; var u = gt(), r = "unknown"; return document.documentMode && (r = "ie"), Se = { svgNS: "http://www.w3.org/2000/svg", xmlNS: "http://www.w3.org/XML/1998/namespace", xmlnsNS: "http://www.w3.org/2000/xmlns/", xlinkNS: "http://www.w3.org/1999/xlink", evNS: "http://www.w3.org/2001/xml-events", /** * Get svg dimensions: width and height * * @param {SVGSVGElement} svg * @return {Object} {width: 0, height: 0} */ getBoundingClientRectNormalized: function(n) { if (n.clientWidth && n.clientHeight) return { width: n.clientWidth, height: n.clientHeight }; if (n.getBoundingClientRect()) return n.getBoundingClientRect(); throw new Error("Cannot get BoundingClientRect for SVG."); }, /** * Gets g element with class of "viewport" or creates it if it doesn't exist * * @param {SVGSVGElement} svg * @return {SVGElement} g (group) element */ getOrCreateViewport: function(n, s) { var a = null; if (u.isElement(s) ? a = s : a = n.querySelector(s), !a) { var f = Array.prototype.slice.call(n.childNodes || n.children).filter(function(l) { return l.nodeName !== "defs" && l.nodeName !== "#text"; }); f.length === 1 && f[0].nodeName === "g" && f[0].getAttribute("transform") === null && (a = f[0]); } if (!a) { var t = "viewport-" + (/* @__PURE__ */ new Date()).toISOString().replace(/\D/g, ""); a = document.createElementNS(this.svgNS, "g"), a.setAttribute("id", t); var A = n.childNodes || n.children; if (A && A.length > 0) for (var v = A.length; v > 0; v--) A[A.length - v].nodeName !== "defs" && a.appendChild(A[A.length - v]); n.appendChild(a); } var B = []; return a.getAttribute("class") && (B = a.getAttribute("class").split(" ")), ~B.indexOf("svg-pan-zoom_viewport") || (B.push("svg-pan-zoom_viewport"), a.setAttribute("class", B.join(" "))), a; }, /** * Set SVG attributes * * @param {SVGSVGElement} svg */ setupSvgAttributes: function(n) { if (n.setAttribute("xmlns", this.svgNS), n.setAttributeNS(this.xmlnsNS, "xmlns:xlink", this.xlinkNS), n.setAttributeNS(this.xmlnsNS, "xmlns:ev", this.evNS), n.parentNode !== null) { var s = n.getAttribute("style") || ""; s.toLowerCase().indexOf("overflow") === -1 && n.setAttribute("style", "overflow: hidden; " + s); } }, /** * How long Internet Explorer takes to finish updating its display (ms). */ internetExplorerRedisplayInterval: 300, /** * Forces the browser to redisplay all SVG elements that rely on an * element defined in a 'defs' section. It works globally, for every * available defs element on the page. * The throttling is intentionally global. * * This is only needed for IE. It is as a hack to make markers (and 'use' elements?) * visible after pan/zoom when there are multiple SVGs on the page. * See bug report: https://connect.microsoft.com/IE/feedback/details/781964/ * also see svg-pan-zoom issue: https://github.com/bumbu/svg-pan-zoom/issues/62 */ refreshDefsGlobal: u.throttle( function() { for (var n = document.querySelectorAll("defs"), s = n.length, a = 0; a < s; a++) { var f = n[a]; f.parentNode.insertBefore(f, f); } }, Se ? Se.internetExplorerRedisplayInterval : null ), /** * Sets the current transform matrix of an element * * @param {SVGElement} element * @param {SVGMatrix} matrix CTM * @param {SVGElement} defs */ setCTM: function(n, s, a) { var f = this, t = "matrix(" + s.a + "," + s.b + "," + s.c + "," + s.d + "," + s.e + "," + s.f + ")"; n.setAttributeNS(null, "transform", t), "transform" in n.style ? n.style.transform = t : "-ms-transform" in n.style ? n.style["-ms-transform"] = t : "-webkit-transform" in n.style && (n.style["-webkit-transform"] = t), r === "ie" && a && (a.parentNode.insertBefore(a, a), window.setTimeout(function() { f.refreshDefsGlobal(); }, f.internetExplorerRedisplayInterval)); }, /** * Instantiate an SVGPoint object with given event coordinates * * @param {Event} evt * @param {SVGSVGElement} svg * @return {SVGPoint} point */ getEventPoint: function(n, s) { var a = s.createSVGPoint(); return u.mouseAndTouchNormalize(n, s), a.x = n.clientX, a.y = n.clientY, a; }, /** * Get SVG center point * * @param {SVGSVGElement} svg * @return {SVGPoint} */ getSvgCenterPoint: function(n, s, a) { return this.createSVGPoint(n, s / 2, a / 2); }, /** * Create a SVGPoint with given x and y * * @param {SVGSVGElement} svg * @param {Number} x * @param {Number} y * @return {SVGPoint} */ createSVGPoint: function(n, s, a) { var f = n.createSVGPoint(); return f.x = s, f.y = a, f; } }, Se; } var lt, sn; function mo() { if (sn) return lt; sn = 1; var u = mt(); return lt = { enable: function(r) { var n = r.svg.querySelector("defs"); n || (n = document.createElementNS(u.svgNS, "defs"), r.svg.appendChild(n)); var s = n.querySelector("style#svg-pan-zoom-controls-styles"); if (!s) { var a = document.createElementNS(u.svgNS, "style"); a.setAttribute("id", "svg-pan-zoom-controls-styles"), a.setAttribute("type", "text/css"), a.textContent = ".svg-pan-zoom-control { cursor: pointer; fill: black; fill-opacity: 0.333; } .svg-pan-zoom-control:hover { fill-opacity: 0.8; } .svg-pan-zoom-control-background { fill: white; fill-opacity: 0.5; } .svg-pan-zoom-control-background { fill-opacity: 0.8; }", n.appendChild(a); } var f = document.createElementNS(u.svgNS, "g"); f.setAttribute("id", "svg-pan-zoom-controls"), f.setAttribute( "transform", "translate(" + (r.width - 70) + " " + (r.height - 76) + ") scale(0.75)" ), f.setAttribute("class", "svg-pan-zoom-control"), f.appendChild(this._createZoomIn(r)), f.appendChild(this._createZoomReset(r)), f.appendChild(this._createZoomOut(r)), r.svg.appendChild(f), r.controlIcons = f; }, _createZoomIn: function(r) { var n = document.createElementNS(u.svgNS, "g"); n.setAttribute("id", "svg-pan-zoom-zoom-in"), n.setAttribute("transform", "translate(30.5 5) scale(0.015)"), n.setAttribute("class", "svg-pan-zoom-control"), n.addEventListener( "click", function() { r.getPublicInstance().zoomIn(); }, !1 ), n.addEventListener( "touchstart", function() { r.getPublicInstance().zoomIn(); }, !1 ); var s = document.createElementNS(u.svgNS, "rect"); s.setAttribute("x", "0"), s.setAttribute("y", "0"), s.setAttribute("width", "1500"), s.setAttribute("height", "1400"), s.setAttribute("class", "svg-pan-zoom-control-background"), n.appendChild(s); var a = document.createElementNS(u.svgNS, "path"); return a.setAttribute( "d", "M1280 576v128q0 26 -19 45t-45 19h-320v320q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-320h-320q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h320v-320q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v320h320q26 0 45 19t19 45zM1536 1120v-960 q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" ), a.setAttribute("class", "svg-pan-zoom-control-element"), n.appendChild(a), n; }, _createZoomReset: function(r) { var n = document.createElementNS(u.svgNS, "g"); n.setAttribute("id", "svg-pan-zoom-reset-pan-zoom"), n.setAttribute("transform", "translate(5 35) scale(0.4)"), n.setAttribute("class", "svg-pan-zoom-control"), n.addEventListener( "click", function() { r.getPublicInstance().reset(); }, !1 ), n.addEventListener( "touchstart", function() { r.getPublicInstance().reset(); }, !1 ); var s = document.createElementNS( u.svgNS, "rect" ); s.setAttribute("x", "2"), s.setAttribute("y", "2"), s.setAttribute("width", "182"), s.setAttribute("height", "58"), s.setAttribute( "class", "svg-pan-zoom-control-background" ), n.appendChild(s); var a = document.createElementNS( u.svgNS, "path" ); a.setAttribute( "d", "M33.051,20.632c-0.742-0.406-1.854-0.609-3.338-0.609h-7.969v9.281h7.769c1.543,0,2.701-0.188,3.473-0.562c1.365-0.656,2.048-1.953,2.048-3.891C35.032,22.757,34.372,21.351,33.051,20.632z" ), a.setAttribute( "class", "svg-pan-zoom-control-element" ), n.appendChild(a); var f = document.createElementNS( u.svgNS, "path" ); return f.setAttribute( "d", "M170.231,0.5H15.847C7.102,0.5,0.5,5.708,0.5,11.84v38.861C0.5,56.833,7.102,61.5,15.847,61.5h154.384c8.745,0,15.269-4.667,15.269-10.798V11.84C185.5,5.708,178.976,0.5,170.231,0.5z M42.837,48.569h-7.969c-0.219-0.766-0.375-1.383-0.469-1.852c-0.188-0.969-0.289-1.961-0.305-2.977l-0.047-3.211c-0.03-2.203-0.41-3.672-1.142-4.406c-0.732-0.734-2.103-1.102-4.113-1.102h-7.05v13.547h-7.055V14.022h16.524c2.361,0.047,4.178,0.344,5.45,0.891c1.272,0.547,2.351,1.352,3.234,2.414c0.731,0.875,1.31,1.844,1.737,2.906s0.64,2.273,0.64,3.633c0,1.641-0.414,3.254-1.242,4.84s-2.195,2.707-4.102,3.363c1.594,0.641,2.723,1.551,3.387,2.73s0.996,2.98,0.996,5.402v2.32c0,1.578,0.063,2.648,0.19,3.211c0.19,0.891,0.635,1.547,1.333,1.969V48.569z M75.579,48.569h-26.18V14.022h25.336v6.117H56.454v7.336h16.781v6H56.454v8.883h19.125V48.569z M104.497,46.331c-2.44,2.086-5.887,3.129-10.34,3.129c-4.548,0-8.125-1.027-10.731-3.082s-3.909-4.879-3.909-8.473h6.891c0.224,1.578,0.662,2.758,1.316,3.539c1.196,1.422,3.246,2.133,6.15,2.133c1.739,0,3.151-0.188,4.236-0.562c2.058-0.719,3.087-2.055,3.087-4.008c0-1.141-0.504-2.023-1.512-2.648c-1.008-0.609-2.607-1.148-4.796-1.617l-3.74-0.82c-3.676-0.812-6.201-1.695-7.576-2.648c-2.328-1.594-3.492-4.086-3.492-7.477c0-3.094,1.139-5.664,3.417-7.711s5.623-3.07,10.036-3.07c3.685,0,6.829,0.965,9.431,2.895c2.602,1.93,3.966,4.73,4.093,8.402h-6.938c-0.128-2.078-1.057-3.555-2.787-4.43c-1.154-0.578-2.587-0.867-4.301-0.867c-1.907,0-3.428,0.375-4.565,1.125c-1.138,0.75-1.706,1.797-1.706,3.141c0,1.234,0.561,2.156,1.682,2.766c0.721,0.406,2.25,0.883,4.589,1.43l6.063,1.43c2.657,0.625,4.648,1.461,5.975,2.508c2.059,1.625,3.089,3.977,3.089,7.055C108.157,41.624,106.937,44.245,104.497,46.331z M139.61,48.569h-26.18V14.022h25.336v6.117h-18.281v7.336h16.781v6h-16.781v8.883h19.125V48.569z M170.337,20.14h-10.336v28.43h-7.266V20.14h-10.383v-6.117h27.984V20.14z" ), f.setAttribute( "class", "svg-pan-zoom-control-element" ), n.appendChild(f), n; }, _createZoomOut: function(r) { var n = document.createElementNS(u.svgNS, "g"); n.setAttribute("id", "svg-pan-zoom-zoom-out"), n.setAttribute("transform", "translate(30.5 70) scale(0.015)"), n.setAttribute("class", "svg-pan-zoom-control"), n.addEventListener( "click", function() { r.getPublicInstance().zoomOut(); }, !1 ), n.addEventListener( "touchstart", function() { r.getPublicInstance().zoomOut(); }, !1 ); var s = document.createElementNS(u.svgNS, "rect"); s.setAttribute("x", "0"), s.setAttribute("y", "0"), s.setAttribute("width", "1500"), s.setAttribute("height", "1400"), s.setAttribute("class", "svg-pan-zoom-control-background"), n.appendChild(s); var a = document.createElementNS(u.svgNS, "path"); return a.setAttribute( "d", "M1280 576v128q0 26 -19 45t-45 19h-896q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h896q26 0 45 19t19 45zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5 t84.5 -203.5z" ), a.setAttribute("class", "svg-pan-zoom-control-element"), n.appendChild(a), n; }, disable: function(r) { r.controlIcons && (r.controlIcons.parentNode.removeChild(r.controlIcons), r.controlIcons = null); } }, lt; } var ct, an; function vo() { if (an) return ct; an = 1; var u = mt(), r = gt(), n = function(s, a) { this.init(s, a); }; return n.prototype.init = function(s, a) { this.viewport = s, this.options = a, this.originalState = { zoom: 1, x: 0, y: 0 }, this.activeState = { zoom: 1, x: 0, y: 0 }, this.updateCTMCached = r.proxy(this.updateCTM, this), this.requestAnimationFrame = r.createRequestAnimationFrame( this.options.refreshRate ), this.viewBox = { x: 0, y: 0, width: 0, height: 0 }, this.cacheViewBox(); var f = this.processCTM(); this.setCTM(f), this.updateCTM(); }, n.prototype.cacheViewBox = function() { var s = this.options.svg.getAttribute("viewBox"); if (s) { var a = s.split(/[\s\,]/).filter(function(t) { return t; }).map(parseFloat); this.viewBox.x = a[0], this.viewBox.y = a[1], this.viewBox.width = a[2], this.viewBox.height = a[3]; var f = Math.min( this.options.width / this.viewBox.width, this.options.height / this.viewBox.height ); this.activeState.zoom = f, this.activeState.x = (this.options.width - this.viewBox.width * f) / 2, this.activeState.y = (this.options.height - this.viewBox.height * f) / 2, this.updateCTMOnNextFrame(), this.options.svg.removeAttribute("viewBox"); } else this.simpleViewBoxCache(); }, n.prototype.simpleViewBoxCache = function() { var s = this.viewport.getBBox(); this.viewBox.x = s.x, this.viewBox.y = s.y, this.viewBox.width = s.width, this.viewBox.height = s.height; }, n.prototype.getViewBox = function() { return r.extend({}, this.viewBox); }, n.prototype.processCTM = function() { var s = this.getCTM(); if (this.options.fit || this.options.contain) { var a; this.options.fit ? a = Math.min( this.options.width / this.viewBox.width, this.options.height / this.viewBox.height ) : a = Math.max( this.options.width / this.viewBox.width, this.options.height / this.viewBox.height ), s.a = a, s.d = a, s.e = -this.viewBox.x * a, s.f = -this.viewBox.y * a; } if (this.options.center) { var f = (this.options.width - (this.viewBox.width + this.viewBox.x * 2) * s.a) * 0.5, t = (this.options.height - (this.viewBox.height + this.viewBox.y * 2) * s.a) * 0.5; s.e = f, s.f = t; } return this.originalState.zoom = s.a, this.originalState.x = s.e, this.originalState.y = s.f, s; }, n.prototype.getOriginalState = function() { return r.extend({}, this.originalState); }, n.prototype.getState = function() { return r.extend({}, this.activeState); }, n.prototype.getZoom = function() { return this.activeState.zoom; }, n.prototype.getRelativeZoom = function() { return this.activeState.zoom / this.originalState.zoom; }, n.prototype.computeRelativeZoom = function(s) { return s / this.originalState.zoom; }, n.prototype.getPan = function() { return { x: this.activeState.x, y: this.activeState.y }; }, n.prototype.getCTM = function() { var s = this.options.svg.createSVGMatrix(); return s.a = this.activeState.zoom, s.b = 0, s.c = 0, s.d = this.activeState.zoom, s.e = this.activeState.x, s.f = this.activeState.y, s; }, n.prototype.setCTM = function(s) { var a = this.isZoomDifferent(s), f = this.isPanDifferent(s); if (a || f) { if (a && (this.options.beforeZoom( this.getRelativeZoom(), this.computeRelativeZoom(s.a) ) === !1 ? (s.a = s.d = this.activeState.zoom, a = !1) : (this.updateCache(s), this.options.onZoom(this.getRelativeZoom()))), f) { var t = this.options.beforePan(this.getPan(), { x: s.e, y: s.f }), A = !1, v = !1; t === !1 ? (s.e = this.getPan().x, s.f = this.getPan().y, A = v = !0) : r.isObject(t) && (t.x === !1 ? (s.e = this.getPan().x, A = !0) : r.isNumber(t.x) && (s.e = t.x), t.y === !1 ? (s.f = this.getPan().y, v = !0) : r.isNumber(t.y) && (s.f = t.y)), A && v || !this.isPanDifferent(s) ? f = !1 : (this.updateCache(s), this.options.onPan(this.getPan())); } (a || f) && this.updateCTMOnNextFrame(); } }, n.prototype.isZoomDifferent = function(s) { return this.activeState.zoom !== s.a; }, n.prototype.isPanDifferent = function(s) { return this.activeState.x !== s.e || this.activeState.y !== s.f; }, n.prototype.updateCache = function(s) { this.activeState.zoom = s.a, this.activeState.x = s.e, this.activeState.y = s.f; }, n.prototype.pendingUpdate = !1, n.prototype.updateCTMOnNextFrame = function() { this.pendingUpdate || (this.pendingUpdate = !0, this.requestAnimationFrame.call(window, this.updateCTMCached)); }, n.prototype.updateCTM = function() { var s = this.getCTM(); u.setCTM(this.viewport, s, this.defs), this.pendingUpdate = !1, this.options.onUpdatedCTM && this.options.onUpdatedCTM(s); }, ct = function(s, a) { return new n(s, a); }, ct; } var ft, ln; function Ao() { if (ln) return ft; ln = 1; var u = go(), r = mo(), n = gt(), s = mt(), a = vo(), f = function(l, h) { this.init(l, h); }, t = { viewportSelector: ".svg-pan-zoom_viewport", // Viewport selector. Can be querySelector string or SVGElement panEnabled: !0, // enable or disable panning (default enabled) controlIconsEnabled: !1, // insert icons to give user an option in addition to mouse events to control pan/zoom (default disabled) zoomEnabled: !0, // enable or disable zooming (default enabled) dblClickZoomEnabled: !0, // enable or disable zooming by double clicking (default enabled) mouseWheelZoomEnabled: !0, // enable or disable zooming by mouse wheel (default enabled) preventMouseEventsDefault: !0, // enable or disable preventDefault for mouse events zoomScaleSensitivity: 0.1, // Zoom sensitivity minZoom: 0.5, // Minimum Zoom level maxZoom: 10, // Maximum Zoom level fit: !0, // enable or disable viewport fit in SVG (default true) contain: !1, // enable or disable viewport contain the svg (default false) center: !0, // enable or disable viewport centering in SVG (default true) refreshRate: "auto", // Maximum number of frames per second (altering SVG's viewport) beforeZoom: null, onZoom: null, beforePan: null, onPan: null, customEventsHandler: null, eventsListenerElement: null, onUpdatedCTM: null }, A = { passive: !0 }; f.prototype.init = function(l, h) { var C = this; this.svg = l, this.defs = l.querySelector("defs"), s.setupSvgAttributes(this.svg), this.options = n.extend(n.extend({}, t), h), this.state = "none"; var y = s.getBoundingClientRectNormalized( l ); this.width = y.width, this.height = y.height, this.viewport = a( s.getOrCreateViewport(this.svg, this.options.viewportSelector), { svg: this.svg, width: this.width, height: this.height, fit: this.options.fit, contain: this.options.contain, center: this.options.center, refreshRate: this.options.refreshRate, // Put callbacks into functions as they can change through time beforeZoom: function(E, S) { if (C.viewport && C.options.beforeZoom) return C.options.beforeZoom(E, S); }, onZoom: function(E) { if (C.viewport && C.options.onZoom) return C.options.onZoom(E); }, beforePan: function(E, S) { if (C.viewport && C.options.beforePan) return C.options.beforePan(E, S); }, onPan: function(E) { if (C.viewport && C.options.onPan) return C.options.onPan(E); }, onUpdatedCTM: function(E) { if (C.viewport && C.options.onUpdatedCTM) return C.options.onUpdatedCTM(E); } } ); var m = this.getPublicInstance(); m.setBeforeZoom(this.options.beforeZoom), m.setOnZoom(this.options.onZoom), m.setBeforePan(this.options.beforePan), m.setOnPan(this.options.onPan), m.setOnUpdatedCTM(this.options.onUpdatedCTM), this.options.controlIconsEnabled && r.enable(this), this.lastMouseWheelEventTime = Date.now(), this.setupHandlers(); }, f.prototype.setupHandlers = function() { var l = this, h = null; if (this.eventListeners = { // Mouse down group mousedown: function(E) { var S = l.handleMouseDown(E, h); return h = E, S; }, touchstart: function(E) { var S = l.handleMouseDown(E, h); return h = E, S; }, // Mouse up group mouseup: function(E) { return l.handleMouseUp(E); }, touchend: function(E) { return l.handleMouseUp(E); }, // Mouse move group mousemove: function(E) { return l.handleMouseMove(E); }, touchmove: function(E) { return l.handleMouseMove(E); }, // Mouse leave group mouseleave: function(E) { return l.handleMouseUp(E); }, touchleave: function(E) { return l.handleMouseUp(E); }, touchcancel: function(E) { return l.handleMouseUp(E); } }, this.options.customEventsHandler != null) { this.options.customEventsHandler.init({ svgElement: this.svg, eventsListenerElement: this.options.eventsListenerElement, instance: this.getPublicInstance() }); var C = this.options.customEventsHandler.haltEventListeners; if (C && C.length) for (var y = C.length - 1; y >= 0; y--) this.eventListeners.hasOwnProperty(C[y]) && delete this.eventListeners[C[y]]; } for (var m in this.eventListeners) (this.options.eventsListenerElement || this.svg).addEventListener( m, this.eventListeners[m], this.options.preventMouseEventsDefault ? !1 : A ); this.options.mouseWheelZoomEnabled && (this.options.mouseWheelZoomEnabled = !1, this.enableMouseWheelZoom()); }, f.prototype.enableMouseWheelZoom = function() { if (!this.options.mouseWheelZoomEnabled) { var l = this; this.wheelListener = function(C) { return l.handleMouseWheel(C); }; var h = !this.options.preventMouseEventsDefault; u.on( this.options.eventsListenerElement || this.svg, this.wheelListener, h ), this.options.mouseWheelZoomEnabled = !0; } }, f.prototype.disableMouseWheelZoom = function() { if (this.options.mouseWheelZoomEnabled) { var l = !this.options.preventMouseEventsDefault; u.off( this.options.eventsListenerElement || this.svg, this.wheelListener, l ), this.options.mouseWheelZoomEnabled = !1; } }, f.prototype.handleMouseWheel = function(l) { if (!(!this.options.zoomEnabled || this.state !== "none")) { this.options.preventMouseEventsDefault && (l.preventDefault ? l.preventDefault() : l.returnValue = !1); var h = l.deltaY || 1, C = Date.now() - this.lastMouseWheelEventTime, y = 3 + Math.max(0, 30 - C); this.lastMouseWheelEventTime = Date.now(), "deltaMode" in l && l.deltaMode === 0 && l.wheelDelta && (h = l.deltaY === 0 ? 0 : Math.abs(l.wheelDelta) / l.deltaY), h = -0.3 < h && h < 0.3 ? h : (h > 0 ? 1 : -1) * Math.log(Math.abs(h) + 10) / y; var m = this.svg.getScreenCTM().inverse(), E = s.getEventPoint(l, this.svg).matrixTransform( m ), S = Math.pow(1 + this.options.zoomScaleSensitivity, -1 * h); this.zoomAtPoint(S, E); } }, f.prototype.zoomAtPoint = function(l, h, C) { var y = this.viewport.getOriginalState(); C ? (l = Math.max( this.options.minZoom * y.zoom, Math.min(this.options.maxZoom * y.zoom, l) ), l = l / this.getZoom()) : this.getZoom() * l < this.options.minZoom * y.zoom ? l = this.options.minZoom * y.zoom / this.getZoom() : this.getZoom() * l > this.options.maxZoom * y.zoom && (l = this.options.maxZoom * y.zoom / this.getZoom()); var m = this.viewport.getCTM(), E = h.matrixTransform(m.inverse()), S = this.svg.createSVGMatrix().translate(E.x, E.y).scale(l).translate(-E.x, -E.y), M = m.multiply(S); M.a !== m.a && this.viewport.setCTM(M); }, f.prototype.zoom = function(l, h) { this.zoomAtPoint( l, s.getSvgCenterPoint(this.svg, this.width, this.height), h ); }, f.prototype.publicZoom = function(l, h) { h && (l = this.computeFromRelativeZoom(l)), this.zoom(l, h); }, f.prototype.publicZoomAtPoint = function(l, h, C) { if (C && (l = this.computeFromRelativeZoom(l)), n.getType(h) !== "SVGPoint") if ("x" in h && "y" in h) h = s.createSVGPoint(this.svg, h.x, h.y); else throw new Error("Given point is invalid"); this.zoomAtPoint(l, h, C); }, f.prototype.getZoom = function() { return this.viewport.getZoom(); }, f.prototype.getRelativeZoom = function() { return this.viewport.getRelativeZoom(); }, f.prototype.computeFromRelativeZoom = function(l) { return l * this.viewport.getOriginalState().zoom; }, f.prototype.resetZoom = function() { var l = this.viewport.getOriginalState(); this.zoom(l.zoom, !0); }, f.prototype.resetPan = function() { this.pan(this.viewport.getOriginalState()); }, f.prototype.reset = function() { this.resetZoom(), this.resetPan(); }, f.prototype.handleDblClick = function(l) { if (this.options.preventMouseEventsDefault && (l.preventDefault ? l.preventDefault() : l.returnValue = !1), this.options.controlIconsEnabled) { var h = l.target.getAttribute("class") || ""; if (h.indexOf("svg-pan-zoom-control") > -1) return !1; } var C; l.shiftKey ? C = 1 / ((1 + this.options.zoomScaleSensitivity) * 2) : C = (1 + this.options.zoomScaleSensitivity) * 2; var y = s.getEventPoint(l, this.svg).matrixTransform( this.svg.getScreenCTM().inverse() ); this.zoomAtPoint(C, y); }, f.prototype.handleMouseDown = function(l, h) { this.options.preventMouseEventsDefault && (l.preventDefault ? l.preventDefault() : l.returnValue = !1), n.mouseAndTouchNormalize(l, this.svg), this.options.dblClickZoomEnabled && n.isDblClick(l, h) ? this.handleDblClick(l) : (this.state = "pan", this.firstEventCTM = this.viewport.getCTM(), this.stateOrigin = s.getEventPoint(l, this.svg).matrixTransform( this.firstEventCTM.inverse() )); }, f.prototype.handleMouseMove = function(l) { if (this.options.preventMouseEventsDefault && (l.preventDefault ? l.preventDefault() : l.returnValue = !1), this.state === "pan" && this.options.panEnabled) { var h = s.getEventPoint(l, this.svg).matrixTransform( this.firstEventCTM.inverse() ), C = this.firstEventCTM.translate( h.x - this.stateOrigin.x, h.y - this.stateOrigin.y ); this.viewport.setCTM(C); } }, f.prototype.handleMouseUp = function(l) { this.options.preventMouseEventsDefault && (l.preventDefault ? l.preventDefault() : l.returnValue = !1), this.state === "pan" && (this.state = "none"); }, f.prototype.fit = function() { var l = this.viewport.getViewBox(), h = Math.min( this.width / l.width, this.height / l.height ); this.zoom(h, !0); }, f.prototype.contain = function() { var l = this.viewport.getViewBox(), h = Math.max( this.width / l.width, this.height / l.height ); this.zoom(h, !0); }, f.prototype.center = function() { var l = this.viewport.getViewBox(), h = (this.width - (l.width + l.x * 2) * this.getZoom()) * 0.5, C = (this.height - (l.height + l.y * 2) * this.getZoom()) * 0.5; this.getPublicInstance().pan({ x: h, y: C }); }, f.prototype.updateBBox = function() { this.viewport.simpleViewBoxCache(); }, f.prototype.pan = function(l) { var h = this.viewport.getCTM(); h.e = l.x, h.f = l.y, this.viewport.setCTM(h); }, f.prototype.panBy = function(l) { var h = this.viewport.getCTM(); h.e += l.x, h.f += l.y, this.viewport.setCTM(h); }, f.prototype.getPan = function() { var l = this.viewport.getState(); return { x: l.x, y: l.y }; }, f.prototype.resize = function() { var l = s.getBoundingClientRectNormalized( this.svg ); this.width = l.width, this.height = l.height; var h = this.viewport; h.options.width = this.width, h.options.height = this.height, h.processCTM(), this.options.controlIconsEnabled && (this.getPublicInstance().disableControlIcons(), this.getPublicInstance().enableControlIcons()); }, f.prototype.destroy = function() { var l = this; this.beforeZoom = null, this.onZoom = null, this.beforePan = null, this.onPan = null, this.onUpdatedCTM = null, this.options.customEventsHandler != null && this.options.customEventsHandler.destroy({ svgElement: this.svg, eventsListenerElement: this.options.eventsListenerElement, instance: this.getPublicInstance() }); for (var h in this.eventListeners) (this.options.eventsListenerElement || this.svg).removeEventListener( h, this.eventListeners[h], this.options.preventMouseEventsDefault ? !1 : A ); this.disableMouseWheelZoom(), this.getPublicInstance().disableControlIcons(), this.reset(), v = v.filter(function(C) { return C.svg !== l.svg; }), delete this.options, delete this.viewport, delete this.publicInstance, delete this.pi, this.getPublicInstance = function() { return null; }; }, f.prototype.getPublicInstance = function() { var l = this; return this.publicInstance || (this.publicInstance = this.pi = { // Pan enablePan: function() { return l.options.panEnabled = !0, l.pi; }, disablePan: function() { return l.options.panEnabled = !1, l.pi; }, isPanEnabled: function() { return !!l.options.panEnabled; }, pan: function(h) { return l.pan(h), l.pi; }, panBy: function(h) { return l.panBy(h), l.pi; }, getPan: function() { return l.getPan(); }, // Pan event setBeforePan: function(h) { return l.options.beforePan = h === null ? null : n.proxy(h, l.publicInstance), l.pi; }, setOnPan: function(h) { return l.options.onPan = h === null ? null : n.proxy(h, l.publicInstance), l.pi; }, // Zoom and Control Icons enableZoom: function() { return l.options.zoomEnabled = !0, l.pi; }, disableZoom: function() { return l.options.zoomEnabled = !1, l.pi; }, isZoomEnabled: function() { return !!l.options.zoomEnabled; }, enableControlIcons: function(