var myvmc = false;
store.registerModule("exam", {
  namespaced: true,
  state() {
    return {
      active: 0,
      afktimeout: 0,
      maxCheatCount: 0,
      soal_generated: null,
      cheatCount: 0,
      minFinishTime: 0,
      strict: false,
      loading: false,
      grettingModalTitle: 'Ujian Dimulai',
      grettingModalBody: 'Selamat Mengerjakan',
      notFound: false,
      hasCheat: false,
      listenResize: false,
      strictCount: 0,
      ready: false,
      tinyOn: false,
      shortEntryOn: false,
      textAreaOn: false,
      nowUnix: mm().unix(),
      data: [],
      soalAnswered: [],
      errMsg: "",
      warnMsg: "",
      envc: "production",
      timeoutSplitScreen: null,
    };
  },
  actions: {
    tinyClick({ commit, state }, params = {}) {
      commit('tinyOn', params.state || true);
    },
    shortEntryClick({ commit, state }, params = {}) {
      commit('shortEntryOn', params.state || true);
    },
    textAreaClick({ commit, state }, params = {}) {
      commit('textAreaOn', params.state || true);
    },
  },
  mutations: {
    grettingModalTitle(state, n) {
      state.grettingModalTitle = n;
    },
    grettingModalBody(state, n) {
      state.grettingModalBody = n;
    },
    active(state, n) {
      state.active = n;
    },
    notFound(state, n) {
      state.notFound = n;
    },
    tinyOn(state, n) {
      state.tinyOn = n;
    },
    shortEntryOn(state, n) {
      state.shortEntryOn = n;
    },
    textAreaOn(state, n) {
      state.textAreaOn = n;
    },
    strictCount(state, n) {
      state.strictCount = n;
    },
    maxCheatCount(state, n) {
      state.maxCheatCount = n;
    },
    cheatCount(state, n) {
      window.localStorage.setItem(window.location.href + "/cc", n);
      state.cheatCount = n;
    },
    data(state, n) {
      state.data = n;
    },
    nowUnix(state, n) {
      state.nowUnix = n;
    },
    soalAnswered(state, n) {
      state.soalAnswered = n;
    },
    errMsg(state, n) {
      state.errMsg = n;
    },
    warnMsg(state, n) {
      state.warnMsg = n;
    },
    envc(state, n) {
      state.envc = n;
    },
    strict(state, n) {
      state.strict = n;
    },
    listenResize(state, n) {
      state.listenResize = n;
    },
    afktimeout(state, n) {
      state.afktimeout = n;
    },
    minFinishTime(state, n) {
      state.minFinishTime = n;
    },
    hasCheat(state, n) {
      state.hasCheat = n;
    },
    ready(state, n) {
      state.ready = n;
    },
    loading(state, n = null) {
      if (n != null) {
        return (state.loading = n);
      }
      state.loading = !state.loading;
    },
  },
});
VAPP.mixin({
  data() {
    return {
      finished: false,
      grettingModal: {
        title: "Ujian Dimulai",
        body: "Selamat Mengerjakan",
      },
      wakeLock: {
        supported: false,
        instance: null,
      },
      webtitle: { ori: "", fake: "" },
      afk: {
        timer: null,
        counter: null,
        timeParsed: "",
      },
      splitScreenListen: { state: false, active: false, timeout: null },
      localConfig: {
        expiredAt: null,
        cache_soal: false,
        ready: false,
      },
    };
  },
  mounted() {
    this.loadConfig();
    if (!myvmc) return myvmc = !myvmc;
    this.loadSoalAnswered();
    setInterval(this.loadSoalAnswered, 1000 * 60 * 10);
    document.querySelector("body").onkeydown = this.cheatDetector;
    this.fullscreenListener();
    document.addEventListener("visibilitychange", () => {
      if (!this.afk.timer && document.visibilityState == "hidden") {
        this.AFKListener(true);
      } else if (this.afk.timer && document.visibilityState == "visible") {
        if (!this.$store.state.exam.strict) this.AFKListener(false);
        if (this.$store.state.exam.strict && document.fullscreenElement)
          this.AFKListener(false);
      }
    });
    window.addEventListener('resize', () => {
      if (this.splitScreenListen.state) this.executeSplitScreen();
      this.splitScreenListen.state = false;
      if (this.splitScreenListen.timeout) return;
      this.splitScreenListen.timeout = setTimeout(() => {
        this.splitScreenListen.state = true;
        this.splitScreenListen.timeout = null;
      }, 1000);
    }, true);

    document.addEventListener("contextmenu", (event) =>
      this.$store.state.exam.envc != "development"
        ? event.preventDefault()
        : null
    );
    setInterval(() => this.$store.commit("exam/nowUnix", mm().unix()), 100);
  },
  methods: {
    checkSplitScreen() {
      let screenHeigth = window.screen.height;
      let screenWidth = window.screen.width;
      let rasionalHeight = screenHeigth * 0.7;
      let rasionalWidth = screenWidth * 0.7;
      if (window.innerHeight < rasionalHeight || window.innerWidth < rasionalWidth) {
        this.$store.commit('exam/grettingModalTitle', "Peringatan!");
        this.$store.commit('exam/grettingModalBody', `Split screen terdeteksi!`);
        this.$store.commit('exam/hasCheat', true);
      }
    },
    turnOnWakeLock() {
      if (this.wakeLock.supported) return;
      if ("wakeLock" in navigator) this.wakeLock.supported = true;
      else return console.log("Wake lock is not supported by this browser.")
      try {
        navigator.wakeLock.request('screen').then(v => {
          this.wakeLock.instance = v;
          console.log("Wake Lock Active");
        });
      } catch (err) {
        // The Wake Lock request has failed - usually system related, such as battery.
        console.log(err.name, err.message);
      }
    },
    turnOffWakeLock() {
      if (!this.wakeLock.supported) return;
      if (!this.wakeLock.instance) return;
      this.wakeLock.instance.release().then(() => {
        this.wakeLock.instance = null;
      });
    },
    // Fungsi untuk mendeteksi apakah pengguna menggunakan perangkat Android
    isAndroid() {
      // Periksa apakah string navigator.userAgent mengandung "Android"
      return navigator.userAgent.indexOf("Android") !== -1;
    },
    // Fungsi untuk mendeteksi apakah pengguna menggunakan perangkat iOS
    isiOS() {
      // Periksa apakah string navigator.userAgent mengandung "iPhone" atau "iPad" atau "iPod"
      return /iPhone|iPad|iPod/i.test(navigator.userAgent);
    },
    executeSplitScreen() {
      if (this.$store.state.exam.tinyOn) return;
      if (this.$store.state.exam.textAreaOn) return;
      if (this.$store.state.exam.shortEntryOn) return;
      this.$store.commit('exam/listenResize', true);
      if (!this.$store.state.exam.strict || !this.$store.state.exam.listenResize) return;
      this.$store.commit('exam/listenResize', false)
      if (this.$store.state.exam.maxCheatCount <= 0) return;

      let screenHeigth = window.screen.height;
      let screenWidth = window.screen.width;
      let rasionalHeight = screenHeigth * 0.7;
      let rasionalWidth = screenWidth * 0.7;
      if (window.innerHeight > rasionalHeight && window.innerWidth > rasionalWidth) return;
      if (this.timeoutSplitScreen) clearTimeout(this.timeoutSplitScreen);
      if (this.$store.state.exam.cheatCount < this.$store.state.exam.maxCheatCount) {
        this.timeoutSplitScreen = setTimeout(() => {
          this.timeoutSplitScreen = null;
          this.executeSplitScreen();
        }, 1000 * 5);
      }

      let mdl = document.getElementById("grettingModal");

      this.$store.commit('exam/cheatCount', this.$store.state.exam.cheatCount + 1);
      this.$store.commit('exam/grettingModalTitle', "Peringatan!");
      if (this.$store.state.exam.maxCheatCount > 0) {
        this.$store.commit('exam/grettingModalBody', `Anda telah melakukan pelanggaran ${this.$store.state.exam.cheatCount}  kali, lebih dari ${this.$store.state.exam.maxCheatCount} akan dikeluarkan`);
      } else {
        this.$store.commit('exam/grettingModalBody', `Perbuatan curang terdeteksi, sudah tercatat di sistem`);
      }
      if (!mdl.classList.contains("show")) new bootstrap.Modal(mdl).show();

      if (this.$store.state.exam.cheatCount < this.$store.state.exam.maxCheatCount) return;
      axios({
        method: "PUT",
        data: { [this.$store.state.config.csrf.name]: this.$store.state.config.csrf.value, cc: this.$store.state.exam.cheatCount },
        url: window.location.href + "/hc",
      }).then((response) => {
        alert(`Anda telah melakukan pelanggaran lebih dari ${this.$store.state.exam.maxCheatCount} dan akan dikeluarkan`);
        window.location.href = window.location.href + "/finish?hc=a";
      },
        (error) => {
          window.location.href = window.location.href + "/finish?hc=a";
          return setTimeout(() => this.executeSplitScreen(), Math.floor(Math.random() * 5000));
        }
      );
    },
    fullscreenListener() {

      let mdl = document.getElementById("grettingModal");
      mdl.addEventListener("hide.bs.modal", (e) => {
        try {
          if (document.visibilityState == "visible") this.AFKListener(false);
          document.getElementsByClassName("modal-backdrop")[0].remove();
          setTimeout(() => {
            document.body.style.overflow = null;
            document.body.style.paddingRight = null;
          }, 200);
        } catch (error) { }
      });
      // document.addEventListener("fullscreenchange", ()=> { 

      //   if(!noBrowserFullscreen()&&this.$store.state.exam.strict)return;
      //   this.grettingModal.title = "Peringatan!";
      //   if(this.$store.state.exam.maxCheatCount>0){
      //     this.$store.commit("exam/cheatCount", this.$store.state.exam.cheatCount+1);
      //     this.grettingModal.body = `Anda telah melakukan pelanggaran ${this.$store.state.exam.cheatCount}  kali, lebih dari ${this.$store.state.exam.maxCheatCount} akan dikeluarkan`;
      //   }else{
      //     this.grettingModal.body = `Perbuatan curang terdeteksi, sudah tercatat di sistem`;
      //   }
      //   if(!mdl.classList.contains("show"))new bootstrap.Modal(mdl).show();
      //   if (!this.afk.timer) this.AFKListener(true);
      //   this.$store.commit('exam/listenResize',false)
      //   setTimeout(()=>this.$store.commit('exam/listenResize',true),300);
      // });
      //   document.addEventListener("fullscreenchange", (event) => {

      //     if (!document.fullscreenElement && this.$store.state.exam.strict) {
      //       this.grettingModal.title = "Peringatan!";
      //       if(this.$store.state.exam.maxCheatCount>0){
      //         this.$store.commit("exam/cheatCount", this.$store.state.exam.cheatCount+1);
      //         this.grettingModal.body = `Anda telah melakukan pelanggaran ${this.$store.state.exam.cheatCount} kali, lebih dari ${this.$store.state.exam.maxCheatCount} akan dikeluarkan`;
      //       }else{
      //         this.grettingModal.body = `Perbuatan curang terdeteksi, sudah tercatat di sistem`;
      //       }
      //       if(!mdl.classList.contains("show"))new bootstrap.Modal(mdl).show();
      //       if (!this.afk.timer) this.AFKListener(true);
      //     }
      //     this.$store.commit('exam/listenResize',false)
      //     setTimeout(()=>this.$store.commit('exam/listenResize',true),300);
      //   });
    },
    /* View in fullscreen */
    openFullscreen() {
      if (!window.navigator.userAgent.includes("CandyCBTBro")) { openFullscreen(); }
    },
    /* Close fullscreen */
    closeFullscreen() {
      this.$store.commit('exam/listenResize', false);
      if (document.exitFullscreen) {
        console.log('exitfulscreen');
        document.exitFullscreen();
      } else if (document.webkitExitFullscreen) {
        /* Safari */
        document.webkitExitFullscreen();
      } else if (document.msExitFullscreen) {
        /* IE11 */
        document.msExitFullscreen();
      }
    },
    noBrowserFullscreen() {
      return !document.fullscreenElement &&
        !document.webkitIsFullScreen &&
        !document.mozFullScreen &&
        !document.msFullscreenElement
    },
    AFKListener(state = false) {
      if (this.$store.state.exam.afktimeout <= 0) return;
      if (this.afk.timer != null && !state) {
        let t = this.$store.state.exam.afktimeout;
        let ti = parseTimeToString(secondsToTime(t, true));
        let h = t - this.afk.counter;
        let hi = parseTimeToString(secondsToTime(h == 0 ? 1 : h, true));
        this.$store.state.exam.errMsg = `Peringatan! Terdeteksi meninggalkan ujian selama ${hi.replace(/\s+/g, "") === "" ? (h == 0 ? 1 : h) + " Detik" : hi
          }. Anda dikeluarkan jika melebihi ${ti.replace(/\s+/g, "") === "" ? t + " Detik" : ti
          }`;
        clearInterval(this.afk.timer);
        this.afk.timer = null;
        this.afk.counter = null;
        this.afk.timeParsed = null;
        document.title = this.webtitle.ori;
      } else if (this.$store.state.exam.envc != "development" && state) {
        this.afk.counter = this.$store.state.exam.afktimeout;
        let hi = parseTimeToString(secondsToTime(this.afk.counter, true));
        this.afk.timeParsed =
          hi.replace(/\s+/g, "") === "" ? this.afk.counter + " Detik" : hi;
        document.title = `Kembali! ${this.afk.timeParsed}`;
        this.afk.timer = setInterval(() => {
          if (this.afk.counter == 0) {
            if (document.title != "Meniggalkan Ujian!") {
              document.title = "Meniggalkan Ujian!";
              this.logout();
            }
            return;
          }
          if (document.visibilityState == 'visible') {
            this.AFKListener(false);
            return;
          }
          let hi = parseTimeToString(secondsToTime(this.afk.counter--, true));
          this.afk.timeParsed =
            hi.replace(/\s+/g, "") === "" ? this.afk.counter + " Detik" : hi;
          document.title = `Kembali! ${this.afk.timeParsed}`;
        }, 1000);
      }
    },
    logout() {
      axios({
        method: "GET",
        url: this.$store.state.config.base_url + "/logout",
      }).then(
        (response) => {
          window.location.href = this.$store.state.config.base_url + "/logout";
        },
        (error) => { }
      );
    },
    prevSoal() {
      // this.soalData[this.soalActive-1].jenis_soal==2?this.soalData[this.soalActive-1].esai=null:'';
      this.soalActive--;
    },
    nextSoal() {
      document.activeElement.blur();
      // this.soalData[this.soalActive-1].jenis_soal==2?this.soalData[this.soalActive-1].esai=null:'';
      this.soalActive++;
    },
    cheatDetector(e) {
      if (e.key == "F12" && this.$store.state.exam.envc != "development") {
        e.preventDefault();
        this.$store.commit("exam/cheatCount", this.$store.state.exam.cheatCount + 1);
        this.$store.commit("exam/hasCheat", true);
        return;
      }

      switch (e.key) {
        case "ArrowLeft":
          //arrow right for prev
          let prev = document.getElementById("prev-soal");
          if (prev) {
            e.preventDefault();
            prev.click();
          }
          break;
        case "ArrowRight":
          //arrow right for next
          let next = document.getElementById("next-soal");
          if (next) {
            e.preventDefault();
            next.click();
          }
          break;
      }
      switch (e.code) {
        case "KeyA":
          //option A
          let opsiA = document.getElementById("opsi-0");
          if (opsiA) {
            e.preventDefault();
            opsiA.click();
          }
          break;
        case "KeyB":
          //option B
          let opsiB = document.getElementById("opsi-1");
          if (opsiB) {
            e.preventDefault();
            opsiB.click();
          }
          break;
        case "KeyC":
          //option C
          let opsiC = document.getElementById("opsi-2");
          if (opsiC) {
            e.preventDefault();
            opsiC.click();
          }
          break;
        case "KeyD":
          //option D
          let opsiD = document.getElementById("opsi-3");
          if (opsiD) {
            e.preventDefault();
            opsiD.click();
          }
          break;
        case "KeyE":
          //option E
          let opsiE = document.getElementById("opsi-4");
          if (opsiE) {
            e.preventDefault();
            opsiE.click();
          }
          break;
      }
      if (e.ctrlKey && e.key == "KeyL") {
        //ctrl + l for daftar soal
        let ls = document.getElementById("list-soal");
        if (ls) {
          e.preventDefault();
          ls.click();
        }
      }
      if (e.ctrlKey && e.key == "KeyI") {
        e.preventDefault();
        //ctrl + i for shortcut info
        document.getElementById("show-shortcut").click();
      }
      if (e.ctrlKey && e.key == "KeyF") {
        //ctrl + f for finish exam
        let ls = document.getElementById("finish-soal");
        if (ls) {
          e.preventDefault();
          ls.click();
        }
      }
    },
    loadConfig() {
      axios({
        method: "get",
        url: window.location.href + "/config",
      }).then(
        (response) => {
          if (!isObject(response.data))
            return setTimeout(this.loadConfig, 1000);
          setInterval(this.timeOut, 1);
          if (this.$store.state.exam.strictCount == 0 && response.data.strict)
            new bootstrap.Modal(
              document.getElementById("grettingModal")
            ).show();
          this.$store.commit(
            "exam/strictCount",
            this.$store.state.exam.strictCount + 1
          );
          if (response.data.strict) this.checkSplitScreen();
          let soalTime = localStorage.getItem(window.location.href + "/soal-time/" + i);
          if (soalTime != response.data.soal_generated && soalTime != null) {
            for (let i = 1; i <= response.data.total_soal; i++) {
              localStorage.removeItem(window.location.href + "/soal/" + i);
            }
            localStorage.removeItem(window.location.href + "/cc");
            localStorage.setItem(window.location.href + "/soal/active", 1);
          }
          let cheatCount = parseInt(localStorage.getItem(window.location.href + "/cc") || '0');
          let maxCheatCount = parseInt(response.data.maxCheatCount);
          if (maxCheatCount <= 0) cheatCount = 0;
          else if (cheatCount > maxCheatCount) cheatCount = 0;
          localStorage.setItem(window.location.href + "/cc", cheatCount);
          localStorage.setItem(window.location.href + "/soal-time/" + i, response.data.soal_generated);
          this.$store.commit("config/timezone", response.data.timezone);
          this.$store.commit("exam/envc", response.data.environment);
          this.$store.commit("exam/strict", response.data.strict);
          this.$store.commit("exam/afktimeout", response.data.afktimeout);
          this.$store.commit("exam/maxCheatCount", maxCheatCount);
          this.$store.commit("exam/minFinishTime", (response.data.minFinishTime || 0) * 60);
          this.$store.commit("exam/cheatCount", cheatCount);
          this.$store.commit("exam/ready", true);
          this.localConfig = response.data;
          this.localConfig.ready = true;
          this.webtitle.ori = "Ujian " + response.data.nama_mapel;
          document.title = this.webtitle.ori;
          let soalData = [];
          for (let index = 0; index < response.data.total_soal; index++) {
            let d = null;
            if (this.localConfig.cache_soal) {
              d = localStorage.getItem(
                window.location.href + "/soal/" + (index + 1)
              );
              if (d) {
                d = JSON.parse(d);
                // d.sync = true;
              }
            } else {
              localStorage.removeItem(
                window.location.href + "/soal/" + (index + 1)
              );
            }
            soalData.push(d);
          }
          if (this.soalActive == 0) {
            this.soalActive =
              localStorage.getItem(window.location.href + "/soal/active") || 1;
            this.soalData = soalData;
          }
        },
        (error) => { }
      );
    },
    loadSoalAnswered() {
      axios({
        method: "get",
        url: window.location.href + "/soal-answered",
      }).then(
        (response) => {
          if (!isObject(response.data))
            return setTimeout(this.loadSoalAnswered, 1000);
          this.$store.commit("exam/soalAnswered", response.data.soal_answered);
        },
        (error) => { }
      );
    },
    isSoalTerjawab(index) {
      let soal = null;
      try {
        soal = this.soalData[index - 1];
      } catch (error) {
        return false;
      }
      let jawaban = false;
      if (soal) {
        switch (parseInt(soal.jenis_soal)) {
          case 1:
            jawaban = soal.opsi_id;
            break;
          case 2:
            jawaban = soal.esai;
            break;
          case 3:
            jawaban = soal.opsi_id;
            break;
          case 4:
            jawaban = soal.opsi_id;
            break;
          case 5:
            jawaban = soal.respond;
            break;
          case 6:
            jawaban = soal.opsi_id;
            break;
        }
      }
      if (!jawaban && soal) {
        let j = false;
        for (let [jk, jv] in Object.entries(
          this.$store.state.exam.soalAnswered
        )) {
          if (j) break;
          if (jk == soal.soal_id) j = jv;
        }
        if (!j) return false;
        return parseInt(j) == 1;
      }
      if (jawaban === false) return false;
      if (jawaban === null) return false;
      if (jawaban == "0") return true;
      return jawaban;
    },
    timeOut() {
      this.localConfig.expiredAt = "";
      if (this.localConfig.status != '1') return;
      let timestart = moment().unix() - this.localConfig.startDateTime;
      let timeend = moment().unix() - this.localConfig.end_at;
      if (timeend > 0 && timestart > 0) {
        if (this.localConfig.status == '1') {
          this.localConfig.status = 2;
        }
        this.localConfig.expiredAt = "";
        if (this.$store.state.exam.ready) this.finish();
        return this.$store.commit("exam/warnMsg", "");
      } else if (timestart < 0) {
        if (this.$store.state.exam.ready) this.finish();
        return this.$store.commit("exam/warnMsg", "");
      }
      let time = secondsToTime(-timeend);
      if (time.m < 10 && !time.h) {
        this.$store.commit(
          "exam/warnMsg",
          "Ujian Segera Berakhir, Segera Simpan Jawaban!"
        );
      }
      time = `${parseTimeToString(time)} `;
      this.localConfig.expiredAt = time;
    },
    finish() {
      for (let i = 0; i < this.jumlahSoal; i++) {
        localStorage.removeItem(window.location.href + "/soal/" + i);
      }
      if (this.finished) return;
      this.finished = true;
      document.title = "Ujian Selesai";
      this.turnOffWakeLock();
      window.location.href = window.location.href + "/finish";
    },
  },
  computed: {
    canFinishNow() {
      let state = {
        state: true,
        mm: mm()
      }
      if (this.$store.state.exam.minFinishTime <= 0) return state;
      if (this.localConfig.endDateTime <= this.$store.state.nowUnix) return state;
      state.mm = mm({ unix: parseInt(this.$store.state.exam.minFinishTime) + parseInt(this.localConfig.start_at) });
      if (this.$store.state.exam.nowUnix >= state.mm.unix()) return state;
      state.state = false;
      return state;
    },
    semuaSoalTerjawab() {
      let data = {
        state: true,
        index: 0,
        notsync: false,
      };
      this.soalData.forEach((elem, i) => {
        let issync = true;
        try {
          issync = elem.sync;
        } catch (error) {

        }
        if (issync === false) {
          if (data.index == 0) {
            data.index = i;
          }
          data.notsync = true;
          data.state = false;
          return;
        }
        if (!this.isSoalTerjawab(i + 1)) {
          if (data.index == 0) {
            data.index = i;
          }
          data.state = false;
          return;
        }
      });
      return data;
    },
    jumlahSoal() {
      return this.$store.state.exam.data.length;
    },
    soalData: {
      get() {
        return this.$store.state.exam.data;
      },
      set(v) {
        this.$store.commit("exam/data", v);
      },
    },
    soalActive: {
      get() {
        return this.$store.state.exam.active;
      },
      set(i) {
        this.$store.commit("exam/active", i);
      },
    },
  },
});
var VPujian = (function () {
  vp_template = `
    <div style="transform: none !important" class="page-content-wrapper py-3">
      <div v-if="$store.state.exam.hasCheat" class="alert custom-alert-2 alert-danger alert-dismissible fade show" role="alert"><i class="bi bi-info-circle"></i>
        <span>Perbuatan curang terdeteksi!</span>
        <button class="btn btn-close btn-close-white position-relative p-1 ms-auto" type="button" data-bs-dismiss="alert" aria-label="Close"></button>
      </div>
      <div v-else>
        <div class="container">
          <div v-show="!internetState&&$store.state.config.is_https" class="alert custom-alert-2 alert-danger alert-dismissible fade show" role="alert"><i class="bi bi-info-circle"></i>
            <span>Koneksi Tidak Tersedia, Periksa Internet Anda Sebelum Menjawab</span>
            <button class="btn btn-close btn-close-white position-relative p-1 ms-auto" type="button" data-bs-dismiss="alert" aria-label="Close"></button>
          </div>
          <div v-show="$store.state.exam.warnMsg" class="alert custom-alert-2 alert-warning alert-dismissible fade show" role="alert"><i class="bi bi-info-circle"></i>
            <span>{{$store.state.exam.warnMsg}}</span>
            <button class="btn btn-close btn-close-white position-relative p-1 ms-auto" type="button" data-bs-dismiss="alert" aria-label="Close"></button>
          </div>
          <div v-show="lastServerError" class="alert custom-alert-2 alert-danger alert-dismissible fade show" role="alert"><i class="bi bi-info-circle"></i>
            <span>Jaringan tidak stabil, silahkan lanjutkan mengerjakan ujian</span>
            <button class="btn btn-close btn-close-white position-relative p-1 ms-auto" type="button" data-bs-dismiss="alert" aria-label="Close"></button>
          </div>
        </div>
        <div class="container" v-if="soalData[soalActive-1]&&!$store.state.exam.loading">
          <div class="card mt-2">
            <div class="card-body p-3">
              <div class="row m-0">
                <div class="col-4">
                  <a class="btn btn-sm m-1 btn-round btn-outline-info " href="javascript:void(0)">No. {{soalActive}}</a>
                </div>
                <div class="col-8 text-end">
                <button type="button" title="Kecilkan Font" @click="changeFont('-')" class="btn btn-sm m-1 btn-round btn-outline-info unselectable">A-</button>
                <button type="button" title="Reset Font" @click="changeFont('=')" class="btn btn-sm m-1 btn-round btn-outline-info unselectable"><i class="fas fa-sync"></i></button>
                <button type="button" title="Besarkan Font" @click="changeFont('+')" class="btn btn-sm m-1 btn-round btn-outline-info unselectable">A+</button>
                </div>
              </div>
              <div class="divider divider-dashed border-light mt-1"></div>
  
              <div v-if="!soalData[soalActive-1].sync&&!internetState" class="alert custom-alert-2 alert-warning alert-dismissible show" role="alert"><i class="bi bi-info-circle"></i>
                <span>Jawaban Akan Disimpan Saat Koneksi Tersedia</span>
                <button class="btn btn-close btn-close-white position-relative p-1 ms-auto" type="button" data-bs-dismiss="alert" aria-label="Close"></button>
              </div>
  
              <div v-if="$store.state.exam.errMsg" class="alert custom-alert-2 alert-danger alert-dismissible fade show" role="alert"><i class="bi bi-info-circle"></i>
                <span>{{$store.state.exam.errMsg}}</span>
                <button class="btn btn-close btn-close-white position-relative p-1 ms-auto" type="button" data-bs-dismiss="alert" aria-label="Close"></button>
              </div>
              <div class="unselectable" v-html="soalData[soalActive-1].question">
              </div>
            </div>
          </div>
          <template v-if="soalData[soalActive-1].jenis_soal==1">
            <div class="card mt-2" v-for="(opsi,i) in soalData[soalActive-1].opsi" @click="pgcommon(opsi.id)" >
              <div class="card-body p-3">
                <div class="form-check unselectable">
                  <input class="form-check-input form-check-success" :id="'opsi-'+i" type="radio" :checked="soalData[soalActive-1].opsi_id==opsi.id" :name="opsi.soal_id">
                  <label class="form-check-label" v-html="opsi.body"></label>
                </div>
              </div>
            </div>
          </template>
          <template v-else-if="soalData[soalActive-1].jenis_soal==2">
            <div class="card mt-2">
              <div class="card-body p-3">
                <div class="form-group">
                  <label class="form-label">Masukan Jawaban</label>
                  <editor :tinymceScriptSrc="$store.state.config.base_url+'/vendors/tinymce/js/tinymce/tinymce.min.js'" @blur="addSaveQueue(soalActive),$store.dispatch('exam/tinyClick',{state:true})" @focus="$store.dispatch('exam/tinyClick',{state:false})" v-model="soalData[soalActive-1].esai" :init="tinymce" />
                </div>
              </div>
            </div>
          </template>
          <template v-else-if="soalData[soalActive-1].jenis_soal==5"><div class="card mt-2">
            <div v-if="!soalData[soalActive-1].custom_respond" class="card-body p-3">
                <div class="form-group">
                <label class="form-label">Masukan Jawaban</label>
                <textarea @focus="$store.dispatch('exam/textAreaClick',{state:false})" @blur="$store.dispatch('exam/textAreaClick',{state:true})"  class="form-control form-control-clicked" @change="addSaveQueue(soalActive)" v-model="soalData[soalActive-1].respond"  cols="3" rows="5" placeholder="Masukan Jawaban"></textarea>
                </div>
            </div>
            </div>
          </template>
          <template v-else-if="soalData[soalActive-1].jenis_soal==4">
                <div class="row mt-2">

                    <div class="col-6">
                        <template v-for="(question,i) in coupleQuestions">
                            <div v-if="option_selected" @click="coupleQuestionSelected(i)" :class="(question.coupled?'bg-'+question.color+' text-white':'')" class="card my-2 blink_me">
                                <div class="card-body p-3">
                                    <div class="questions-body unselectable" v-html="question.body">
                                    </div>
                                </div>
                            </div>
                            <div v-else-if="question_selected==question.id" @click="question_selected=null" :class="(question.coupled?'bg-'+question.color+' text-white':'')" class="card my-2 blink_me">
                                <div class="card-body p-3">
                                    <div class="questions-body unselectable" v-html="question.body">
                                    </div>
                                </div>
                            </div>
                            <div v-else @click="question_selected=question.id" :class="(question.coupled?'bg-'+question.color+' text-white':'')" class="card my-2">
                                <div class="card-body p-3">
                                    <div class="questions-body unselectable" v-html="question.body">
                                    </div>
                                </div>
                            </div>
                        </template>
                    </div>

                    <div class="col-6">
                        <template v-for="(option,i) in coupleOptions">
                            <div v-if="question_selected&&question_selected!=option.soal_couple_id"
                            @click="coupleOptionSelected(i)" :class="(option.coupled?'bg-'+option.color+' text-white':'')" class="card my-2 blink_me">
                                <div class="card-body p-3">
                                    <div class="options-body unselectable" v-html="option.body">
                                    </div>
                                </div>
                            </div>
                            <div v-else-if="(!question_selected&&option.soal_couple_id)||(question_selected&&question_selected==option.soal_couple_id)"
                            @click="releaseCoupleOption(i)" :class="(option.coupled?'bg-'+option.color+' text-white':'')" class="card my-2">
                                <div class="card-body p-3">
                                    <div class="options-body unselectable" v-html="option.body">
                                    </div>
                                </div>
                            </div>
                            <div v-else @click="option_selected=option_selected==option.id?null:option.id" :class="(option.coupled?'bg-'+option.color+' text-white':'')" class="card my-2">
                                <div class="card-body p-3">
                                    <div class="options-body unselectable" v-html="option.body">
                                    </div>
                                </div>
                            </div>
                        </template>
                    </div>

                </div>

          </template>
          <template v-else-if="soalData[soalActive-1].jenis_soal==3">
  
            <div class="card mt-2" v-for="(opsi,i) in soalData[soalActive-1].opsi" @click="pgmultiselected(i)">
              <div class="card-body p-3">
                <div class="form-check unselectable">
                  <input class="form-check-input form-check-success" :id="'opsi-'+i" :name="opsi.soal_id" :checked="(soalData[soalActive-1].opsi_id||'').split(',').includes(opsi.id)" type="checkbox" value="">
                  <label class="form-check-label"  v-html="opsi.body">
                  </label>
                </div>
              </div>
            </div>
  
          </template>
          <template v-else-if="soalData[soalActive-1].jenis_soal==6">
          <div class="card mt-2" v-for="(opsi,i) in soalData[soalActive-1].opsi" >
            <div class="card-body p-3">
              <div class="form-check unselectable">
                  <div class="d-none d-sm-block">
                      <div class="row">
                          <div class="col-md-8">
                              <div v-html="opsi.body">
                              </div>
                          </div>
                          <div class="col-md-4">
                              <div class="d-flex justify-content-evenly">
                                  <div class="">
                                      <input title="Benar" class="form-check-input form-check-success bg-success" :id="opsi.id+'mdt'+i" :name="'opsi-mdtf-'+opsi.id+''+i" @click="pgtfselected(1,i)" :checked="(soalData[soalActive-1].opsi_id||'').split(',').includes(opsi.id+'-1')==true" type="radio">
                                      <label :for="opsi.id+'mdt'+i" class="form-check-label">
                                          Benar
                                      </label>
                                  </div>
                                  <div class="">
                                      <input title="Salah" class="form-check-input form-check-success bg-danger" :id="opsi.id+'mdf'+i" :name="'opsi-mdtf-'+opsi.id+''+i" @click="pgtfselected(0,i)" :checked="(soalData[soalActive-1].opsi_id||'').split(',').includes(opsi.id+'-0')==true" type="radio">
                                      <label :for="opsi.id+'mdf'+i" class="form-check-label">
                                          Salah
                                      </label>
                                  </div>
                              </div>
                          </div>
                      </div>    
                  </div>
                  <div class="d-block d-sm-none">
                      <div v-html="opsi.body">
                      </div>
                      <div class="d-flex justify-content-evenly">
                          <div class="">
                              <input title="Benar" class="form-check-input form-check-success bg-success" :id="opsi.id+'xst'+i" :name="'opsi-xstf-'+opsi.id+''+i" @click="pgtfselected(1,i)" :checked="(soalData[soalActive-1].opsi_id||'').split(',').includes(opsi.id+'-1')" type="radio">
                              <label :for="opsi.id+'xst'+i" class="form-check-label">
                                  Benar
                              </label>
                          </div>
                          <div class="">
                              <input title="Salah" class="form-check-input form-check-success bg-danger" :id="opsi.id+'xsf'+i" :name="'opsi-xstf-'+opsi.id+''+i" @click="pgtfselected(0,i)" :checked="(soalData[soalActive-1].opsi_id||'').split(',').includes(opsi.id+'-0')" type="radio">
                              <label :for="opsi.id+'xsf'+i" class="form-check-label">
                                  Salah
                              </label>
                          </div>
                      </div>
                  </div>

              </div>
            </div>
          </div>

        </template>
  
        </div>

        <div class="container text-center" v-else-if="$store.state.exam.notFound">
            <div class="alert custom-alert-2 alert-danger alert-dismissible fade show" role="alert"><i class="bi bi-info-circle"></i>
                <span>Soal tidak ditemukan!</span>
                <button class="btn btn-close btn-close-white position-relative p-1 ms-auto" type="button" data-bs-dismiss="alert" aria-label="Close"></button>
            </div>
        </div>
        <div class="container text-center" v-else-if="$store.state.exam.errMsg">
            <div class="alert custom-alert-2 alert-danger alert-dismissible fade show" role="alert"><i class="bi bi-info-circle"></i>
                <span>{{$store.state.exam.errMsg}}</span>
                <button class="btn btn-close btn-close-white position-relative p-1 ms-auto" type="button" data-bs-dismiss="alert" aria-label="Close"></button>
            </div>
        </div>
        <div class="container text-center" v-else>
          <div class="spinner-grow text-primary" role="status"><span class="visually-hidden">Loading...</span></div>
        </div>
      </div>
  
    </div>`;
  return {
    name: "ujian",
    template: vp_template,

    data() {
      return {
        cancelToken: axios.CancelToken,
        source: null,
        fontCustom: 14,
        axiosToken: {
          save: [],
        },
        amplifyImageTimeout: null,
        question_selected: null,
        option_selected: null,
        requesting: 0,
        internetState: true,
        tinymce: {
          statusbar: false,
          menubar: false,
          branding: false,
          images_upload_handler: this.images_upload_handler,
          plugins: ["image paste"],
          content_style: "img {max-width: 200px;}",
          toolbar: "bold italic numlist bullist emoticons image",
        },
        lastServerError: 0,
      };
    },
    mounted() {
      this.source = this.cancelToken.source();
      window.addEventListener("online", this.onlineStatus);
      window.addEventListener("offline", this.onlineStatus);
      setInterval(this.queueSaveSoal, 2000);
      this.shortEntryListener();
    },
    watch: {
      soalActive(i) {
        this.destroyAmplifyImage();
        this.option_selected = null;
        this.question_selected = null;
        localStorage.setItem(window.location.href + "/soal/active", i);
        this.$store.commit("exam/errMsg", "");
        if (!this.localConfig.ready) return;
        let ts = 0;
        this.soalData.forEach((el) => (el ? ts++ : ""));
        if (this.localConfig.cache_soal) {
          if (ts < this.localConfig.total_soal) return this.loadSoals();
        }
        this.loadSoal();
        if (this.amplifyImageTimeout) clearTimeout(this.amplifyImageTimeout);
        this.amplifyImageTimeout = setTimeout(this.amplifyImage, 100);
      },
      localConfig(v) {
        if (v.cache_soal && !this.isSoalAvailableLocalStorage()) {
          this.loadSoals();
        }
      },
      internetState(v) {
        if (v) this.queueSaveSoal();
      },
    },
    methods: {
      destroyAmplifyImage() {
        let images = document.querySelectorAll('img');
        if (images.length == 0) return;
        for (let i = 0; i < images.length; i++) {
          let image = images[i];
          $(image).trigger('zoom.destroy');
        }
      },
      amplifyImage() {
        let images = document.querySelectorAll('img');
        if (images.length == 0) return;
        for (let i = 0; i < images.length; i++) {
          let image = images[i];
          let parent = image.parentNode;
          let wrapper = document.createElement('div');
          wrapper.classList.add('zoom');
          parent.replaceChild(wrapper, image);
          wrapper.appendChild(image);
          $(wrapper).zoom({ on: 'click' });
        }
        this.amplifyImageTimeout = null;
      },
      changeFont(key) {
        if (key == '-') this.fontCustom--;
        else if (key == '+') this.fontCustom++;
        else this.fontCustom = 14;
        let p = document.getElementsByTagName('p');
        for (let i = 0; i < p.length; i++) {
          const el = p[i];
          el.style.fontSize = this.fontCustom + "px";
        }
      },
      trimdot(str) {
        let result = "";
        str = str.trim();
        let skip = true;
        for (let i = 0; i < str.length; i++) {
          let chr = str.charAt(i);
          if (skip && chr == ".") continue;
          skip = false;
          result += chr;
        }
        return result;
      },
      shortEntryListener() {
        document.addEventListener("focusin", (e) => {
          if (e.target && e.target.classList.contains("shortentry-respond") && !this.$store.state.exam.shortEntryOn) {
            this.$store.dispatch('exam/shortEntryClick', { state: false });
            if (e.target.innerHTML == ".....") {
              setTimeout(() => {
                e.target.blur();
              }, 50);
              setTimeout(() => {
                e.target.innerHTML = "";
                e.target.focus();
              }, 60);
            }
          }
        });
        document.addEventListener("focusout", (e) => {
          if (e.target && e.target.classList.contains("shortentry-respond")) {
            this.$store.dispatch('exam/shortEntryClick', { state: true });
            let ser = document.getElementsByClassName("shortentry-respond");
            let serv = [];
            for (let i = 0; i < ser.length; i++) {
              let v = "";
              try {
                v = ser[i].innerHTML;
                v = v || "";
                v = v.replaceAll(",", ".");
              } catch (error) {
                v = "";
              }
              v = this.trimdot(v);
              v = v.split("").reverse().join("");
              v = this.trimdot(v);
              v = v.split("").reverse().join("");
              serv.push(v);
            }
            this.currentSoal.respond = serv.join(",");
            this.addSaveQueue();
            if (e.target.innerHTML.length <= 0) e.target.innerHTML = ".....";
          }
        });
      },
      releaseCoupleOption(index) {
        let option = this.coupleOptions[index];
        this.currentSoal.opsi_id = this.currentSoal.opsi_id
          .split(",")
          .filter((el) => {
            return el.split("-")[1] != option.id;
          })
          .join(",");
        this.question_selected = null;
        option.soal_couple_id = null;
        this.addSaveQueue();
      },
      coupleOptionSelected(index) {
        let nopsi_id = [];
        let opsi_id = [];
        if (this.currentSoal.opsi_id) {
          opsi_id = this.currentSoal.opsi_id.split(",");
        }
        opsi_id.forEach((el) => {
          let e = el.split("-");
          if (
            e[0] == this.question_selected ||
            this.coupleOptions[index].id == e[1]
          )
            return;
          nopsi_id.push(e.join("-"));
        });
        this.coupleOptions.map((v, i) => {
          v.soal_couple_id =
            i == index
              ? this.question_selected
              : this.question_selected != v.soal_couple_id
                ? v.soal_couple_id
                : null;
          return v;
        });
        nopsi_id.push(
          `${this.question_selected}-${this.coupleOptions[index].id}`
        );
        this.currentSoal.opsi_id = nopsi_id.join(",");

        this.question_selected = null;
        this.addSaveQueue();
      },
      coupleQuestionSelected(index) {
        let nopsi_id = [];
        let opsi_id = [];
        if (this.currentSoal.opsi_id) {
          opsi_id = this.currentSoal.opsi_id.split(",");
        }
        opsi_id.forEach((el) => {
          let e = el.split("-");
          if (
            e[1] == this.option_selected ||
            this.coupleQuestions[index].id == e[0]
          )
            return;
          nopsi_id.push(e.join("-"));
        });
        this.coupleQuestions.map((v, i) => {
          v.soal_couple_id =
            i == index
              ? this.option_selected
              : this.option_selected != v.soal_couple_id
                ? v.soal_couple_id
                : null;
          return v;
        });
        nopsi_id.push(
          `${this.coupleQuestions[index].id}-${this.option_selected}`
        );
        this.currentSoal.opsi_id = nopsi_id.join(",");

        this.option_selected = null;
        this.addSaveQueue();
      },
      images_upload_handler(blobInfo, success, failure, progress) {
        if (this.$store.state.exam.strict) {
          let mdl = document.getElementById("grettingModal");
          this.$store.commit('exam/grettingModalTitle', 'Perhatian!');
          this.$store.commit('exam/grettingModalBody', 'Kembali ke ujian');
          if (!mdl.classList.contains("show")) new bootstrap.Modal(mdl).show();
        }

        let xhr, formData;

        xhr = new XMLHttpRequest();
        xhr.withCredentials = false;
        xhr.open("POST", window.location.href + "/imageUploader");

        xhr.upload.onprogress = function (e) {
          progress((e.loaded / e.total) * 100);
        };

        xhr.onload = () => {
          let json;

          if (xhr.status === 403) return failure("HTTP Error: " + xhr.status, { remove: true });

          if (xhr.status < 200 || xhr.status >= 300) return failure("HTTP Error: " + xhr.status);

          json = JSON.parse(xhr.responseText);

          if (!json || typeof json.location != "string") return failure("Invalid JSON: " + xhr.responseText);
          if (this.$store.state.exam.strict) this.$store.commit('exam/grettingModalBody', 'Gambar berhasil di unggah');
          success(json.location);
        };

        xhr.onerror = function () {
          failure(
            "Image upload failed due to a XHR Transport error. Code: " +
            xhr.status
          );
        };

        formData = new FormData();
        formData.append("file", blobInfo.blob(), blobInfo.filename());
        formData.append(
          [this.$store.state.config.csrf.name],
          this.$store.state.config.csrf.value
        );

        xhr.send(formData);
      },
      queueSaveSoal() {
        if (!this.internetState) return;
        if (this.lastServerError != 0 && this.lastServerError >= mm().subtract(2, 'm').unix()) return;
        this.soalData.forEach((elem, i) => {
          if (!elem) return;
          if (elem.sync && this.requesting > 3) return;
          this.requesting++;
          let dur = i * (Math.floor(Math.random() * 2000) + 500);
          if (
            mm().unix() + dur > this.localConfig.end_at &&
            this.localConfig.end_at
          )
            dur = mm().unix() - this.localConfig.end_at - 200;
          if (dur < 0) dur = 0;
          setTimeout(() => {
            this.saveSoal(i + 1, true);
          }, dur);
        });
      },
      onlineStatus(event) {
        this.internetState = navigator.onLine;
      },
      shuffle(array) {
        let currentIndex = array.length,
          randomIndex;

        // While there remain elements to shuffle...
        while (currentIndex != 0) {
          // Pick a remaining element...
          randomIndex = Math.floor(Math.random() * currentIndex);
          currentIndex--;

          // And swap it with the current element.
          [array[currentIndex], array[randomIndex]] = [
            array[randomIndex],
            array[currentIndex],
          ];
        }

        return array;
      },
      isSoalAvailableLocalStorage() {
        for (let index = 1; index < this.localConfig.total_soal; index++) {
          if (!localStorage.getItem(`${window.location.href}/soal/${index}`))
            return false;
        }
        return true;
      },
      loadSoals() {
        this.warnMsg = "";
        axios({
          method: "get",
          cancelToken: this.source.token,
          url: window.location.href + "/soals",
        }).then(
          (response) => {
            this.$store.commit("exam/notFound", false);
            if (!isObject(response.data))
              return (this.warnMsg = gaem(
                {
                  response,
                },
                response.data
              ));
            // if (this.localConfig.acak_soal == "1") this.shuffle(response.data);
            response.data.forEach((v, soalIndex) => {
              if (
                [1, 3, 4].includes(parseInt(v.jenis_soal)) &&
                this.localConfig.acak_opsi == "1"
              ) {
                v.opsi = this.shuffle(v.opsi);
                if (v.jenis_soal == 4) v.questions = this.shuffle(v.questions);
              }
              v.sync = true;
              v.custom_respond = v.question.indexOf("{...}") != -1;
              localStorage.setItem(
                window.location.href + "/soal/" + (soalIndex + 1),
                JSON.stringify(v)
              );
              if (soalIndex + 1 == this.soalActive) {
                this.soalData[soalIndex] = v;
                if (v.jenis_soal == 5) this.shortentryParse();
              } else {
                this.soalData[soalIndex] = v;
              }
            });
            this.amplifyImage();
          },
          (err) => {
            if (typeof err.response == "undefined") return;
            if (err.response.status == 500) return this.$store.commit("exam/errMsg", gaem(err, "Terjadi Kesalahan Dalam Memuat Soal"));
            if (err.response.status == 404)
              this.$store.commit("exam/notFound", true);
          }
        );
      },
      loadSoal(index = null) {
        let soalIndex = index || this.soalActive;
        this.warnMsg = "";
        let sd = localStorage.getItem(
          window.location.href + "/soal/" + soalIndex
        );
        if (sd && (this.localConfig.cache_soal || !this.internetState)) {
          let soal = JSON.parse(sd);
          this.soalData[soalIndex - 1] = soal;
          if (parseInt(soal.jenis_soal) == 5) this.shortentryParse();
          else if (
            parseInt(soal.jenis_soal) == 2 &&
            (soal.esai || "").length <= 0
          ) {
            this.soalData[soalIndex - 1].esai = " ";
          }
          return this.$store.commit("exam/notFound", false);
        }
        if (!this.internetState && soalIndex == this.soalActive) {
          return setTimeout(() => this.loadSoal(index), 500);
        }

        this.soalData[soalIndex - 1] = null;
        axios({
          method: "get",
          cancelToken: this.source.token,
          url: window.location.href + "/soal/" + soalIndex,
        }).then(
          (response) => {
            this.$store.commit("exam/notFound", false);
            if (!isObject(response.data))
              return (this.warnMsg = gaem(
                {
                  response,
                },
                response.data
              ));
            if (
              [1, 3, 4].includes(parseInt(response.data.jenis_soal)) &&
              this.localConfig.acak_opsi == "1"
            ) {
              response.data.opsi = this.shuffle(response.data.opsi);
              if (response.data.jenis_soal == 4)
                response.data.questions = this.shuffle(response.data.questions);
            }
            response.data.sync = true;
            response.data.custom_respond =
              response.data.question.indexOf("{...}") != -1;
            let e = this.soalData;
            e[soalIndex - 1] = response.data;
            this.soalData = e;
            localStorage.setItem(
              window.location.href + "/soal/" + soalIndex,
              JSON.stringify(response.data)
            );
            if (parseInt(response.data.jenis_soal) == 5) this.shortentryParse();
          },
          (err) => {
            if (typeof err.response == "undefined") return;
            this.warnMsg = gaem(err, "Terjadi Kesalahan Dalam Memuat Soal");
            if (err.response.status == 404)
              this.$store.commit("exam/notFound", true);
          }
        );
      },
      pgcommon(opsi_id) {
        this.soalData = this.soalData.map((elem, i) => {
          if (i == this.soalActive - 1) {
            elem.opsi_id = opsi_id;
          }
          return elem;
        });
        this.addSaveQueue(this.soalActive);
      },
      pgmultiselected(index) {
        if (this.currentSoal.opsi_id == null) {
          this.currentSoal.opsi_id = this.currentSoal.opsi[index].id;
          return this.addSaveQueue();
        }
        let opsi_id = (this.currentSoal.opsi_id || "").split(",");
        let opsi_exist = opsi_id.findIndex(
          (v) => v == this.currentSoal.opsi[index].id
        );
        if (opsi_exist != -1) {
          opsi_id = opsi_id.filter((v) => v != this.currentSoal.opsi[index].id);
        } else {
          opsi_id.push(this.currentSoal.opsi[index].id);
        }
        this.currentSoal.opsi_id = opsi_id.join(",").replace(/(^,)|(,$)/g, "");
        this.addSaveQueue();
      },
      pgtfselected(state, index) {
        let opsi_id = (this.currentSoal.opsi_id || "")
          .split(",")
          .filter((v) => {
            return v.split("-")[0] != `${this.currentSoal.opsi[index].id}`;
          });
        opsi_id.push(`${this.currentSoal.opsi[index].id}-${state}`);
        this.currentSoal.opsi_id = opsi_id.join(",").replace(/(^,)|(,$)/g, "");
        this.addSaveQueue();
      },
      shortentryParse() {
        let data = this.currentSoal;
        if (parseInt(data.jenis_soal) != 5 || !data.custom_respond) return;
        let pattern = /<span class="input shortentry-respond px-3" id="shortentry-respond" role="textbox" contenteditable="">(.....|.*?)<\/span>/gm;
        let crl = data.question.match(/{...}/g) || data.question.match(pattern);
        crl = !crl ? 0 : crl.length;
        let serv = (data.respond || "").split(',');
        if (crl == 1) {
          data.question = data.question.replace(
            pattern,
            `<span class="input shortentry-respond px-3" id="shortentry-respond" role="textbox" contenteditable="">${data.respond || "....."
            }</span>`
          );
          data.question = data.question.replace(
            "{...}",
            `<span class="input shortentry-respond px-3" id="shortentry-respond" role="textbox" contenteditable="">${data.respond || "....."
            }</span>`
          );
          return;
        }

        if (data.respond == null) {
          serv = [];
          for (let i = 0; i < crl; i++) serv.push(null);
        }
        let i = 0;
        data.question = data.question.replace(
          pattern,
          function (str) {
            return `<span class="input shortentry-respond px-3" id="shortentry-respond" role="textbox" contenteditable="">${serv[i++] || "....."
              }</span>`
          }
        );

        // } else {
        for (i = 0; i < crl; i++) {
          data.question = data.question.replace(
            "{...}",
            `<span class="input shortentry-respond px-3" id="shortentry-respond" role="textbox" contenteditable="">${serv[i] || "....."
            }</span>`
          );

        }
        // }
      },
      addSaveQueue(index = null) {
        let soalIndex = index || this.soalActive;
        let data = this.soalData[soalIndex - 1];
        if (!data) return;
        if ((parseInt(data.jenis_soal) == 2 && !data.esai) || (parseInt(data.jenis_soal) == 5 && !data.respond)) {
          if (!data.esai)
            return this.$store.commit("exam/errMsg", "Tolong Isi Jawaban!");
        } else if (
          [1, 3, 4].includes(parseInt(data.jenis_soal)) &&
          !data.opsi_id
        ) {
          return this.$store.commit("exam/errMsg", "Tolong Pilih Jawaban!");
        }
        this.$store.commit("exam/errMsg", "");
        data.sync = false;
        if (data.jenis_soal == 4 && this.currentSoal.soal_id == data.soal_id) {
          data.questions = this.currentSoal.questions;
          data.opsi = this.currentSoal.opsi;
        }
        this.soalData[soalIndex - 1] = data;
        localStorage.setItem(
          window.location.href + "/soal/" + soalIndex,
          JSON.stringify(data)
        );
      },
      saveSoal(index = null, isQue = false) {
        let soalIndex = index || this.soalActive;
        if (!this.axiosToken.save[index]) {
          this.axiosToken.save[index] = {
            saveSource: null,
            CancelToken: null,
            Source: null,
          };
        }
        if (this.axiosToken.save[index].Source) {
          // this.axiosToken.save[index].Source.cancel();
        }
        this.axiosToken.save[index].CancelToken = axios.CancelToken;
        this.axiosToken.save[index].Source =
          this.axiosToken.save[index].CancelToken.source();
        let data = this.soalData[soalIndex - 1];
        if (data.sync && isQue) return;
        if (!data) return;
        if (
          (parseInt(data.jenis_soal) == 2 && !data.esai) ||
          (parseInt(data.jenis_soal) == 5 && !data.respond)
        ) {
          if (!data.esai)
            return this.$store.commit("exam/errMsg", "Tolong Isi Jawaban!");
        } else if (
          [1, 3, 4].includes(parseInt(data.jenis_soal)) &&
          !data.opsi_id
        ) {
          return this.$store.commit("exam/errMsg", "Tolong Pilih Jawaban!");
        }
        this.$store.commit("exam/errMsg", "");
        if (data.sync) {
          // this.$store.commit('exam/loading', true);
        }
        data.sync = false;
        data = Object.assign(
          {
            [this.$store.state.config.csrf.name]:
              this.$store.state.config.csrf.value,
          },
          data
        );
        let ndt = JSON.parse(JSON.stringify(data));
        delete ndt.question;
        axios({
          method: "put",
          data: ndt,
          cancelToken: this.axiosToken.save[index].Source.token,
          url: window.location.href + "/soal/" + soalIndex,
        }).then(
          (response) => {
            if (!isObject(response.data))
              return setTimeout(() => this.saveSoal(soalIndex, isQue), 1000);
            delete response.data.csrf;
            if (isQue) this.requesting--;
            // this.$store.commit('exam/loading', false);
            let e = this.soalData;
            data.sync = true;
            if (this.soalActive == soalIndex) {
              e[soalIndex - 1].sync = true;
            } else {
              e[soalIndex - 1] = data;
              e[soalIndex - 1].sync = true;
              this.soalData = e;
            }
            // if (data.jenis_soal == 5) this.shortentryParse(true);
            localStorage.setItem(
              window.location.href + "/soal/" + soalIndex,
              JSON.stringify(data)
            );
            this.lastServerError = 0;
            // if (data.jenis_soal == 5) this.shortentryParse(false);
          },
          (err) => {
            if (
              data.jenis_soal == 4 &&
              this.currentSoal.soal_id == data.soal_id
            ) {
              data.questions = this.currentSoal.questions;
              data.opsi = this.currentSoal.opsi;
            }
            if (isQue) this.requesting--;
            let e = this.soalData;
            if (!e[soalIndex - 1].sync && this.soalActive != soalIndex) {
              e[soalIndex - 1] = data;
              this.soalData = e;
            }
            delete data[this.$store.state.config.csrf.name];
            localStorage.setItem(
              window.location.href + "/soal/" + soalIndex,
              JSON.stringify(data)
            );
            // this.$store.commit('exam/loading', false);
            if (typeof err.response == "undefined") return;
            if ([502, 504].includes(err.response.status)) this.lastServerError = mm().unix();
            if (isQue && err.response.status != 404) return;
            this.$store.commit("exam/errMsg", gaem(err));
          }
        );
      },
    },
    computed: {
      currentSoal() {
        return this.soalData[this.soalActive - 1];
      },
      coupleQuestions() {
        let colors = ["primary", "success", "info", "warning", "danger"];
        return this.currentSoal.questions.map((v, i) => {
          v.color = colors[i];
          v.coupled =
            this.compiledCoupleOptions.findIndex(
              (v2) => v2.soal_couple_id == v.id
            ) != -1;
          return v;
        });
      },
      compiledCoupleOptions() {
        return this.currentSoal.opsi.map((v, i) => {
          v.soal_couple_id = null;
          let opsi = this.currentSoal.opsi_id;
          if (!opsi) return v;
          let sci = opsi.split(",").map((sv) => sv.split("-"));
          let opsi_id = sci.findIndex((v2) => v2[1] == v.id);
          if (opsi_id != -1) {
            v.soal_couple_id = sci[opsi_id][0];
          }
          return v;
        });
      },
      coupleOptions() {
        return this.compiledCoupleOptions.map((v, i) => {
          let coupled = this.coupleQuestions.findIndex(
            (v2) => v2.id == v.soal_couple_id
          );
          v.coupled = coupled != -1;
          v.color = v.coupled ? this.coupleQuestions[coupled].color : null;
          return v;
        });
      },
      soalActive: {
        get() {
          return this.$store.state.exam.active;
        },
        set(i) {
          this.$store.commit("exam/active", i);
        },
      },
    },
  };
})();
