<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport"
        content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
    <title>QEC Playground</title>
    <link rel="icon" href="icon.svg">
    <link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons" rel="stylesheet"
        type="text/css">
    <link href="https://cdn.jsdelivr.net/npm/animate.css@^4.0.0/animate.min.css" rel="stylesheet" type="text/css">
    <link href="https://cdn.jsdelivr.net/npm/quasar@2.6.6/dist/quasar.prod.css" rel="stylesheet" type="text/css">
    <style>
        body,
        html {
            margin: 0;
            overflow: hidden;
            height: 100%;
        }

        :root {
            --s: 1;
            /* scale */
            --control-visibility: hidden;
        }

        .control-bar {
            position: fixed;
            width: calc(550px * var(--s));
            background-color: rgb(250, 250, 250);
            height: 100%;
            right: 0;
            overflow-y: hidden;
            overflow-x: hidden;
            visibility: var(--control-visibility);
        }

        .control-bar-inner {
            width: 550px;
            height: calc(100% / var(--s));
            transform: scale(var(--s));
            transform-origin: 0 0;
            font-size: 18px;
        }

        canvas {
            display: block;
        }

        .slider {
            margin-top: 0;
            margin-left: 35px;
            width: 480px;
        }

        .selector {
            margin-top: 20px;
            margin-left: 25px;
            width: 500px;
        }

        h1 {
            margin: 20px auto 0 auto;
            text-align: center;
            font-size: 40px;
            line-height: 40px;
        }

        h3 {
            margin: 0;
            font-size: 25px;
            line-height: 25px;
            font-weight: bold;
        }

        h5 {
            margin: 0;
            font-size: 20px;
            line-height: 20px;
            font-weight: bold;
        }

        .flex-center-div {
            width: 550px;
            margin-top: 10px;
            display: flex;
            justify-content: center;
            flex-direction: row;
        }

        .display-options-div {
            width: 550px;
            margin-top: 10px;
        }

        .display-options-row {
            width: 550px;
            margin-top: 0;
            display: flex;
            justify-content: center;
            flex-direction: row;
        }

        .display-options-row-left {
            width: 530px;
            margin-top: 0;
            margin-left: 20px;
            display: flex;
            justify-content: left;
            flex-direction: row;
        }

        .select-info-div-center {
            width: 530px;
            padding: 10px;
            margin: 10px;
            display: flex;
            justify-content: center;
            flex-direction: row;
        }

        .select-info-div {
            width: 530px;
            padding: 10px;
            margin: 10px;
        }

        .select-info-time {
            width: 190px;
            margin: 0 10px 0 10px;
        }

        .range-select {
            position: fixed;
            width: calc(50px * var(--s));
            background-color: rgb(250, 250, 250);
            height: 100%;
            right: calc(550px * var(--s));
            overflow-y: hidden;
            overflow-x: hidden;
            visibility: var(--control-visibility);
        }

        .range-select-inner {
            width: 50px;
            height: calc(100% / var(--s));
            transform: scale(var(--s));
            transform-origin: 0 0;
            font-size: 18px;
        }

        .range-select-qrange {
            height: 95%;
            margin-top: 30px;
        }

        .noise-model-row {
            width: 508px;
            margin-top: 0;
            display: flex;
            justify-content: center;
            flex-direction: row;
        }

        .noise-model-element {
            width: 120px;
            margin: 5px;
        }

        .noise-model-element-p {
            font-size: 80%;
        }

        .ref-position-btn {
            margin-left: 5px;
            margin-top: 2px;
            margin-bottom: 2px;
        }
    </style>
</head>

<body>
    <script src="https://cdn.jsdelivr.net/npm/vue@3.2.33/dist/vue.global.prod.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@2.6.6/dist/quasar.umd.prod.js"></script>
    <script id="MathJax-script" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>


    <div id="app">
        <div class="control-bar">
            <q-scroll-area class="control-bar-inner" :vertical-thumb-style="vertical_thumb_style"
                :horizontal-thumb-style="horizontal_thumb_style" :vertical-bar-style="vertical_bar_style"
                :horizontal-bar-style="horizontal_bar_style">
                <div class="flex-center-div">
                    <h1>QEC Playground</h1>
                </div>
                <q-banner inline-actions class="text-white bg-yellow-10" v-if="!is_browser_supported"
                    style="margin-top: 20px;">
                    Please use Chrome or Firefox browser (It has known issue in Safari)
                    <template v-slot:action>
                        <q-btn flat color="white" label="Dismiss" @click="is_browser_supported = true" />
                    </template>
                </q-banner>
                <q-banner inline-actions class="text-white bg-red" v-if="error_message != null"
                    style="margin-top: 20px;">
                    {{ error_message }}
                </q-banner>
                <q-banner inline-actions class="text-black bg-yellow" v-if="warning_message != null"
                    style="margin-top: 20px;">
                    {{ warning_message }}
                </q-banner>
                <div class="selector">
                    <q-select filled v-model="case_select_label" :options="case_labels" options-dense behavior="menu"
                        rounded>
                        <template v-slot:selected v-if="case_select_label && active_case">
                            {{ case_select_label }} &nbsp;
                            <q-badge color="blue" v-if="get_idx_from_label(case_select_label) == 0">noise
                                model</q-badge>
                            <q-badge color="red" v-else-if="active_case.qec_failed">logical error</q-badge>
                            <q-badge color="green" v-else>success</q-badge>
                            <span v-if="get_idx_from_label(case_select_label) > 0">&nbsp; {{
                                Object.keys(active_case.error_pattern).length }} physical errors</span>
                        </template>
                        <template v-slot:option="scope">
                            <q-item v-bind="scope.itemProps" v-if="scope.opt">
                                {{ scope.opt }} &nbsp;
                                <q-badge style="height: 20px;" color="blue"
                                    v-if="get_idx_from_label(scope.opt) == 0">noise model</q-badge>
                                <q-badge style="height: 20px;" color="red"
                                    v-else-if="get_case(get_idx_from_label(scope.opt)).qec_failed">logical
                                    error</q-badge>
                                <q-badge style="height: 20px;" color="green" v-else>success</q-badge>
                                <span v-if="get_idx_from_label(scope.opt) > 0">
                                    &nbsp; {{ Object.keys(get_case(get_idx_from_label(scope.opt)).error_pattern).length
                                    }} physical errors
                                </span>
                            </q-item>
                        </template>
                        <template v-slot:before>
                            <q-btn round flat icon="arrow_circle_left" :disabled="case_select == 0"
                                @click="case_select -= 1" size="xl" />
                        </template>
                        <template v-slot:after>
                            <q-btn round flat icon="arrow_circle_right" :disabled="case_select == case_num-1"
                                @click="case_select += 1" size="xl" />
                        </template>
                    </q-select>
                </div>
                <div class="slider">
                    <q-slider v-model="case_select" :min="0" :max="case_num-1" :step="1" snap thumb-size="25px"
                        track-size="8px"></q-slider>
                </div>
                <div class="flex-center-div">
                    <q-btn-toggle v-model="use_perspective_camera" no-caps rounded unelevated toggle-color="primary"
                        color="white" text-color="primary"
                        :options="[ { label: 'orthogonal', value: false }, { label: 'perspective', value: true } ]"
                        size="lg"></q-btn-toggle>
                    <span style="margin: 0 15px 0 15px; line-height: 52px; font-size: 25px;">camera</span>
                    <q-btn-dropdown color="warning" label="reset" no-caps size="lg" rounded>
                        <q-list>
                            <q-item clickable v-close-popup @click="reset_camera('top')">
                                <q-item-section>
                                    <q-item-label>from top</q-item-label>
                                </q-item-section>
                            </q-item>
                            <q-item clickable v-close-popup @click="reset_camera('front')">
                                <q-item-section>
                                    <q-item-label>from front</q-item-label>
                                </q-item-section>
                            </q-item>
                            <q-item clickable v-close-popup @click="reset_camera('left')">
                                <q-item-section>
                                    <q-item-label>from left</q-item-label>
                                </q-item-section>
                            </q-item>
                        </q-list>
                    </q-btn-dropdown>
                </div>
                <div class="flex-center-div">
                    <div><q-toggle v-model="show_config" label="render configs" size="md" /></div>
                    <div><q-toggle v-model="show_stats" label="performance stats" size="md" /></div>
                    <div><q-toggle v-model="lock_view" label="lock view" size="md" /></div>
                    <!-- <q-toggle v-model="show_hover_effect" label="hover effect" size="md"/> -->
                </div>
                <div class="flex-center-div">
                    <span style="margin: 0 5px 0 5px; line-height: 40px; font-size: 20px;">export image:</span>
                    <q-select rounded outlined v-model="export_scale_selected" :options="export_resolution_options"
                        label="resolution" style="width: 200px;" emit-value behavior="menu" map-options
                        dense></q-select>
                    <q-btn push color="brown-5" rounded label="preview" style="margin-left: 10px;" no-caps
                        @click="preview_image"></q-btn>
                    <q-btn push color="brown-5" rounded label="download" style="margin-left: 10px;" no-caps
                        @click="download_image"></q-btn>
                </div>
                <q-card bordered class="select-info-div-center" v-if="active_case && active_case.elapsed">
                    <q-card-section class="bg-cyan text-white select-info-time">
                        <div class="text-h6">{{ Number.parseFloat(active_case.elapsed.simulate).toExponential(3) }} (s)
                        </div>
                        <div class="text-subtitle2">Simulate Time</div>
                    </q-card-section>
                    <q-card-section class="bg-cyan text-white select-info-time">
                        <div class="text-h6">{{ Number.parseFloat(active_case.elapsed.decode).toExponential(3) }} (s)
                        </div>
                        <div class="text-subtitle2">Decode Time</div>
                    </q-card-section>
                    <q-card-section class="bg-cyan text-white select-info-time">
                        <div class="text-h6">{{ Number.parseFloat(active_case.elapsed.validate).toExponential(3) }} (s)
                        </div>
                        <div class="text-subtitle2">Validate Time</div>
                    </q-card-section>
                </q-card>
                <div class="display-options-div">
                    <div class="display-options-row">
                        <div><q-toggle v-model="display_qubits" label="qubits" size="md" /></div>
                        <div><q-toggle v-model="display_idle_sticks" label="idle sticks" size="md" /></div>
                        <div><q-toggle v-model="display_gates" label="gates" size="md" /></div>
                        <div><q-toggle v-model="display_measurements" label="measurements" size="md" /></div>
                    </div>
                    <div class="display-options-row-left" v-if="existed_noise_model">
                        <span style="line-height: 42px;">Noise Model: </span>
                        <div><q-toggle v-model="display_noise_model_pauli" label="Pauli errors" size="md" color="red" />
                        </div>
                        <div><q-toggle v-model="display_noise_model_erasure" label="erasure errors" size="md"
                                color="purple" /></div>
                    </div>
                    <div class="display-options-row-left" v-if="existed_model_graph">
                        <div><q-toggle left-label v-model="display_model_graph" label="Model Graph: " size="md" /></div>
                        <div style="margin-top: 3px;">
                            <q-option-group v-model="model_graph_region_display" :options="model_graph_region_options"
                                color="green" type="toggle" inline left-label dense />
                        </div>
                    </div>
                    <div class="display-options-row-left" v-if="existed_model_hypergraph">
                        <div><q-toggle left-label v-model="display_model_hypergraph" label="Model Hypergraph: "
                                size="md" /></div>
                    </div>
                    <div class="display-options-row-left" v-if="existed_tailored_model_graph">
                        <div>
                            <q-toggle left-label v-model="display_tailored_model_graph" label="Tailored Graph: "
                                size="md"></q-toggle>
                            <div v-if="existed_tailored_unfixed_stabilizer">
                                <q-toggle left-label v-model="display_tailored_unfixed_stabilizer"
                                    label="unfixed stabs:" size="md"></q-toggle>
                            </div>
                        </div>
                        <div style=" margin-top: 3px;">
                            <q-option-group v-model="tailored_model_graph_region_display"
                                :options="tailored_model_graph_region_options" color="green" type="toggle" inline
                                left-label dense />
                        </div>
                    </div>
                    <div class="display-options-row-left" v-if="case_select > 0">
                        <span style="line-height: 42px;">Case [{{ case_select }}]: </span>
                        <div><q-toggle v-model="display_error_pattern" label="actual error" size="md" /></div>
                        <div><q-toggle v-model="display_correction" label="correction" size="md" /></div>
                        <q-btn size="md" style="margin-left: 20px;" push no-caps color="white" text-color="primary"
                            :label="display_error_pattern ? '&nbsp;→ Correction&nbsp;' : '→ Actual Error'"
                            @click="toggle_error_correction"></q-btn>
                    </div>
                    <div class="display-options-row-left"
                        v-if="log_matchings_options != null && log_matchings_options.length > 0">
                        <div><q-toggle color="brown" left-label v-model="display_matchings" label="Matchings: "
                                size="md" />
                        </div>
                        <div style="margin-top: 3px;">
                            <q-option-group v-model="log_matchings_display" :options="log_matchings_options"
                                color="green" type="toggle" inline left-label dense />
                        </div>
                    </div>
                </div>
                <q-card bordered class="select-info-div"
                    v-if="current_selected != null && current_selected.type == 'qubit'">
                    <q-card-section class="bg-teal text-white">
                        <div class="text-h6">{{ qubit_type_name(current_selected.qubit_type) }} Qubit
                            at [...][{{ current_selected.i }}][{{ current_selected.j }}]</div>
                    </q-card-section>
                </q-card>
                <q-card bordered class="select-info-div"
                    v-if="current_selected != null && is_error_position(current_selected.type)">
                    <q-card-section class="bg-teal text-white">
                        <div class="text-h6">Noise Model at [{{ current_selected.t }}][{{ current_selected.i }}][{{
                            current_selected.j }}]
                            <span v-if="current_selected.gate_peer != null">, Gate Peer: {{ current_selected.gate_peer
                                }}</span>
                        </div>
                    </q-card-section>
                    <q-separator inset v-if="noise_model_info != null"></q-separator>
                    <q-card-section v-if="noise_model_info != null" style="padding: 0;">
                        <div class="noise-model-row">
                            <span style="line-height: 30px; position: relative; top: 5px; width: 50px;">Pauli: </span>
                            <div class="noise-model-element"
                                :style="{ color: noise_model_info.pp.px > 2e-300 ? non_zero_color : zero_color }">\(
                                p_{\small X}\):
                                <span class="noise-model-element-p">{{
                                    Number.parseFloat(noise_model_info.pp.px).toExponential(2) }}</span>
                            </div>
                            <div class="noise-model-element"
                                :style="{ color: noise_model_info.pp.py > 2e-300 ? non_zero_color : zero_color }">\(
                                p_{\small Y}\):
                                <span class="noise-model-element-p">{{
                                    Number.parseFloat(noise_model_info.pp.py).toExponential(2) }}</span>
                            </div>
                            <div class="noise-model-element"
                                :style="{ color: noise_model_info.pp.pz > 2e-300 ? non_zero_color : zero_color }">\(
                                p_{\small Z}\):
                                <span class="noise-model-element-p">{{
                                    Number.parseFloat(noise_model_info.pp.pz).toExponential(2) }}</span>
                            </div>
                        </div>
                        <div class="noise-model-row">
                            <span style="line-height: 30px; position: relative; top: 5px; width: 70px;">Erasure: </span>
                            <div class="noise-model-element"
                                :style="{ color: noise_model_info.pe > 2e-300 ? non_zero_color : zero_color }">\(
                                p_{\small E}\):
                                <span class="noise-model-element-p">{{
                                    Number.parseFloat(noise_model_info.pe).toExponential(2) }}</span>
                            </div>
                            <div class="noise-model-element"
                                :style="{ width: '220px', 'margin-left': '56px', color: noise_model_info.pp.sum > 6e-300 ? non_zero_color : zero_color }">
                                \( p_{\small X} {\small+} p_{\small Y} {\small+} p_{\small Z} \):
                                <span class="noise-model-element-p">{{
                                    Number.parseFloat(noise_model_info.pp.sum).toExponential(2) }}</span>
                            </div>
                        </div>
                        <div class="noise-model-row" v-if="noise_model_info.corr_pe != null"
                            style="border: 1px dashed grey;">
                            <div class="noise-model-element"
                                :style="{ color: noise_model_info.corr_pe.sum > 2e-300 ? non_zero_color : zero_color, 'background-color': 'lightgrey' }">
                                \( \sum p_{\small ee}\):
                                <span class="noise-model-element-p">{{
                                    Number.parseFloat(noise_model_info.corr_pe.sum).toExponential(2) }}
                            </div>
                            <div class="noise-model-element"
                                :style="{ color: noise_model_info.corr_pe.pie > 2e-300 ? non_zero_color : zero_color }">
                                \( p_{\small I\otimes E}\):
                                <span class="noise-model-element-p">{{
                                    Number.parseFloat(noise_model_info.corr_pe.pie).toExponential(2) }}
                            </div>
                            <div class="noise-model-element"
                                :style="{ color: noise_model_info.corr_pe.pei > 2e-300 ? non_zero_color : zero_color }">
                                \( p_{\small E\otimes I}\):
                                <span class="noise-model-element-p">{{
                                    Number.parseFloat(noise_model_info.corr_pe.pei).toExponential(2) }}
                            </div>
                            <div class="noise-model-element"
                                :style="{ color: noise_model_info.corr_pe.pee > 2e-300 ? non_zero_color : zero_color }">
                                \( p_{\small E\otimes E}\):
                                <span class="noise-model-element-p">{{
                                    Number.parseFloat(noise_model_info.corr_pe.pee).toExponential(2) }}
                            </div>
                        </div>
                        <div v-if="noise_model_info.corr_pp != null" style="border: 1px dashed grey;">
                            <div class="noise-model-row">
                                <div class="noise-model-element"
                                    :style="{ color: noise_model_info.corr_pp.sum > 30e-300 ? non_zero_color : zero_color, 'background-color': 'lightgrey' }">
                                    \( \sum p_{\small pp}\):
                                    <span class="noise-model-element-p">{{
                                        Number.parseFloat(noise_model_info.corr_pp.sum).toExponential(2) }}
                                </div>
                                <div class="noise-model-element"
                                    :style="{ color: noise_model_info.corr_pp.pix > 30e-300 ? non_zero_color : zero_color }">
                                    \( p_{\small I\otimes X}\):
                                    <span class="noise-model-element-p">{{
                                        Number.parseFloat(noise_model_info.corr_pp.pix).toExponential(2) }}
                                </div>
                                <div class="noise-model-element"
                                    :style="{ color: noise_model_info.corr_pp.piy > 30e-300 ? non_zero_color : zero_color }">
                                    \( p_{\small I\otimes Y}\):
                                    <span class="noise-model-element-p">{{
                                        Number.parseFloat(noise_model_info.corr_pp.piy).toExponential(2) }}
                                </div>
                                <div class="noise-model-element"
                                    :style="{ color: noise_model_info.corr_pp.piz > 30e-300 ? non_zero_color : zero_color }">
                                    \( p_{\small I\otimes Z}\):
                                    <span class="noise-model-element-p">{{
                                        Number.parseFloat(noise_model_info.corr_pp.piz).toExponential(2) }}
                                </div>
                            </div>
                            <div class="noise-model-row">
                                <div class="noise-model-element"
                                    :style="{ color: noise_model_info.corr_pp.pxi > 30e-300 ? non_zero_color : zero_color }">
                                    \( p_{\small X\otimes I}\):
                                    <span class="noise-model-element-p">{{
                                        Number.parseFloat(noise_model_info.corr_pp.pxi).toExponential(2) }}
                                </div>
                                <div class="noise-model-element"
                                    :style="{ color: noise_model_info.corr_pp.pxx > 30e-300 ? non_zero_color : zero_color }">
                                    \( p_{\small X\otimes X}\):
                                    <span class="noise-model-element-p">{{
                                        Number.parseFloat(noise_model_info.corr_pp.pxx).toExponential(2) }}
                                </div>
                                <div class="noise-model-element"
                                    :style="{ color: noise_model_info.corr_pp.pxy > 30e-300 ? non_zero_color : zero_color }">
                                    \( p_{\small X\otimes Y}\):
                                    <span class="noise-model-element-p">{{
                                        Number.parseFloat(noise_model_info.corr_pp.pxy).toExponential(2) }}
                                </div>
                                <div class="noise-model-element"
                                    :style="{ color: noise_model_info.corr_pp.pxz > 30e-300 ? non_zero_color : zero_color }">
                                    \( p_{\small X\otimes Z}\):
                                    <span class="noise-model-element-p">{{
                                        Number.parseFloat(noise_model_info.corr_pp.pxz).toExponential(2) }}
                                </div>
                            </div>
                            <div class="noise-model-row">
                                <div class="noise-model-element"
                                    :style="{ color: noise_model_info.corr_pp.pyi > 30e-300 ? non_zero_color : zero_color }">
                                    \( p_{\small Y\otimes I}\):
                                    <span class="noise-model-element-p">{{
                                        Number.parseFloat(noise_model_info.corr_pp.pyi).toExponential(2) }}
                                </div>
                                <div class="noise-model-element"
                                    :style="{ color: noise_model_info.corr_pp.pyx > 30e-300 ? non_zero_color : zero_color }">
                                    \( p_{\small Y\otimes X}\):
                                    <span class="noise-model-element-p">{{
                                        Number.parseFloat(noise_model_info.corr_pp.pyx).toExponential(2) }}
                                </div>
                                <div class="noise-model-element"
                                    :style="{ color: noise_model_info.corr_pp.pyy > 30e-300 ? non_zero_color : zero_color }">
                                    \( p_{\small Y\otimes Y}\):
                                    <span class="noise-model-element-p">{{
                                        Number.parseFloat(noise_model_info.corr_pp.pyy).toExponential(2) }}
                                </div>
                                <div class="noise-model-element"
                                    :style="{ color: noise_model_info.corr_pp.pyz > 30e-300 ? non_zero_color : zero_color }">
                                    \( p_{\small Y\otimes Z}\):
                                    <span class="noise-model-element-p">{{
                                        Number.parseFloat(noise_model_info.corr_pp.pyz).toExponential(2) }}
                                </div>
                            </div>
                            <div class="noise-model-row">
                                <div class="noise-model-element"
                                    :style="{ color: noise_model_info.corr_pp.pzi > 30e-300 ? non_zero_color : zero_color }">
                                    \( p_{\small Z\otimes I}\):
                                    <span class="noise-model-element-p">{{
                                        Number.parseFloat(noise_model_info.corr_pp.pzi).toExponential(2) }}
                                </div>
                                <div class="noise-model-element"
                                    :style="{ color: noise_model_info.corr_pp.pzx > 30e-300 ? non_zero_color : zero_color }">
                                    \( p_{\small Z\otimes X}\):
                                    <span class="noise-model-element-p">{{
                                        Number.parseFloat(noise_model_info.corr_pp.pzx).toExponential(2) }}
                                </div>
                                <div class="noise-model-element"
                                    :style="{ color: noise_model_info.corr_pp.pzy > 30e-300 ? non_zero_color : zero_color }">
                                    \( p_{\small Z\otimes Y}\):
                                    <span class="noise-model-element-p">{{
                                        Number.parseFloat(noise_model_info.corr_pp.pzy).toExponential(2) }}
                                </div>
                                <div class="noise-model-element"
                                    :style="{ color: noise_model_info.corr_pp.pzz > 30e-300 ? non_zero_color : zero_color }">
                                    \( p_{\small Z\otimes Z}\):
                                    <span class="noise-model-element-p">{{
                                        Number.parseFloat(noise_model_info.corr_pp.pzz).toExponential(2) }}
                                </div>
                            </div>
                        </div>
                        <div v-if="noise_model_info.additional.length > 0" style="margin-top: 10px;">
                            <h5>Other Contributing Noise:</h5>
                            <div v-for="(ad, index) in noise_model_info.additional" style="margin-top: 5px;">
                                <span>> </span>
                                <span v-if="ad.source == 'corr_pp'">two-qubit Pauli from
                                    <q-btn class="ref-position-btn" size="md" dense
                                        :label="`[${ad.t}][${ad.i}][${ad.j}]`" color="red" glossy
                                        @mouseover="ref_btn_hover(`[${ad.t}][${ad.i}][${ad.j}]`)"
                                        @mouseleave="ref_btn_leave()"
                                        @click="ref_btn_click(`[${ad.t}][${ad.i}][${ad.j}]`)" />
                                </span>
                                <span v-if="ad.source == 'corr_pe'">two-qubit erasure from
                                    <q-btn class="ref-position-btn" size="md" dense
                                        :label="`[${ad.t}][${ad.i}][${ad.j}]`" color="purple" glossy
                                        @mouseover="ref_btn_hover(`[${ad.t}][${ad.i}][${ad.j}]`)"
                                        @mouseleave="ref_btn_leave()"
                                        @click="ref_btn_click(`[${ad.t}][${ad.i}][${ad.j}]`)"></q-btn>
                                </span>
                                <span v-if="ad.source == 'add_p' || ad.source == 'add_e'">{{ ad.source == 'add_p' ?
                                    "Pauli": "erasure" }} from additional noise [{{ ad.add_idx }}], probability: <span
                                        :style="{ color: non_zero_color }">{{
                                        Number.parseFloat(ad.noise.p).toExponential(2) }}</span>
                                    <span v-if="Object.entries(ad.noise.pe).length > 0">
                                        <br /><span style="margin-left: 20px;">Pauli: </span>
                                        <q-btn v-for="(error, pos_str) in ad.noise.pe" class="ref-position-btn"
                                            size="md" dense :label="pos_str + ':' + error.toUpperCase()" color="red"
                                            glossy @mouseover="ref_btn_hover(pos_str)" @mouseleave="ref_btn_leave()"
                                            @click="ref_btn_click(pos_str)"></q-btn>
                                    </span>
                                    <span v-if="ad.noise.ee.length > 0">
                                        <br /><span style="margin-left: 20px;">erasures: </span>
                                        <q-btn v-for="pos_str in ad.noise.ee" class="ref-position-btn" size="md" dense
                                            :label="pos_str" color="purple" glossy @mouseover="ref_btn_hover(pos_str)"
                                            @mouseleave="ref_btn_leave()" @click="ref_btn_click(pos_str)"></q-btn>
                                    </span>
                                </span>
                            </div>
                        </div>
                    </q-card-section>
                </q-card>
                <q-card bordered class="select-info-div"
                    v-if="current_selected != null && current_selected.type == 'model_hypergraph_vertex'">
                    <q-card-section class="bg-green text-white">
                        <div class="text-h6">Vertex {{ current_selected.vertex_index }} at {{
                            selected_hypergraph_info.vertex_position }}</div>
                    </q-card-section>
                    <q-separator inset></q-separator>
                    <q-card-section>
                        <div v-for="edge of selected_hypergraph_info.neighbor_edges" style="margin-top: 15px;">
                            <q-btn color="teal" no-caps size="12px" rounded padding="none md"
                                @mouseenter="ref_btn_hover_general('model_hypergraph_edge', { edge_index: edge.edge_index })"
                                @mouseleave="ref_btn_leave()"
                                @click="jump_to('model_hypergraph_edge', { edge_index: edge.edge_index })">
                                <div class="text-center">
                                    Edge</span><br>{{ edge.edge_index }}
                                </div>
                            </q-btn>
                            &nbsp;&nbsp;p: {{ Number.parseFloat(edge.probability).toExponential(2) }},
                            <span class="bg-green-2" style="padding: 14px 5px; border-radius: 5px; line-height: 45px;">V
                                =
                                [<q-btn color="green" no-caps unelevated v-for="vertex of edge.defect_vertices"
                                    style="margin-left: 5px; position: relative; bottom: 2px;" padding="2px 4px"
                                    size="12px"
                                    @mouseenter="ref_btn_hover_general('model_hypergraph_vertex', { vertex_index: vertex.vertex_index })"
                                    @mouseleave="ref_btn_leave()"
                                    @click="jump_to('model_hypergraph_vertex', { vertex_index: vertex.vertex_index })">Vid:
                                    {{ vertex.vertex_index }}<br>{{ vertex.position_str }}</q-btn>
                                ]</span>
                        </div>
                    </q-card-section>
                </q-card>
                <q-card bordered class="select-info-div"
                    v-if="current_selected != null && current_selected.type == 'model_hypergraph_edge'">
                    <q-card-section class="bg-teal text-white">
                        <div class="text-h6">Edge {{ current_selected.edge_index }}</div>
                    </q-card-section>
                    <q-separator inset></q-separator>
                    <q-card-section>
                        <div>
                            p: {{ Number.parseFloat(selected_hypergraph_info.probability).toExponential(2) }},
                            <span class="bg-green-2" style="padding: 14px 5px; border-radius: 5px; line-height: 45px;">V
                                =
                                [<q-btn color="green" no-caps unelevated
                                    v-for="vertex of selected_hypergraph_info.defect_vertices"
                                    style="margin-left: 5px; position: relative; bottom: 2px;" padding="2px 4px"
                                    size="12px"
                                    @mouseenter="ref_btn_hover_general('model_hypergraph_vertex', { vertex_index: vertex.vertex_index })"
                                    @mouseleave="ref_btn_leave()"
                                    @click="jump_to('model_hypergraph_vertex', { vertex_index: vertex.vertex_index })">Vid:
                                    {{ vertex.vertex_index }}<br>{{ vertex.position_str }}</q-btn>
                                ]</span>
                        </div>
                        <div class="text-h6">Contributing Independent Errors:</div>
                        <div v-for="hyperedge of selected_hypergraph_info.all_hyperedges" style="margin-top: 15px;">
                            p: {{ Number.parseFloat(hyperedge.probability).toExponential(2) }},
                            <span class="bg-red-2"
                                style="padding: 14px 5px; border-radius: 5px; line-height: 45px;">Error =
                                [<q-btn color="red" no-caps unelevated v-for="error of hyperedge.error_pattern"
                                    style="margin-left: 5px; position: relative; bottom: 2px;" padding="2px 4px"
                                    size="12px" @mouseover="ref_btn_hover(error.position_str)"
                                    @mouseleave="ref_btn_leave()" @click="ref_btn_click(error.position_str)">{{
                                    error.position_str }}<br>{{ error.type }}</q-btn>
                                ]</span>,
                            <span class="bg-orange-2"
                                style="padding: 14px 5px; border-radius: 5px; line-height: 45px;">Correction =
                                [<q-btn color="orange" no-caps unelevated v-for="correction of hyperedge.correction"
                                    style="margin-left: 5px; position: relative; bottom: 2px;" padding="2px 4px"
                                    size="12px" @mouseover="ref_btn_hover(correction.position_str)"
                                    @mouseleave="ref_btn_leave()" @click="ref_btn_click(correction.position_str)">{{
                                    correction.position_str }}<br>{{ correction.type }}</q-btn>
                                ]</span>,
                        </div>
                    </q-card-section>
                </q-card>
                <q-card bordered class="select-info-div"
                    v-if="current_selected != null && current_selected.type == 'model_graph_vertex'">
                    <q-card-section class="bg-green text-white">
                        <div class="text-h6">Vertex [{{ current_selected.t }}][{{ current_selected.i }}][{{
                            current_selected.j }}] (region {{ current_selected.region_idx }})</div>
                    </q-card-section>
                    <q-separator inset></q-separator>
                    <q-card-section>
                        <div v-for="(edge, peer_position_str) of selected_model_graph_info.edges"
                            style="margin-top: 5px;">
                            <q-btn color="teal" no-caps size="12px" rounded padding="none md"
                                @mouseenter="ref_btn_hover_general('model_graph_edge', edge.userData)"
                                @mouseleave="ref_btn_leave()" @click="jump_to('model_graph_edge', edge.userData)">
                                <div class="text-center">
                                    Edge</span><br>{{ peer_position_str }}
                                </div>
                            </q-btn>
                            <div class="text-center"
                                style="display: inline-block; font-size: 15px; position: relative; top: 10px; margin-left: 10px;">
                                probability: {{ Number.parseFloat(edge.p).toExponential(3) }}<br>weight: {{
                                Number.parseFloat(edge.w).toExponential(3) }}
                            </div>,
                            <div
                                style="display: inline-block; font-size: 15px; position: relative; top: 10px; margin-left: 10px;">
                                error pattern: <span v-for="(error_type, position_str) of edge.e"
                                    @mouseover="ref_btn_hover(position_str)" @mouseleave="ref_btn_leave()"
                                    @click="ref_btn_click(position_str)">
                                    {{ error_type }}({{ position_str }})
                                </span><br>correction: <span v-for="(error_type, position_str) of edge.c"
                                    @mouseover="ref_btn_hover(position_str)" @mouseleave="ref_btn_leave()"
                                    @click="ref_btn_click(position_str)">
                                    {{ error_type }}({{ position_str }})
                                </span>
                            </div>
                        </div>
                        <div style="margin-top: 5px;" v-if="selected_model_graph_info.boundary != null">
                            <q-btn color="teal-9" no-caps size="12px" rounded padding="none md">
                                <div class="text-center">
                                    Boundary
                                </div>
                            </q-btn>
                            <div class="text-center"
                                style="display: inline-block; font-size: 15px; position: relative; top: 10px; margin-left: 10px;">
                                probability: {{ Number.parseFloat(selected_model_graph_info.boundary.p).toExponential(3)
                                }}<br>
                                weight: {{ Number.parseFloat(selected_model_graph_info.boundary.w).toExponential(3) }}
                            </div>,
                            <div
                                style="display: inline-block; font-size: 15px; position: relative; top: 10px; margin-left: 10px;">
                                error pattern: <span
                                    v-for="(error_type, position_str) of selected_model_graph_info.boundary.e"
                                    @mouseover="ref_btn_hover(position_str)" @mouseleave="ref_btn_leave()"
                                    @click="ref_btn_click(position_str)">
                                    {{ error_type }}({{ position_str }})
                                </span><br>correction: <span
                                    v-for="(error_type, position_str) of selected_model_graph_info.boundary.c"
                                    @mouseover="ref_btn_hover(position_str)" @mouseleave="ref_btn_leave()"
                                    @click="ref_btn_click(position_str)">
                                    {{ error_type }}({{ position_str }})
                                </span>
                            </div>
                        </div>
                    </q-card-section>
                </q-card>
                <q-card bordered class="select-info-div"
                    v-if="current_selected != null && (
                        current_selected.type == 'model_graph_edge' || current_selected.type == 'model_graph_boundary')">
                    <q-card-section class="text-white bg-teal">
                        <div class="text-h6">Edge
                            <q-btn color="green" no-caps unelevated
                                @mouseenter="ref_btn_hover_general('model_graph_vertex', selected_model_graph_info.vertex_user_data)"
                                @mouseleave="ref_btn_leave()"
                                @click="jump_to('model_graph_vertex', selected_model_graph_info.vertex_user_data)"
                                style="margin-left: 0; position: relative; bottom: 2px;" padding="8px 12px" size="20px">
                                [{{ current_selected.t }}][{{ current_selected.i }}][{{ current_selected.j }}]
                            </q-btn>
                            <span v-if="selected_model_graph_info.peer_user_data != null">
                                to <q-btn color="green" no-caps unelevated
                                    @mouseenter="ref_btn_hover_general('model_graph_vertex', selected_model_graph_info.peer_user_data)"
                                    @mouseleave="ref_btn_leave()"
                                    @click="jump_to('model_graph_vertex', selected_model_graph_info.peer_user_data)"
                                    style="margin-left: 0; position: relative; bottom: 2px;" padding="8px 12px"
                                    size="20px">
                                    {{ current_selected.peer }}
                                </q-btn>
                            </span>
                        </div>
                    </q-card-section>
                    <q-separator inset></q-separator>
                    <q-card-section>
                        <div style="margin-bottom: 10px;">
                            probability: {{ Number.parseFloat(selected_model_graph_info.probability).toExponential(2)
                            }},&nbsp;&nbsp;
                            weight: {{ Number.parseFloat(selected_model_graph_info.weight).toExponential(2) }}
                        </div>
                        <div class="text-h6">Contributing Independent Errors:</div>
                        <div v-for="edge of selected_model_graph_info.all_edges" style="margin-top: 15px;">
                            p: {{ Number.parseFloat(edge.probability).toExponential(2) }},
                            <span class="bg-red-2"
                                style="padding: 14px 5px; border-radius: 5px; line-height: 45px;">Error =
                                [<q-btn color="red" no-caps unelevated v-for="error of edge.error_pattern"
                                    style="margin-left: 5px; position: relative; bottom: 2px;" padding="2px 4px"
                                    size="12px" @mouseover="ref_btn_hover(error.position_str)"
                                    @mouseleave="ref_btn_leave()" @click="ref_btn_click(error.position_str)">{{
                                    error.position_str }}<br>{{ error.type }}</q-btn>
                                ]</span>,
                            <span class="bg-orange-2"
                                style="padding: 14px 5px; border-radius: 5px; line-height: 45px;">Correction =
                                [<q-btn color="orange" no-caps unelevated v-for="correction of edge.correction"
                                    style="margin-left: 5px; position: relative; bottom: 2px;" padding="2px 4px"
                                    size="12px" @mouseover="ref_btn_hover(correction.position_str)"
                                    @mouseleave="ref_btn_leave()" @click="ref_btn_click(correction.position_str)">{{
                                    correction.position_str }}<br>{{ correction.type }}</q-btn>
                                ]</span>,
                        </div>
                    </q-card-section>
                </q-card>
                <q-card bordered class="select-info-div"
                    v-if="current_selected != null && current_selected.type == 'tailored_vertex'">
                    <q-card-section class="bg-blue text-white">
                        <div class="text-h6">Vertex [{{ current_selected.t }}][{{ current_selected.i }}][{{
                            current_selected.j }}]
                            <span v-if="current_selected.is_virtual"> (virtual)</span>
                            <span v-if="current_selected.is_corner"> (corner <q-btn color="red" no-caps unelevated
                                    @mouseenter="ref_btn_hover_general('tailored_vertex', selected_tailored_info.corner_pair_user_data)"
                                    @mouseleave="ref_btn_leave()"
                                    @click="jump_to('tailored_vertex', selected_tailored_info.corner_pair_user_data)"
                                    style="margin-left: 0; position: relative; bottom: 2px;" padding="8px 12px"
                                    size="20px">
                                    [{{ current_selected.corner_pair.t }}][{{ current_selected.corner_pair.i }}][{{
                                    current_selected.corner_pair.j }}]
                                </q-btn>)</span>
                        </div>
                    </q-card-section>
                    <div v-for="tsg of Object.values(tailored_model_graph_region_display)">
                        <q-separator inset></q-separator>
                        <q-card-section>
                            <div v-for="(edge, peer_position_str) of selected_tailored_info.triple_edges[tsg]"
                                style="margin-top: 5px;">
                                <q-btn :color="sequential_colors[tsg + 1][0]" no-caps size="12px" rounded
                                    padding="none md"
                                    @mouseenter="ref_btn_hover_general('tailored_edge', edge.userData)"
                                    @mouseleave="ref_btn_leave()" @click="jump_to('tailored_edge', edge.userData)">
                                    <div class="text-center">
                                        Edge</span><br>{{ peer_position_str }}
                                    </div>
                                </q-btn>
                                <div class="text-center"
                                    style="display: inline-block; font-size: 15px; position: relative; top: 10px; margin-left: 10px;">
                                    probability: {{ Number.parseFloat(edge.p).toExponential(3) }}<br>weight: {{
                                    Number.parseFloat(edge.w).toExponential(3) }}
                                </div>,
                                <div
                                    style="display: inline-block; font-size: 15px; position: relative; top: 10px; margin-left: 10px;">
                                    error pattern: <span v-for="(error_type, position_str) of edge.e"
                                        @mouseover="ref_btn_hover(position_str)" @mouseleave="ref_btn_leave()"
                                        @click="ref_btn_click(position_str)">
                                        {{ error_type }}({{ position_str }})
                                    </span><br>correction: <span v-for="(error_type, position_str) of edge.c"
                                        @mouseover="ref_btn_hover(position_str)" @mouseleave="ref_btn_leave()"
                                        @click="ref_btn_click(position_str)">
                                        {{ error_type }}({{ position_str }})
                                    </span>
                                </div>
                            </div>
                        </q-card-section>
                    </div>
                </q-card>
                <q-card bordered class="select-info-div"
                    v-if="current_selected != null && current_selected.type == 'tailored_edge'">
                    <q-card-section class="text-white" :class="{ 'bg-green': current_selected.tsg == 0
                        , 'bg-deep-purple': current_selected.tsg == 1
                        , 'bg-brown': current_selected.tsg == 2 }">
                        <div class="text-h6">Edge
                            <q-btn :color="selected_tailored_info.vertex_user_data.color" no-caps unelevated
                                @mouseenter="ref_btn_hover_general('tailored_vertex', selected_tailored_info.vertex_user_data)"
                                @mouseleave="ref_btn_leave()"
                                @click="jump_to('tailored_vertex', selected_tailored_info.vertex_user_data)"
                                style="margin-left: 0; position: relative; bottom: 2px;" padding="8px 12px" size="20px">
                                [{{ current_selected.t }}][{{ current_selected.i }}][{{ current_selected.j }}]
                            </q-btn> to <q-btn :color="selected_tailored_info.peer_user_data.color" no-caps unelevated
                                @mouseenter="ref_btn_hover_general('tailored_vertex', selected_tailored_info.peer_user_data)"
                                @mouseleave="ref_btn_leave()"
                                @click="jump_to('tailored_vertex', selected_tailored_info.peer_user_data)"
                                style="margin-left: 0; position: relative; bottom: 2px;" padding="8px 12px" size="20px">
                                {{ current_selected.peer }}
                            </q-btn>
                        </div>
                    </q-card-section>
                    <q-separator inset></q-separator>
                    <q-card-section>
                        <div style="margin-bottom: 10px;">
                            probability: {{ Number.parseFloat(selected_tailored_info.probability).toExponential(2)
                            }},&nbsp;&nbsp;
                            weight: {{ Number.parseFloat(selected_tailored_info.weight).toExponential(2) }}
                        </div>
                        <div class="text-h6">Contributing Independent Errors:</div>
                        <div v-for="edge of selected_tailored_info.all_edges" style="margin-top: 15px;">
                            p: {{ Number.parseFloat(edge.probability).toExponential(2) }},
                            <span class="bg-red-2"
                                style="padding: 14px 5px; border-radius: 5px; line-height: 45px;">Error =
                                [<q-btn color="red" no-caps unelevated v-for="error of edge.error_pattern"
                                    style="margin-left: 5px; position: relative; bottom: 2px;" padding="2px 4px"
                                    size="12px" @mouseover="ref_btn_hover(error.position_str)"
                                    @mouseleave="ref_btn_leave()" @click="ref_btn_click(error.position_str)">{{
                                    error.position_str }}<br>{{ error.type }}</q-btn>
                                ]</span>,
                            <span class="bg-orange-2"
                                style="padding: 14px 5px; border-radius: 5px; line-height: 45px;">Correction =
                                [<q-btn color="orange" no-caps unelevated v-for="correction of edge.correction"
                                    style="margin-left: 5px; position: relative; bottom: 2px;" padding="2px 4px"
                                    size="12px" @mouseover="ref_btn_hover(correction.position_str)"
                                    @mouseleave="ref_btn_leave()" @click="ref_btn_click(correction.position_str)">{{
                                    correction.position_str }}<br>{{ correction.type }}</q-btn>
                                ]</span>,
                        </div>
                    </q-card-section>
                </q-card>
            </q-scroll-area>
        </div>
        <div class="range-select">
            <div class="range-select-inner">
                <q-range class="range-select-qrange" v-model="t_range" :min="0" :max="t_length" vertical label snap
                    label-always dense markers color="teal-4" track-size="8px" style="margin-left: 37px;"
                    switch-label-side thumb-size="30px" drag-range reverse />
            </div>
        </div>
    </div>

    <script type="importmap">
{
    "imports": {
        "three": "https://cdn.jsdelivr.net/npm/three@0.139.2/build/three.module.js",
        "./node_modules/three/examples/jsm/controls/OrbitControls.js": "https://cdn.jsdelivr.net/npm/three@0.139.2/examples/jsm/controls/OrbitControls.js",
        "./node_modules/three/examples/jsm/geometries/ConvexGeometry.js": "https://cdn.jsdelivr.net/npm/three@0.139.2/examples/jsm/geometries/ConvexGeometry.js",
        "./node_modules/three/examples/jsm/libs/stats.module.js": "https://cdn.jsdelivr.net/npm/three@0.139.2/examples/jsm/libs/stats.module.js",
        "./node_modules/three/examples/jsm/libs/lil-gui.module.min.js": "https://cdn.jsdelivr.net/npm/three@0.139.2/examples/jsm/libs/lil-gui.module.min.js"
    }
}
</script>
    <script src="https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js"></script>

    <script type="module" src="./index.js"></script>
    <!-- <script>
// always fetch the latest script and avoid caching
var index_script = document.createElement('script');
index_script.setAttribute('src','./index.js?v=' + Math.random());
index_script.setAttribute('type','module');
document.body.appendChild(index_script);
</script> -->

</body>

</html>