!(function (e, t) {
    "object" == typeof exports && "object" == typeof module
        ? (module.exports = t())
        : "function" == typeof define && define.amd
        ? define([], t)
        : "object" == typeof exports
        ? (exports.supersetEmbeddedSdk = t())
        : (e.supersetEmbeddedSdk = t());
})(globalThis, () =>
    (() => {
        "use strict";
        var e = {
                d: (t, s) => {
                    for (var o in s)
                        e.o(s, o) &&
                            !e.o(t, o) &&
                            Object.defineProperty(t, o, {
                                enumerable: !0,
                                get: s[o],
                            });
                },
                o: (e, t) => Object.prototype.hasOwnProperty.call(e, t),
                r: (e) => {
                    "undefined" != typeof Symbol &&
                        Symbol.toStringTag &&
                        Object.defineProperty(e, Symbol.toStringTag, {
                            value: "Module",
                        }),
                        Object.defineProperty(e, "__esModule", { value: !0 });
                },
            },
            t = {};
        e.r(t), e.d(t, { embedDashboard: () => l });
        const s = "__embedded_comms__",
            o = { visible: "show_filters", expanded: "expand_filters" };
        var r = (function (e) {
            return (
                (e.GET = "get"),
                (e.REPLY = "reply"),
                (e.EMIT = "emit"),
                (e.ERROR = "error"),
                e
            );
        })(r || {});
        class i {
            constructor(e) {
                (this.port = void 0),
                    (this.name = ""),
                    (this.methods = {}),
                    (this.incrementor = 1),
                    (this.debugMode = void 0),
                    (this.isInitialised = void 0),
                    e && this.init(e);
            }
            init(e) {
                if (this.isInitialised)
                    return void this.logError("already initialized");
                const { port: t, name: s = "switchboard", debug: o = !1 } = e;
                (this.port = t),
                    (this.name = s),
                    (this.debugMode = o),
                    t.addEventListener("message", async (e) => {
                        this.log("message received", e);
                        const t = e.data;
                        if (
                            (function (e) {
                                return e.switchboardAction === r.GET;
                            })(t)
                        )
                            this.port.postMessage(
                                await this.getMethodResult(t)
                            );
                        else if (
                            (function (e) {
                                return e.switchboardAction === r.EMIT;
                            })(t)
                        ) {
                            const { method: e, args: s } = t,
                                o = this.methods[e];
                            o && o(s);
                        }
                    }),
                    (this.isInitialised = !0);
            }
            async getMethodResult({ messageId: e, method: t, args: s }) {
                const o = this.methods[t];
                if (null == o)
                    return {
                        switchboardAction: r.ERROR,
                        messageId: e,
                        error: `[${this.name}] Method "${t}" is not defined`,
                    };
                try {
                    const t = await o(s);
                    return {
                        switchboardAction: r.REPLY,
                        messageId: e,
                        result: t,
                    };
                } catch (s) {
                    return (
                        this.logError(s),
                        {
                            switchboardAction: r.ERROR,
                            messageId: e,
                            error: `[${this.name}] Method "${t}" threw an error`,
                        }
                    );
                }
            }
            defineMethod(e, t) {
                this.methods[e] = t;
            }
            get(e, t = void 0) {
                return new Promise((s, o) => {
                    if (!this.isInitialised)
                        return void o(new Error("Switchboard not initialised"));
                    const i = this.getNewMessageId(),
                        n = (e) => {
                            const t = e.data;
                            if (t.messageId === i)
                                if (
                                    (this.port.removeEventListener(
                                        "message",
                                        n
                                    ),
                                    (function (e) {
                                        return e.switchboardAction === r.REPLY;
                                    })(t))
                                )
                                    s(t.result);
                                else {
                                    const e = (function (e) {
                                        return e.switchboardAction === r.ERROR;
                                    })(t)
                                        ? t.error
                                        : "Unexpected response message";
                                    o(new Error(e));
                                }
                        };
                    this.port.addEventListener("message", n), this.port.start();
                    const a = {
                        switchboardAction: r.GET,
                        method: e,
                        messageId: i,
                        args: t,
                    };
                    this.port.postMessage(a);
                });
            }
            emit(e, t = void 0) {
                if (!this.isInitialised)
                    return void this.logError("Switchboard not initialised");
                const s = { switchboardAction: r.EMIT, method: e, args: t };
                this.port.postMessage(s);
            }
            start() {
                this.isInitialised
                    ? this.port.start()
                    : this.logError("Switchboard not initialised");
            }
            log(...e) {
                this.debugMode && console.debug(`[${this.name}]`, ...e);
            }
            logError(...e) {
                console.error(`[${this.name}]`, ...e);
            }
            getNewMessageId() {
                return `m_${this.name}_${this.incrementor++}`;
            }
        }
        new i();
        class n extends Error {}
        n.prototype.name = "InvalidTokenError";
        const a = 5e3,
            d = 1e4,
            c = 3e5;
        function h(e) {
            const t = (function (e, t) {
                    if ("string" != typeof e)
                        throw new n(
                            "Invalid token specified: must be a string"
                        );
                    t || (t = {});
                    const s = !0 === t.header ? 0 : 1,
                        o = e.split(".")[s];
                    if ("string" != typeof o)
                        throw new n(
                            `Invalid token specified: missing part #${s + 1}`
                        );
                    let r;
                    try {
                        r = (function (e) {
                            let t = e.replace(/-/g, "+").replace(/_/g, "/");
                            switch (t.length % 4) {
                                case 0:
                                    break;
                                case 2:
                                    t += "==";
                                    break;
                                case 3:
                                    t += "=";
                                    break;
                                default:
                                    throw new Error(
                                        "base64 string is not of the correct length"
                                    );
                            }
                            try {
                                return (function (e) {
                                    return decodeURIComponent(
                                        atob(e).replace(/(.)/g, (e, t) => {
                                            let s = t
                                                .charCodeAt(0)
                                                .toString(16)
                                                .toUpperCase();
                                            return (
                                                s.length < 2 && (s = "0" + s),
                                                "%" + s
                                            );
                                        })
                                    );
                                })(t);
                            } catch (e) {
                                return atob(t);
                            }
                        })(o);
                    } catch (e) {
                        throw new n(
                            `Invalid token specified: invalid base64 for part #${
                                s + 1
                            } (${e.message})`
                        );
                    }
                    try {
                        return JSON.parse(r);
                    } catch (e) {
                        throw new n(
                            `Invalid token specified: invalid json for part #${
                                s + 1
                            } (${e.message})`
                        );
                    }
                })(e),
                s = new Date(
                    /[^0-9\.]/g.test(t.exp) ? t.exp : 1e3 * parseFloat(t.exp)
                );
            return (
                ("Invalid Date" !== s.toString()
                    ? Math.max(d, s.getTime() - Date.now())
                    : c) - a
            );
        }
        async function l({
            id: e,
            supersetDomain: t,
            mountPoint: r,
            fetchGuestToken: n,
            dashboardUiConfig: a,
            debug: d = !1,
            iframeTitle: c = "Embedded Dashboard",
            iframeSandboxExtras: l = [],
        }) {
            function g(...t) {
                d &&
                    console.debug(
                        `[superset-embedded-sdk][dashboard ${e}]`,
                        ...t
                    );
            }
            function m() {
                let e = 0;
                return (
                    a &&
                        (a.hideTitle && (e += 1),
                        a.hideTab && (e += 2),
                        a.hideChartControls && (e += 8)),
                    e
                );
            }
            g("embedding"), t.endsWith("/") && (t = t.slice(0, -1));
            const [u, p] = await Promise.all([
                n(),
                (async function () {
                    return new Promise((n) => {
                        const h = document.createElement("iframe"),
                            u = a ? { uiConfig: `${m()}` } : void 0,
                            p = a?.filters || {},
                            b = Object.keys(p),
                            f = {
                                ...u,
                                ...Object.fromEntries(
                                    b.map((e) => [o[e], p[e]])
                                ),
                                ...a?.urlParams,
                            },
                            w = Object.keys(f).length
                                ? "?" + new URLSearchParams(f).toString()
                                : "";
                        h.sandbox.add("allow-same-origin"),
                            h.sandbox.add("allow-scripts"),
                            h.sandbox.add("allow-presentation"),
                            h.sandbox.add("allow-downloads"),
                            h.sandbox.add("allow-forms"),
                            h.sandbox.add("allow-popups"),
                            l.forEach((e) => {
                                h.sandbox.add(e);
                            }),
                            h.addEventListener("load", () => {
                                const e = new MessageChannel(),
                                    o = e.port1,
                                    r = e.port2;
                                h.contentWindow.postMessage(
                                    { type: s, handshake: "port transfer" },
                                    t,
                                    [r]
                                ),
                                    g("sent message channel to the iframe"),
                                    n(
                                        new i({
                                            port: o,
                                            name: "superset-embedded-sdk",
                                            debug: d,
                                        })
                                    );
                            }),
                            (h.src = `${t}/embedded/${e}${w}`),
                            (h.title = c),
                            r.replaceChildren(h),
                            g("placed the iframe");
                    });
                })(),
            ]);
            return (
                p.emit("guestToken", { guestToken: u }),
                g("sent guest token"),
                setTimeout(async function e() {
                    const t = await n();
                    p.emit("guestToken", { guestToken: t }),
                        setTimeout(e, h(t));
                }, h(u)),
                {
                    getScrollSize: () => p.get("getScrollSize"),
                    unmount: function () {
                        g("unmounting"), r.replaceChildren();
                    },
                    getDashboardPermalink: (e) =>
                        p.get("getDashboardPermalink", { anchor: e }),
                    getActiveTabs: () => p.get("getActiveTabs"),
                }
            );
        }
        return t;
    })()
);
