Tool Translator++ 4.9.28 Standard Version / Developer Version

5.00 star(s) 2 Votes

jaden_yuki

Well-Known Member
Jul 11, 2017
1,056
896
hey, I just noticed that my public version of translator++ just got updated automatically???? I wasn't expecting this, and my custom addons are broken now. nice job dreamsavior :rolleyes:
 

Aescanor

Member
Dec 11, 2019
271
310
Translator++ 7.5.28 Standard Version / Developer Version

View attachment 839993


Or decode games such as images, text, audio, etc. Do not encounter problems with the site because the search in the query and I do not know.


View attachment 839994
Thanks to the participants of this work
TheExorcist- ripno
Version and links updated 7.5.28

Translator++ 4.6.29 x64

Translator++ 4.6.29 xi32

Translator++ 4.6.29 x32 Admin

Translator++ 4.6.29 x64 Admin

Translator++ 4.7.30 Standard x64

Translator++ 4.7.30 Standard x32

Translator++ 4.7.30 Developer x64

Translator++ 4.7.30 Developer x32


Translator++ 4.9.28 https://f95zone.to

Translator++ 7.5.28


The new feature in translating the games you are playing and saving the translation file within the game The reminder does not work on all games

I hope it helps everyone to update the content so that the post in the comments is the most recent update and is tried before it is republished on the homepage. Thanks to everyone who participated

Unity3D Games Automatic Translator
Explain the preparation of the tool and take a copy of the translation files with the possibility of modification and correction

XUnity.AutoTranslator -4.18.0

In the tool there is a fast and slow translator only by changing a number from 8 to 9 I forgot to explain it in the video

View attachment 1390144 View attachment 1390145
OverrideFontTextMeshPro=arialuni_sdf_u2019 OverrideFontTextMeshPro=arialuni_sdf_u2018

If I encountered a problem with the translation exit from the dialog, delete the selector V2, I am facing this problem in translating from English to Arabic
View attachment 1393758 View attachment 1393759
 

srjn12

Newbie
Mar 31, 2020
36
29
i made changes to the palos lions instant translation tool a long time ago, if anyone wants to use it, they can try. mistakes can occur in some games.

"T" translation on/off.
captured_translations in each dialog game folder where instant translation takes place.it is saved in the json name.

good 31s.
 

jaden_yuki

Well-Known Member
Jul 11, 2017
1,056
896
guys, I was inspecting the code of the new version (7.4.24C) here, and I noticed something: some of the code is fetched from a REST API endpoint and then executed. I really don't like this.
 

ripno

Newbie
Jan 27, 2023
63
105
guys, I was inspecting the code of the new version (7.4.24C) here, and I noticed something: some of the code is fetched from a REST API endpoint and then executed. I really don't like this.

Hi, I noticed you're still using version 7.4.24C of Translator++. Just wondering—is there a specific reason you're sticking with that one?

Version 7.5.28 has already been shared with the community (see post #1326), and the developer has even released version 7.6.25 as the latest build.
 

jaden_yuki

Well-Known Member
Jul 11, 2017
1,056
896
Hi, I noticed you're still using version 7.4.24C of Translator++. Just wondering—is there a specific reason you're sticking with that one?

Version 7.5.28 has already been shared with the community (see post #1326), and the developer has even released version 7.6.25 as the latest build.
because that's the current public release, I have to work with that since I'm dev working on custom extensions.
 

jaden_yuki

Well-Known Member
Jul 11, 2017
1,056
896
guys, I was inspecting the code of the new version (7.4.24C) here, and I noticed something: some of the code is fetched from a REST API endpoint and then executed. I really don't like this.
update: this code that is fetched is also encrypted, a bad sign, and the decrypted code is minified as well, a very bad sign. I'll share it here

JavaScript:
/**=====LICENSE STATEMENT START=====
    Translator++
    CAT (Computer-Assisted Translation) tools and framework to create quality
    translations and localizations efficiently.
   
    Copyright (C) 2018  Dreamsavior<dreamsavior@gmail.com>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.
=====LICENSE STATEMENT END=====*/
/**
* @file trans.js The core class of Translator++
* @author Dreamsavior
* File version: 2024-04-03 14:22:34.304
*/

(window.fs = require("graceful-fs")),
  (window.afs = require("await-fs")),
  (window.nwPath = require("path")),
  (window.spawn = require("child_process").spawn),
  (window.debounce = require("debounce")),
  (window.BatchTranslate = require("www/js/BatchTranslate.js")),
  (window.insertArrayAt = function (e, t, n) {
    return Array.prototype.splice.apply(e, [t, 0].concat(n)), e;
  }),
  (global.common ||= {}),
  (common.arrayExchange = function (e, t, n) {
    var r = e[t];
    e.splice(t, 1), e.splice(n, 0, r);
  }),
  (common.arrayExchangeBatch = function (e, t, n) {
    0 == Array.isArray(t) && common.arrayExchange(e, t, n);
    for (var r = t.length - 1; 0 <= r; r--) common.arrayExchange(e, t[r], n);
    return e;
  }),
  (common.arrayMove = function (e, t, n) {
    if (0 != Array.isArray(e) && n !== t) {
      for (var r = e[t], o = n < t ? -1 : 1, a = t; a != n; a += o)
        e[a] = e[a + o];
      e[n] = r;
    }
    return e;
  }),
  (common.arrayMoveBatch = function (e, t, n) {
    if (0 == Array.isArray(t)) return common.arrayMove(e, t, n);
    for (var r = 0, o = t.length - 1; 0 <= o; o--)
      (e = common.arrayMove(e, t[o] + r, n)), r++;
    return e;
  }),
  (common.escapeSelector = function (e) {
    return "string" == typeof (e = e || "") && '"' + CSS.escape(e) + '"';
  }),
  (common.arrayInsert = function (e, t, n) {
    return e.splice(t, 0, n), e;
  }),
  (common.batchArrayInsert = function (e, t, n) {
    for (var r = 0; r < e.length; r++) this.arrayInsert(e[r], t, n);
    return e;
  });
var FileLoader = function () {
  this.handler = {};
};
(FileLoader.prototype.add = function (e, t) {
  this.handler[e] = t;
}),
  (FileLoader.prototype.open = function (e, t) {}),
  (window.FileLoader = FileLoader);
class Trans extends require("www/js/BasicEventHandler.js") {
  constructor() {
    super($(document)), this.init();
  }
}
(Trans.maxCols = 15),
  (Trans.CellInfo = function () {}),
  (Trans.CellInfo.prototype.getAll = function (e) {
    if (e && trans?.project?.files?.[e])
      return (
        (e = trans.getObjectById(e)).cellInfo || (e.cellInfo = []), e.cellInfo
      );
  }),
  (Trans.CellInfo.prototype.getRow = function (e, t) {
    e = this.getAll(e);
    if (e) return e[t];
  }),
  (Trans.CellInfo.prototype.getCell = function (e, t, n) {
    e = this.getRow(e, t);
    if (e) return e[n];
  }),
  (Trans.CellInfo.prototype.getBestCellInfo = function (e, t, n) {
    var r = trans.getData(e),
      r = trans.getTranslationColFromRow(r[t]),
      e = this.getCell(e, t, r);
    return e && (n ? e[n] : e);
  }),
  (Trans.CellInfo.prototype.get = function (e, t, n, r) {
    t = this.getCell(t, n, r);
    if (t) return t[e];
  }),
  (Trans.CellInfo.prototype.set = function (e, t, n, r, o) {
    n = this.getAll(n);
    return (n[r] = n[r] || []), (n[r][o] = n[r][o] || {}), (n[r][o][e] = t), !0;
  }),
  (Trans.CellInfo.prototype.delete = function (e, t, n, r) {
    t = this.getAll(t);
    return (
      (t[n] = t[n] || []), (t[n][r] = t[n][r] || {}), delete t[n][r][e], !0
    );
  }),
  (Trans.CellInfo.prototype.deleteRow = function (e, t) {
    e = this.getAll(e);
    empty(e) || (Array.isArray(e) ? e.splice(t, 1) : delete e[t]);
  }),
  (Trans.CellInfo.prototype.deleteCell = function (e, t, n) {
    e = this.getRow(e, t);
    if (Array.isArray(e)) return e.splice(n, 1), !0;
  }),
  (Trans.CellInfo.prototype.moveCell = function (e, t, n, r) {
    e = this.getRow(e, t);
    if (Array.isArray(e)) return common.arrayMoveBatch(e, n, r), !0;
  }),
  (Trans.prototype.init = function () {
    (this.config = {
      loadRomaji: !0,
      maxRequestLength: 3e3,
      autoSaveEvery: 600,
      batchDelay: 5e3,
      rpgTransFormat: !0,
      autoTranslate: !1,
    }),
      (this.keyColumn = 0),
      (this.isFreeEditing = !1),
      (this.gameTitle = ""),
      (this.gameEngine = ""),
      (this.projectId = ""),
      (this.indexIds = {}),
      (this.fileListLoaded = !1),
      (this.isLoadingFileList = !1),
      (this.unsavedChange = !1),
      (this.gameFolder = ""),
      (this.currentFile = ""),
      (this.skipElement = ["note", "Comment", "Script"]),
      (this.project = void 0),
      (this.timers = {}),
      (this.data = []),
      (this.colHeaders = [
        t("Original Text"),
        t("Initial"),
        t("Machine translation"),
        t("Better translation"),
        t("Best translation"),
      ]),
      (this.onFileNavLoaded = function () {}),
      (this.onFileNavUnloaded = function () {}),
      (this.validateKey = function (e, t) {
        console.log("key validator", e), t("" != e && null != e);
      }),
      (this.columns = [
        { readOnly: !1, validator: this.validateKey, width: 150 },
        { readOnly: !1 },
        { readOnly: !1 },
        { readOnly: !1 },
        { readOnly: !1 },
      ]),
      (this.default = {}),
      (this.default.columns = [
        { readOnly: !1, validator: this.validateKey },
        { readOnly: !1 },
        { readOnly: !1 },
        { readOnly: !1 },
        { readOnly: !1 },
      ]),
      (this.inProject = !1),
      (this.default.colHeaders = [
        t("Original Text"),
        t("Initial"),
        t("Machine translation"),
        t("Better translation"),
        t("Best translation"),
      ]);
  }),
  (Trans.prototype.isTrans = function (e) {
    return !(
      !e ||
      ("Object" !== e.constructor.name && "Trans" !== e.constructor.name) ||
      !e?.project?.files
    );
  }),
  (Trans.prototype.getOption = function (e) {
    if (trans.project)
      return (
        (trans.project.options ||= {}),
        void 0 === trans.project.options.gridInfo &&
          (trans.project.options.gridInfo = {
            isRuleActive: !0,
            enableTrail: !0,
            viewTrail: !1,
            viewOrganicCellMarker: !0,
            rowHeaderInfo: !1,
          }),
        trans.project.options[e]
      );
  }),
  (Trans.prototype.setOption = function (e, t) {
    trans.project &&
      (console.log("Setting option", e, t),
      (trans.project.options ||= {}),
      (trans.project.options[e] = t));
  }),
  (Trans.prototype.getConfig = function (e) {
    if (
      ((trans.project.config = trans.project.config || {}),
      "string" == typeof e)
    )
      return trans.project.config[e];
    if (Array.isArray(e)) {
      var t = trans.project.config;
      try {
        for (var n = 0; n < e.length; n++) t = t[e[n]];
        return t;
      } catch (e) {
        return;
      }
    }
  }),
  (Trans.prototype.setConfig = function (e, t) {
    if (
      ((trans.project.config = trans.project.config || {}),
      "string" == typeof e)
    )
      return (trans.project.config[e] = t), !0;
    if (Array.isArray(e)) {
      var n = trans.project.config;
      try {
        for (var r = 0; r < e.length - 1; r++)
          (n[e[r]] = n[e[r]] || {}), (n = n[e[r]]);
        return (n[e[r]] = t), !0;
      } catch (e) {
        return;
      }
    }
  }),
  (Trans.prototype.isInProject = function () {
    return this.inProject;
  }),
  (Trans.prototype.getTemplatePath = function () {
    var t =
      sys.config.templatePath || nw.App.manifest.localConfig.defaultTemplate;
    fs = fs || require("fs");
    try {
      if (fs.existsSync(t)) return t;
    } catch (e) {
      return nwPath.join(__dirname, t);
    }
  }),
  (Trans.prototype.mergeReference = function (e) {
    for (var t in (console.log("Merging reference"),
    ((e = e || {}).project = e.project || {}),
    (e.project.references = e.project.references || {}),
    (e.project.files = e.project.files || {}),
    e.project.references))
      console.log("assigning : ", t),
        (e.project.files[t] = this.project.references[t]);
    return e;
  }),
  (Trans.prototype.isFileSupported = function (e) {
    return (
      "string" == typeof e &&
      ((e = common.getFileExtension(e)), !!sys.supportedExtension.includes(e))
    );
  }),
  (Trans.prototype.openFile = function (e) {
    var t,
      n = require("child_process").spawn;
    return (
      0 != this.isFileSupported(e) &&
      ((t = common.getFileExtension(e)),
      "function" == typeof this.fileLoader.handler[t]) &&
      void (0 == this.fileListLoaded
        ? (ui.introWindowClose(), this.fileLoader.handler[t].apply(this, [e]))
        : n(nw.process.execPath, [e], { detached: !0 }))
    );
  }),
  (Trans.prototype.initProject = function () {
    if (void 0 !== this.project)
      return console.log("project is already been initialized! skipping!"), !1;
  }),
  (Trans.prototype.closeProject = function () {
    if (void 0 === this.project) return !1;
    "function" == typeof this.grid.destroy() && this.grid.destroy(),
      this.unInitFileNav(),
      this.unInitLocalStorage(),
      (this.project = {}),
      this.init(),
      ui.tableCornerHideLoading(!0),
      ui.closeAllChildWindow(),
      ui.ribbonMenu.clear(),
      ui.clearActiveCellInfo(),
      ui.clearPathInfo(),
      ui.setWindowTitle(""),
      trans.clearFooter(),
      this.initTable(),
      this.gridIsModified(!1);
  }),
  (Trans.prototype.generateNewDictionaryTable = function () {
    var e = "Common Reference";
    if (void 0 !== this.project.files[e]) return this.project.files[e];
    if ("object" == typeof this.project.references)
      for (var t in (console.log("trans.project.reference is an object"),
      this.project.references))
        this.project.files[t] = this.project.references[t];
    else {
      console.log("trans.project.reference is not an object");
      (e = this.getTemplatePath()), (e = this.loadJSONSync(e));
      console.log("template obj : ", e),
        !1 !== Boolean(e) &&
          ((this.project.references = e.project.references),
          console.log("assigning reference : ", this.project.references)),
        this.mergeReference(trans);
    }
    return this.project.references;
  }),
  (Trans.prototype.createProject = function (a) {
    var i, e;
    return (
      console.log("running trans.createProject"),
      !this.isLoadingFileList &&
        "" != this.gameFolder &&
        ((i = this),
        ((a = a || {}).force = a.force || ""),
        (a.selectedFile = a.selectedFile || ""),
        (a.onAfterLoading = a.onAfterLoading || function (e, t) {}),
        (a.options = a.options || {}),
        (this.isLoadingFileList = !0),
        ui.showLoading(),
        (e = {
          gameFolder: this.gameFolder,
          selectedFile: a.selectedFile,
          gameEngine: this.gameEngine,
          gameTitle: this.gameTitle,
          projectId: this.projectId,
          skipElement: this.skipElement,
          indexOriginal: 0,
          indexTranslation: 1,
          force: a.force,
          rpgTransFormat: i.config.rpgTransFormat,
          options: a.options,
        }),
        console.log("Sending this args to loadGameInfo.php : ", e),
        void php.spawn("loadGameInfo.php", {
          args: e,
          onData: function (e) {
            ui.loadingProgress(t("Loading"), e, {
              consoleOnly: !0,
              mode: "consoleOutput",
            });
          },
          onError: function (e) {
            ui.loadingProgress(t("Loading"), e, {
              consoleOnly: !0,
              mode: "consoleOutput",
              classStr: "stderr",
            });
          },
          onDone: function (e) {
            if (
              (console.log("onDone event defined from trans.js"),
              common.isJSON(e))
            )
              (i.project = e),
                (i.currentFile = ""),
                (i.gameTitle = e.gameTitle),
                (i.gameFolder = e.loc),
                (i.projectId = e.projectId),
                (i.gameEngine = e.gameEngine),
                (i.editorName = "Translator++"),
                (i.editorVersion = nw.App.manifest.version),
                i.generateHeader(),
                i.sanitize(),
                i.dataPadding(),
                sys.updateLastOpenedProject(),
                i.autoSave(),
                console.log(e),
                ui.setStatusBar(1, i.gameTitle),
                i.trigger("projectCreated", i, e),
                "function" == typeof a.onAfterLoading &&
                  a.onAfterLoading.call(i, e, this),
                (i.fileListLoaded = !0),
                (i.isLoadingFileList = !1),
                ui.showCloseButton();
            else {
              var e = $("<div>" + e + "</div>"),
                o = e.find("#initialDataPath").attr("data-path");
              if ((console.log("found initPath : " + o), 0 == Boolean(o)))
                ui.loadingProgress(
                  "Error!",
                  "Can not successfully parse your game! Read the documentation here: https://dreamsavior.net/?p=1311",
                  { consoleOnly: !0, mode: "consoleOutput" }
                ),
                  ui.showCloseButton(),
                  (i.fileListLoaded = !1),
                  (i.isLoadingFileList = !1);
              else {
                try {
                  fs.readFile(o, function (e, n) {
                    if (e)
                      throw (
                        (console.log("error opening file : " + o),
                        ui.loadingProgress(
                          "Error!",
                          "Error opening file : " + o,
                          { consoleOnly: !0, mode: "consoleOutput" }
                        ),
                        ui.showCloseButton(),
                        (i.fileListLoaded = !1),
                        (i.isLoadingFileList = !1),
                        e)
                      );
                    var n = n.toString(),
                      r = {};
                    try {
                      r = JSON.parse(n);
                    } catch (e) {
                      return (
                        ui.loadingProgress(
                          t("Error!"),
                          t("Error processing init file : ") + o + "\n" + e,
                          { consoleOnly: !0, mode: "consoleOutput" }
                        ),
                        ui.showCloseButton(),
                        (i.isLoadingFileList = !1)
                      );
                    }
                    if (0 == Boolean(r.files))
                      return (
                        ui.loadingProgress(
                          t("Error!"),
                          t("Error! File list not found in init file at : ") +
                            o,
                          { consoleOnly: !0, mode: "consoleOutput" }
                        ),
                        ui.loadingProgress(
                          t("Error!"),
                          t(
                            "This means that your game was not successfully parsed. Please visit https://dreamsavior.net/?p=1311 for possible solution for this issue."
                          ),
                          { consoleOnly: !0, mode: "consoleOutput" }
                        ),
                        ui.showCloseButton(),
                        (i.isLoadingFileList = !1)
                      );
                    (i.project = r),
                      (i.currentFile = ""),
                      (i.gameTitle = r.gameTitle),
                      (i.gameFolder = r.loc),
                      (i.projectId = r.projectId),
                      (i.gameEngine = r.gameEngine),
                      (i.editorName = "Translator++"),
                      (i.editorVersion = nw.App.manifest.version),
                      i.generateHeader(),
                      i.sanitize(),
                      i.dataPadding(),
                      sys.updateLastOpenedProject(),
                      i.autoSave(),
                      console.log(r),
                      ui.setStatusBar(1, i.gameTitle),
                      i.trigger("projectCreated", i, r),
                      "function" == typeof a.onAfterLoading &&
                        a.onAfterLoading.call(i, r, this),
                      (i.fileListLoaded = !0),
                      (i.isLoadingFileList = !1),
                      ui.loadingProgress(t("Done!"), t("All done!"), {
                        consoleOnly: !1,
                        mode: "consoleOutput",
                      }),
                      ui.loadingEnd();
                  });
                } catch (e) {
                  console.log("error opening file : " + o),
                    ui.loadingProgress(
                      t("Error!"),
                      t("Error opening file : ") + o,
                      { consoleOnly: !1, mode: "consoleOutput" }
                    ),
                    ui.loadingProgress(t("Error!"), e, {
                      consoleOnly: !0,
                      mode: "consoleOutput",
                    }),
                    ui.loadingEnd(),
                    (i.fileListLoaded = !1),
                    (i.isLoadingFileList = !1);
                }
                e = e.find("#tmpPath");
                0 < e.length && ui.showOpenCacheButton(e.text());
              }
            }
          },
        }))
    );
  }),
  (Trans.prototype.procedureCreateProject = function (t, n) {
    if (
      (console.log("running trans.procedureCreateProject"),
      console.log(arguments),
      void 0 === t)
    )
      return !1;
    ((n = n || {}).selectedFile = n.selectedFile || ""),
      (n.force = n.force || ""),
      (n.projectInfo = n.projectInfo || { id: "", title: "" }),
      (n.options = n.options || {}),
      (n.gameEngine = n.gameEngine || ""),
      this.closeProject(),
      (this.projectId = n.projectInfo.id),
      (this.gameTitle = n.projectInfo.title),
      (this.gameFolder = t),
      (this.gameEngine = n.gameEngine),
      ui.newProjectDialog.close(),
      this.createProject({
        selectedFile: n.selectedFile,
        force: n.force,
        onAfterLoading: async function (e) {
          this.drawFileSelector(),
            (this.project.options = this.project.options || {}),
            (this.project.options.init = n.options || {}),
            engines.hasHandler("onAfterCreateProject") &&
              (await common.wait(100),
              await engines.handler("onAfterCreateProject").call(this, t, n));
        },
        options: n.options,
      });
  }),
  (Trans.prototype.getRow = function (e, t) {
    if ("string" == typeof t)
      return (
        console.log("Get row", arguments),
        0 == e.indexIsBuilt &&
          (console.log("building index for the first time"),
          this.buildIndexFromData(e)),
        (e.indexIds = e.indexIds || {}),
        console.log("getRow result is : ", e.indexIds[t]),
        e.indexIds[t]
      );
  }),
  (Trans.prototype.updateProject = function (e, t) {
    "string" == typeof e && (e = JSON.parse(e)),
      ((t = t || {}).onAfterLoading =
        t.onAfterLoading || function (e, t, n) {}),
      (t.onSuccess = t.onSuccess || function (e, t) {}),
      (t.onFailed = t.onFailed || function (e, t) {}),
      (t.filePath = t.filePath || ""),
      (t.purgeNonExistingData ||= !1),
      (e.project = e.project || {}),
      (e.project.files = e.project.files || {});
    var n,
      r = e,
      o = this.getSaveData().project.files || {};
    for (n in (console.log("Base data", e),
    console.log("Preserved current files", o),
    (r.project.files = e.project.files),
    e.project.files)) {
      var a = r.project.files[n];
      if (o[n] && o[n].data && !(o[n].data.length < 1))
        if (
          (console.log("%cprocessing file", "color:aqua", n),
          t.purgeNonExistingData)
        )
          for (let t = 0; t < a.data.length; t++) {
            var i = a.data[t][0],
              s = this.getRow(o[n], i);
            if (
              (console.log("%cKey", "color:aqua", i),
              console.log("%coldFileRow", "color:aqua", s),
              void 0 !== s && o[n].data[s])
            )
              for (let e = 1; e < o[n].data[s].length; e++)
                a.data[t][e] = o[n].data[s][e];
          }
        else {
          var l,
            c,
            d,
            g = o[n];
          let t = 0;
          for (let e = 0; e < g.data.length; e++)
            g.data[e]?.length &&
              (l = g.data[e][0]) &&
              (void 0 === (c = this.getRow(a, l))
                ? ((d = a.data.push(g.data[e]) - 1),
                  (a.data.indexIds ||= {}),
                  (a.data.indexIds[l] = d),
                  (a.context[d] = ["RefreshCarryover/" + t]),
                  g.cellInfo?.[e] &&
                    ((a.cellInfo ||= []), (a.cellInfo[d] = g.cellInfo[e])),
                  g.comments?.[e] &&
                    ((a.comments ||= []), (a.comments[d] = g.comments[e])),
                  g.parameters?.[e] &&
                    ((a.parameters ||= []),
                    (a.parameters[d] = g.parameters[e])),
                  g.tags?.[e] && ((a.tags ||= []), (a.tags[d] = g.tags[e])),
                  t++)
                : ((a.data[c] = g.data[e]),
                  g.cellInfo?.[e] &&
                    ((a.cellInfo ||= []), (a.cellInfo[c] = g.cellInfo[e])),
                  g.comments?.[e] &&
                    ((a.comments ||= []), (a.comments[c] = g.comments[e])),
                  g.parameters?.[e] &&
                    ((a.parameters ||= []),
                    (a.parameters[c] = g.parameters[e])),
                  g.tags?.[e] && ((a.tags ||= []), (a.tags[c] = g.tags[e]))));
        }
    }
    return console.log("updatedProject", r), r;
  }),
  (Trans.prototype.updateProject2 = function (e, t = this.getSaveData()) {
    return e;
  }),
  (Trans.prototype.openFromTransObj = function (e, t) {
    "string" == typeof e && (e = JSON.parse(e)),
      ((t = t || {}).onAfterLoading =
        t.onAfterLoading || function (e, t, n) {}),
      (t.onSuccess = t.onSuccess || function (e, t) {}),
      (t.onFailed = t.onFailed || function (e, t) {}),
      (t.filePath = t.filePath || ""),
      (t.isNew = t.isNew || !1),
      t.isNew && ((e = this.initTransData(e)), console.log(e)),
      (this.currentFile = t.filePath),
      this.applySaveData(e),
      this.sanitize(),
      this.grid.render(),
      sys.insertOpenedFileHistory();
    try {
      ($DV.config.sl = this.project.options.sl || "ja"),
        ($DV.config.tl = this.project.options.tl || "en");
    } catch (e) {
      ($DV.config.sl = "ja"), ($DV.config.tl = "en");
    }
    "function" == typeof t.onSuccess && t.onSuccess.call(this, e),
      "function" == typeof t.onAfterLoading &&
        t.onAfterLoading.call(this, "success", e),
      this.updateStagingInfo(),
      (this.isOpeningFile = !1),
      ui.hideBusyOverlay(),
      e.project.selectedId
        ? this.selectFile(e.project.selectedId)
        : this.selectFile($(".fileList .data-selector").eq(0));
  }),
  (Trans.prototype.detectFormat = async function (e) {
    return (
      !!e &&
      (".tpp" == nwPath.extname(e).toLowerCase()
        ? "tpp"
        : ".trans" == nwPath.extname(e).toLowerCase() && "trans")
    );
  }),
  (Trans.prototype.open = async function (r, o) {
    var a;
    return (
      "" != (r = r || this.currentFile) &&
      null != r &&
      void 0 !== r &&
      (console.log("opening project : ", r),
      "tpp" == (await this.detectFormat(r))
        ? this.importTpp(r)
        : ((a = this),
          ((o = o || {}).onAfterLoading =
            o.onAfterLoading || function (e, t, n) {}),
          (o.onSuccess = o.onSuccess || function (e, t) {}),
          (o.onFailed = o.onFailed || function (e, t) {}),
          (a.isOpeningFile = !0),
          ui.showBusyOverlay(),
          void fs.readFile(r, function (n, e) {
            if (n)
              console.log(n),
                alert(t("error opening file (open): ") + r + "\r\n" + n),
                void 0 !== e &&
                  ((e = e.toString()),
                  "function" == typeof o.onFailed && o.onFailed.call(a, e),
                  "function" == typeof o.onAfterLoading) &&
                  o.onAfterLoading.call(a, "error", e),
                ui.hideBusyOverlay();
            else {
              e = e.toString();
              n = {};
              try {
                n = JSON.parse(e);
              } catch (e) {
                return (
                  console.warn("Failed to parse JSON data"),
                  alert(
                    "Failed to parse JSON data.\nThe .trans file is corrupted."
                  ),
                  "function" == typeof o.onAfterLoading &&
                    o.onAfterLoading.call(a, "Failed", n),
                  (a.isOpeningFile = !1),
                  void ui.hideBusyOverlay()
                );
              }
              console.log(n),
                (a.currentFile = r),
                a.applySaveData(n),
                a.sanitize(),
                a.grid.render(),
                sys.insertOpenedFileHistory();
              try {
                ($DV.config.sl = a.project.options.sl || "ja"),
                  ($DV.config.tl = a.project.options.tl || "en");
              } catch (e) {
                ($DV.config.sl = "ja"), ($DV.config.tl = "en");
              }
              "function" == typeof o.onSuccess && o.onSuccess.call(a, n),
                "function" == typeof o.onAfterLoading &&
                  o.onAfterLoading.call(a, "success", n),
                (a.isOpeningFile = !1),
                ui.hideBusyOverlay(),
                n.project.selectedId
                  ? a.selectFile(n.project.selectedId)
                  : a.selectFile($(".fileList .data-selector").eq(0)),
                a.gridIsModified(!1),
                (a.project.options = a.project.options || {}),
                console.log("displaying info "),
                Boolean(a.project.options.info) &&
                  a.project.options.displayInfo &&
                  ui.showPopup(
                    "infobox_" + a.project.projectId,
                    a.project.options.info,
                    {
                      title: "Project's Info",
                      allExternal: !0,
                      HTMLcleanup: !0,
                    }
                  ),
                a.isCacheError()
                  ? (ui.addIconOverlay($(".button-properties"), "attention"),
                    $(".button-properties").attr(
                      "title",
                      "Project properties - Staging path error!"
                    ))
                  : (ui.clearIconOverlay($(".button-properties")),
                    $(".button-properties").attr(
                      "title",
                      "Project properties"
                    ));
            }
          })))
    );
  }),
  (Trans.prototype.isCacheError = function () {
    return (
      (trans.project.cache = trans.project?.cache || {}),
      !(
        !trans.project.cache.cachePath ||
        0 != common.isDir(trans.project.cache.cachePath)
      )
    );
  }),
  (Trans.prototype.getSl = function () {
    return (
      (sys.config.default = sys.config.default || {}),
      this.getOption("sl") || sys.config.default?.sl || $DV.config.sl
    );
  }),
  (Trans.prototype.getTl = function () {
    return (
      (sys.config.default = sys.config.default || {}),
      this.getOption("tl") || sys.config.default?.tl || $DV.config.tl
    );
  }),
  (Trans.prototype.setSl = function (e) {
    this.project && this.setOption("sl", e);
  }),
  (Trans.prototype.setTl = function (e) {
    this.project && this.setOption("tl", e);
  }),
  (Trans.prototype.applyNewData = function (e) {
    e = e || [[]];
    for (var t = 0; t < e.length; t++) this.data[t] = e[t];
  }),
  (Trans.prototype.applyNewHeader = function (e) {
    e = e || [];
    for (var t = 0; t < e.length; t++) this.colHeaders[t] = e[t];
  }),
  (Trans.prototype.generateId = function () {
    return common.makeid(10, "tppSZ698");
  }),
  (Trans.prototype.initTransData = function (e) {
    e = e || {};
    var t = JSON.parse(fs.readFileSync("data/template.trans")),
      t =
        ((t.project ||= {}),
        (t.project.projectId = void 0),
        (t.project.buildOn = void 0),
        common.mergeDeep(t, e));
    return (
      (t.project = t.project || {}),
      (t.project.options = t.project.options || {}),
      (t.project.options.init = t.project.options.init || {}),
      (t.project.projectId = t.project.projectId || this.generateId(10)),
      (t.project.buildOn = t.project.buildOn || common.formatDate(Date.now())),
      (t.project.editorVersion = nw.App.manifest.version),
      (t.project.editorName = "Translator++"),
      t
    );
  }),
  (Trans.prototype.createFileData = function (e, t, n = {}) {
    return (
      (t = t || {}),
      (e = e.replace(/\\/g, "/")),
      n?.leadSlash && "/" !== e.charAt(0) && (e = "/" + e),
      (t.basename = t.basename || nwPath.basename(e)),
      (t.filename = t.filename || nwPath.basename(e)),
      (t.path = t.path || e),
      (t.relPath = t.relPath || e),
      (t.data = t.data || [[null]]),
      (t.originalFormat = t.originalFormat || "Autogenerated TRANS obj"),
      (t.type = t.type || ""),
      (t.context = t.context || []),
      (t.tags = t.tags || []),
      void 0 === t.extension && (t.extension = nwPath.extname(e)),
      void 0 === t.dirname && (t.dirname = nwPath.dirname(e)),
      t
    );
  }),
  (Trans.prototype.validateTransData = function (e) {
    var n,
      r,
      o,
      a = {};
    if (Array.isArray(e))
      return (
        console.log("Case 1 - transData is array"),
        ((n = this.loadJSONSync(this.getTemplatePath())).project.files[
          "/main"
        ] = this.createFileData("/main", { data: e })),
        n
      );
    if (
      0 == Boolean(e.project) &&
      0 == Boolean(e.files) &&
      Array.isArray(e.data)
    )
      return (
        console.log("Case 1 - transData is file structured"),
        (n = this.loadJSONSync(this.getTemplatePath())),
        (r = e.path || "/main"),
        (n.project.files[r] = this.createFileData(r, { data: e.data })),
        n
      );
    for (o in (0 == Boolean(e.project) && 1 == Boolean(e.files)
      ? (a.project = e)
      : (a = e),
    (a.project.gameTitle = a.project.gameTitle || t("untitled project")),
    (a.project.gameEngine = a.project.gameEngine || ""),
    (a.project.projectId = a.project.projectId || ""),
    (a.project.buildOn = a.project.buildOn || common.formatDate()),
    (a.project.files = a.project.files || {}),
    a.project.files))
      a.project.files[o] = this.createFileData(o, a.project.files[o]);
    return a;
  }),
  (Trans.prototype.normalizeHeader = function () {
    for (var e = 0; e < this.columns.length; e++)
      e == this.keyColumn && (this.columns[e].validator = this.validateKey),
        (this.columns[e].wordWrap = !0);
  }),
  (Trans.prototype.applySaveData = function (t) {
    if (
      (console.log("entering trans.applySaveData"),
      console.log(t),
      (t = this.validateTransData((t = t || {}))),
      (this.data = t.data || [[null]]),
      (this.columns = t.columns || this.default.columns || []),
      this.normalizeHeader(),
      (this.colHeaders = t.colHeaders || this.default.colHeaders || []),
      (this.project = t.project || {}),
      (this.gameTitle = t.project.gameTitle || ""),
      (this.gameEngine = t.project.gameEngine || ""),
      (this.projectId = t.project.projectId || ""),
      (this.gameFolder = t.project.loc || ""),
      0 == t.fileListLoaded)
    )
      try {
        void 0 !== t.project.files && (t.fileListLoaded = !0);
      } catch (e) {
        t.fileListLoaded = !1;
      }
    return (
      this.resetIndex(),
      (this.fileListLoaded = t.fileListLoaded || !1),
      this.initFileNav(),
      this.refreshGrid(),
      ui.setWindowTitle(),
      ui.setStatusBar(1, this.gameTitle),
      this
    );
  }),
  (Trans.prototype.getSaveData = function (e) {
    if (
      (((e = e || {}).filter = e.filter || []),
      (e.type = e.type || ""),
      !empty(this.project) && !empty(this.project.files))
    ) {
      this.project.projectId = this.project.projectId || common.makeid(10);
      var t = JSON.parse(JSON.stringify(this.project)) || {};
      if (
        0 < e.filter.length &&
        (console.log("filtering saved object", e), void 0 !== this.project) &&
        void 0 !== this.project.files
      ) {
        t.files = {};
        for (var n = 0; n < e.filter.length; n++) {
          var r = e.filter[n];
          console.log(
            "testing " + r,
            this.project.files[r],
            this.project.files
          ),
            void 0 !== this.project.files[r] &&
              (console.log("exist, assigning " + r),
              (t.files[r] = JSON.parse(JSON.stringify(this.project.files[r]))));
        }
      }
      var o,
        a = { data: [[null]] };
      (a.columns = this.columns || []),
        (a.colHeaders = this.colHeaders || []),
        (a.project = t),
        (a.fileListLoaded = this.fileListLoaded);
      for (let e = 0; e < this.grid.getColHeader().length; e++)
        a.columns[e] && (a.columns[e].width = this.grid.getColWidth(e));
      for (o in a.project.files)
        "reference" == a.project.files[o].type &&
          ((a.project.references = a.project.references || {}),
          (a.project.references[o] = JSON.parse(
            JSON.stringify(a.project.files[o])
          )),
          delete a.project.files[o]);
      return "json" == e.type ? JSON.stringify(a) : a;
    }
  }),
  (Trans.prototype.compress = async function (e, t) {
    t = t || {};
    var n = Buffer.from([]),
      n = Buffer.isBuffer(e)
        ? e
        : "string" == typeof e
        ? Buffer.from(e)
        : "object" != typeof e || empty(e)
        ? Buffer.from(JSON.stringify(this.getSaveData()))
        : Buffer.from(JSON.stringify(e));
    return common.gzip(n, t);
  }),
  (Trans.prototype.uncompress = async function (e, t) {
    t = t || {};
    var n = Buffer.from([]);
    if (Buffer.isBuffer(e)) n = e;
    else {
      if ("string" != typeof e)
        return console.error(
          "Can not uncompress from data:",
          e,
          "Only buffer or string is accepted"
        );
      n = Buffer.from(e);
    }
    return common.gunzip(n, t);
  }),
  (Trans.prototype.from = async function (e) {
    var t,
      n = "";
    if (
      (Buffer.isBuffer(e)
        ? (n = (
            "31,139,8,0" == e.slice(0, 10).join(",")
              ? (n = await common.gunzip(e))
              : e
          ).toString())
        : "string" == typeof e && (n = e),
      n)
    ) {
      if (0 == JSON.isJSON(n)) return console.error("unknown format :", e);
      t = JSON.parse(n);
    }
    return t;
  }),
  (Trans.prototype.createBackup = async function (e) {
    var t = parseInt(sys.getConfig("backupLevel"));
    if (sys.getConfig("autoBackup") && t) {
      if (!(await common.isFileAsync(e)))
        return console.warn("no such file ", e);
      if (0 != [".trans", ".tpp"].includes(nwPath.extname(e).toLowerCase())) {
        await common.unlink(e + `.${t}.bak`);
        for (var n = t - 1; 0 <= n; n--)
          0 == n
            ? await common.rename(e, e + `.${n + 1}.bak`)
            : 0 != (await common.isFileAsync(e + `.${n}.bak`)) &&
              (await common.rename(e + `.${n}.bak`, e + `.${n + 1}.bak`));
      }
    }
  }),
  (Trans.prototype.saveAs = async function (e, t) {
    e = await ui.saveAs(e || trans.currentFile || "");
    return console.log("Saving into : ", e), e ? this.save(e, t) : "";
  }),
  (Trans.prototype.save = async function (r, o) {
    if (!(r = r || this.currentFile)) return this.saveAs(r, o);
    var a = this;
    if (
      (((o = o || {}).initiator = o.initiator || "user"),
      (o.filter = o.filter || []),
      (o.onAfterLoading = o.onAfterLoading || function (e, t) {}),
      (o.onSuccess = o.onSuccess || function (e, t) {}),
      (o.onFailed = o.onFailed || function (e, t) {}),
      a.isSavingFile)
    )
      return console.warn(
        "Trans.prototype.save() is busy! Please wait until the previous save procedure to be completed before triggering another one!"
      );
    console.log("Saving data to : " + r);
    var i = a.getSaveData(o);
    return (
      console.log(i),
      (a.isSavingFile = !0),
      ui.saveIndicatorStart(),
      "user" == o.initiator && (await this.createBackup(r)),
      new Promise((t, n) => {
        fs.writeFile(r, JSON.stringify(i), (e) => {
          e
            ? ("function" == typeof o.onFailed && o.onFailed.call(a, i, r),
              ui.saveIndicatorEnd(),
              console.warn("Failed to save to : ", r, e),
              n())
            : ("auto" !== o.initiator &&
                (console.log(r + " successfully saved!"),
                sys.insertOpenedFileHistory(
                  r,
                  i.project.projectId,
                  i.project.gameTitle,
                  o.initiator
                ),
                (this.currentFile = r),
                a.gridIsModified(!1),
                ui.setWindowTitle()),
              "function" == typeof o.onSuccess && o.onSuccess.call(a, i, r),
              t(r)),
            o.onAfterLoading.call(a, i, r),
            setTimeout(function () {
              ui.saveIndicatorEnd();
            }, 1e3),
            (a.isSavingFile = !1);
        });
      })
    );
  }),
  (Trans.prototype.generateCachePath = function () {
    (this.project.cache = this.project.cache || {}),
      (this.project.cache.cacheID =
        this.project.cache.cacheID || this.project.projectId),
      this.project.cache.cacheID ||
        (this.project.cache.cacheID = this.project.projectId =
          common.makeid(10)),
      console.log(
        "Joining",
        sys.config.stagingPath,
        this.project.cache.cacheID
      ),
      (this.project.cache.cachePath =
        this.project.cache.cachePath ||
        nwPath.join(sys.config.stagingPath, this.project.cache.cacheID));
    try {
      fs.mkdirSync(this.project.cache.cachePath, { recursive: !0 });
    } catch (e) {
      console.warn(e);
    }
  }),
  (Trans.prototype.autoSave = async function (e) {
    if (((e = e || {}), void 0 === this.project))
      return (
        (e.onSuccess = e.onSuccess || function () {}),
        e.onSuccess.call(this),
        !1
      );
    try {
      (this.project.cache.cachePath &&
        common.isDir(this.project.cache.cachePath)) ||
        this.generateCachePath();
    } catch (e) {
      console.warn(e);
    }
    e.initiator = "auto";
    var t = nwPath.join(this.project.cache.cachePath, "autosave.json");
    return await this.save(t, e), t;
  }),
  (Trans.prototype.buildIndexFromData = function (e, t) {
    if ("object" != typeof e) return console.warn("fileData is not an object");
    if (0 == Array.isArray(e.data))
      return console.warn("fileData.data is not a valid array");
    if (!e.indexIsBuilt || t) {
      (e.data = e.data || []), (e.indexIds = e.indexIds || {});
      for (var n = 0; n < e.data.length; n++) {
        var r = e.data[n];
        r[0] && (e.indexIds[r[0]] = n);
      }
      e.indexIsBuilt = !0;
    }
    return e;
  }),
  (Trans.prototype.mergeTrans = function (e, t, n) {
    ((t = t || this).project = t.project || {}),
      (t.project.files = t.project.files || {}),
      ((e = e || {}).project = e.project || {}),
      (e.project.files = e.project.files || {}),
      ((n = n || {}).overwrite = n.overwrite || !1),
      (n.targetPair = n.targetPair || {}),
      (n.files = n.files || []),
      (n.all = n.all || !1),
      n.all && (n.targetPair = e.project.files);
    var r,
      o = !1;
    for (r in ((t = this.sanitize(t)) instanceof Trans && (o = !0),
    console.log("running mergeTrans with args : ", arguments),
    n.targetPair)) {
      var a = e.project.files[r],
        i = t.project.files[r];
      if (i) {
        if (
          (console.log("merging data", r),
          0 != Array.isArray(a.data) && 0 != a.data.length)
        ) {
          this.buildIndexFromData(i),
            (i.context = i.context || []),
            (a.context = a.context || []);
          for (var s = 0; s < a.data.length; s++) {
            var l,
              c = a.data[s];
            0 != Boolean(c[0]) &&
              (void 0 === (l = i.indexIds[c[0]]) && (l = i.data.length),
              (i.data[l] = common.clone(c)),
              (i.context[l] = common.clone(a.context[s])));
          }
        }
      } else
        (t.project.files[r] = common.clone(a)),
          o && this.addFileItem(r, t.project.files[r]);
    }
    return (
      o &&
        (this.generateHeader(t),
        this.evalTranslationProgress(),
        ui.fileList.reIndex(),
        ui.initFileSelectorDragSelect()),
      this.refreshGrid(),
      t
    );
  }),
  (Trans.prototype.loadJSONSync = function (t, e) {
    if ("" == t || null == t || void 0 === t) return !1;
    ((e = e || {}).onAfterLoading = e.onAfterLoading || function (e, t) {}),
      (e.onSuccess = e.onSuccess || function (e, t) {}),
      (e.onFailed = e.onFailed || function (e, t) {});
    (e = require("fs").readFileSync(t).toString()), (t = !1);
    try {
      return (t = JSON.parse(e));
    } catch (e) {
      return t;
    }
  }),
  (Trans.prototype.loadJSON = async function (t, e) {
    if ("" == t || null == t || void 0 === t) return !1;
    ((e = e || {}).onAfterLoading = e.onAfterLoading || function (e, t) {}),
      (e.onSuccess = e.onSuccess || function (e, t) {}),
      (e.onFailed = e.onFailed || function (e, t) {}),
      (this.isOpeningFile = !0),
      ui.showBusyOverlay();
    try {
      var n = await common.fileGetContents(t, "utf8", !1),
        r = JSON.parse(n);
    } catch (e) {
      alert("Error loading file: " + t);
    }
    return ui.hideBusyOverlay(), (this.isOpeningFile = !1), r;
  }),
  (Trans.prototype.importFromFile = async function (e, n) {
    ((n = n || {}).overwrite = n.overwrite || !1),
      (n.targetPair = n.targetPair || {}),
      (n.files = n.files || []),
      (n.mergeData = n.mergeData || !1);
    var r = this,
      o = this.isTrans(e)
        ? e
        : ((o = await r.loadJSON(e)), r.validateTransData(o));
    if (n.mergeData) r.mergeTrans(o, r, n);
    else {
      for (var a in n.targetPair) {
        "string" != typeof n.targetPair[a] && (n.targetPair[a] = a);
        try {
          "undefined" !== o.project.references[a] &&
            (r.project.files[n.targetPair[a]] = o.project.references[a]),
            void 0 !== o.project.files[a] &&
              ((r.project.files[n.targetPair[a]] = o.project.files[a]),
              console.log(
                t("create file list"),
                n.targetPair[a],
                r.project.files[n.targetPair[a]]
              ),
              r.addFileItem(n.targetPair[a], r.project.files[n.targetPair[a]]));
        } catch (e) {
          console.log(e);
          continue;
        }
      }
      ui.initFileSelectorDragSelect(),
        r.evalTranslationProgress(),
        ui.fileList.reIndex(),
        r.refreshGrid();
    }
  }),
  (Trans.prototype.selectCell = function (e, t) {
    return this.grid.selectCell(e, t);
  }),
  (Trans.prototype.getProjectChecksum = function () {
    if (!this.project.checksum) {
      var e,
        t = [],
        n = this.getAllFiles();
      for (e in (n.sort(), n)) {
        var r = this.project.files[n[e]];
        if (!empty(r) && !empty(r.data) && "*" != r.dirname) {
          for (var o = [], a = 0; a < r.data.length; a++)
            r.data[a][this.keyColumn] && o.push(r.data[a][this.keyColumn]);
          o.length < 1 ||
            (o.sort(), t.push(common.crc32String(JSON.stringify(o))));
        }
      }
      this.project.checksum = common.crc32String(JSON.stringify(t));
    }
    return this.project.checksum;
  }),
  (Trans.prototype.exportTPP = function (n, r) {
    if (void 0 === n) return !1;
    ((r = r || {}).showDetail = r.showDetail || !1),
      (r.onDone = r.onDone || function () {});
    for (
      var e = [],
        o = $(".fileList .data-selector .fileCheckbox:checked"),
        a = 0;
      a < o.length;
      a++
    )
      e.push(o.eq(a).attr("value"));
    (r.files = r.files || e || []),
      ui.saveIndicatorStart(),
      trans.autoSave({
        onSuccess: function () {
          php.spawn("saveTpp.php", {
            args: {
              path: n,
              password: r.password,
              gameFolder: trans.gameFolder,
              gameTitle: trans.gameTitle,
              projectId: trans.projectId,
              gameEngine: trans.gameEngine,
              files: r.files,
              exportMode: r.mode,
              rpgTransFormat: trans.config.rpgTransFormat,
            },
            onData: function (e) {
              r.showDetail &&
                ui.loadingProgress(t("Loading"), e, {
                  consoleOnly: !0,
                  mode: "consoleOutput",
                });
            },
            onError: function (e) {
              r.showDetail &&
                ui.loadingProgress(t("Loading"), e, {
                  consoleOnly: !0,
                  mode: "consoleOutput",
                  classStr: "stderr",
                });
            },
            onDone: function (e) {
              r.showDetail &&
                (ui.loadingProgress(t("Finished"), t("All process finished!"), {
                  consoleOnly: !1,
                  mode: "consoleOutput",
                }),
                ui.showCloseButton(),
                ui.log.addButtons(t("Open Explorer"), function () {
                  common.openExplorer(n);
                })),
                ui.saveIndicatorEnd(),
                r.onDone.call(trans, e);
            },
          });
        },
      });
  }),
  (Trans.prototype.importTpp = async function (e, r) {
    if (void 0 === e) return !1;
    (r = r || {}).onDone = r.onDone || function () {};
    var n = sys.getConfig("stagingPath");
    (await common.isDir(n)) || (await common.mkDir(n));
    trans.closeProject(),
      trans.autoSave({
        onSuccess: function () {
          ui.showLoading(),
            php.spawn("loadTpp.php", {
              args: { path: e, password: r.password },
              onData: function (e) {
                ui.loadingProgress(t("Loading"), e, {
                  consoleOnly: !0,
                  mode: "consoleOutput",
                });
              },
              onError: function (e) {
                ui.loadingProgress(t("Loading"), e, {
                  consoleOnly: !0,
                  mode: "consoleOutput",
                  classStr: "stderr",
                });
              },
              onDone: function (e) {
                console.log("done");
                var n = $(".console").find("output.cachepath").text(),
                  n = nwPath.join(n, "autosave.json");
                console.log("new cache path : ", n),
                  ui.loadingProgress(t("Loading"), t("Opening file!"), {
                    consoleOnly: !1,
                    mode: "consoleOutput",
                  }),
                  trans.open(n, {
                    onSuccess: function () {
                      (trans.project.cache = trans.project.cache || {}),
                        (trans.project.cache.cachePath = nwPath.dirname(n)),
                        ui.loadingProgress(
                          t("Loading"),
                          t(
                            "Assigning new staging path : " +
                              trans.project.cache.cachePath
                          ),
                          { consoleOnly: !1, mode: "consoleOutput" }
                        ),
                        ui.loadingProgress(t("Loading"), t("Success!"), {
                          consoleOnly: !1,
                          mode: "consoleOutput",
                        }),
                        ui.loadingProgress(
                          t("Finished"),
                          t("All process finished!"),
                          { consoleOnly: !1, mode: "consoleOutput" }
                        ),
                        ui.showCloseButton(),
                        r.onDone.call(trans, e);
                    },
                    onFailed: function () {
                      ui.loadingProgress(t("Loading"), t("Failed!"), {
                        consoleOnly: !1,
                        mode: "consoleOutput",
                      }),
                        ui.loadingProgress(
                          t("Finished"),
                          t("All process finished!"),
                          { consoleOnly: !1, mode: "consoleOutput" }
                        ),
                        ui.showCloseButton(),
                        r.onDone.call(trans, e);
                    },
                  });
              },
            });
        },
      });
  }),
  (Trans.prototype.export = async function (e, t) {
    if (void 0 === e) return !1;
    ((t = t || {}).options = t.options || {}),
      console.log("Exporting with arguments:", arguments),
      (t.mode = t.mode || "dir"),
      (t.onDone = t.onDone || function () {}),
      (t.dataPath = t.dataPath || ""),
      (t.transPath = t.transPath || ""),
      (t.options.filterTag = t.options.filterTag || t.filterTag || []),
      (t.options.filterTagMode =
        t.options.filterTagMode || t.filterTagMode || ""),
      (t.custom = t.custom || t.options.custom),
      delete t.options.custom,
      console.log("exporting project", arguments);
    for (
      var n = [],
        r = $(".fileList .data-selector .fileCheckbox:checked"),
        o = 0;
      o < r.length;
      o++
    )
      n.push(r.eq(o).attr("value"));
    t.files = t.files || n || [];
    var a = trans.project.gameEngine;
    if (
      void 0 !== engines[a] &&
      "function" == typeof engines[a].exportHandler
    ) {
      var i = await engines[a].exportHandler.apply(this, arguments);
      if ((console.log("Is process halt?", i), i))
        return void (await this.projectHook.run("afterExport", t));
    }
    (!["csv", "xlsx", "xls", "ods", "html", "RPGMakerTrans"].includes(t.mode) &&
      "spreadsheet" != a) ||
      this.legacyExport(e, t),
      console.log("Export process is finished");
  }),
  (Trans.prototype.legacyExport = async function (e, n) {
    var r = await trans.autoSave(),
      o =
        (ui.log.show(),
        await ui.log(
          "Exporting project to " + n.mode + " format with legacy mode"
        ),
        (trans.project.options = trans.project.options || {}),
        (trans.project.options.init = trans.project.options.init || {}),
        Object.assign(trans.project.options.init, n.options));
    php.spawn("export.php", {
      args: {
        path: e,
        gameFolder: trans.gameFolder,
        gameTitle: trans.gameTitle,
        projectId: trans.projectId,
        gameEngine: trans.gameEngine,
        files: n.files,
        exportMode: n.mode,
        options: o,
        rpgTransFormat: trans.config.rpgTransFormat,
        dataPath: n.dataPath,
        transPath: nwPath.resolve(n.transPath || r),
      },
      onData: function (e) {
        ui.loadingProgress(t("Loading"), e, {
          consoleOnly: !0,
          mode: "consoleOutput",
        });
      },
      onError: function (e) {
        ui.loadingProgress(t("Loading"), e, {
          consoleOnly: !0,
          mode: "consoleOutput",
          classStr: "stderr",
        });
      },
      onDone: async (e) => {
        console.log("done"),
          ui.loadingProgress(t("Finished"), t("All process finished!"), {
            consoleOnly: !1,
            mode: "consoleOutput",
          }),
          await this.projectHook.run("afterExport", n),
          ui.loadingEnd(),
          n.onDone.call(trans, e);
      },
    });
  }),
  (Trans.prototype.revertToOriginal = async function (e, t = {}) {
    var n = require("better-copy");
    if (
      ((e = e || (await ui.openRevertToOriginalDialog())),
      (t.dataPath = t.dataPath || "data"),
      e)
    ) {
      ui.showLoading(), ui.loadingProgress(0, "Reverting original data");
      var r,
        o = this.project.files,
        a =
          (0 < this.getCheckedFiles().length && (o = this.getCheckedObjects()),
          0),
        i = 0,
        s = Object.keys(o).length || 1;
      for (r in (ui.log(`Processing ${s} file(s)`), o)) {
        i++;
        var l = this.getStagingDataPath(),
          c = this.getStagingFile(o[r]),
          d = common.getRelativePath(c, l);
        await ui.loadingProgress(Math.round((i / s) * 100), "Reverting : " + d),
          (await common.isFileAsync(c))
            ? (await ui.log(i + `/${s} Copying : ` + c),
              await n(c, nwPath.join(e, d), { overwrite: !0 }),
              a++)
            : await ui.log("File not found: " + c);
      }
      await ui.log(`Completed! ${a} file(s) reverted to original!`),
        ui.log.addButtons(
          "Open folder",
          function () {
            nw.Shell.showItemInFolder(nwPath.join(e, d));
          },
          { class: "icon-folder-open" }
        ),
        ui.loadingEnd();
    }
  }),
  (Trans.prototype.importSheet = async function (n, o, a) {
    (o = o || 1),
      ((a = a || {}).sourceColumn = a.sourceColumn || "auto"),
      (a.overwrite = a.overwrite || !1),
      (a.files = a.files || trans.getCheckedFiles() || []),
      (a.sourceKeyColumn = a.sourceKeyColumn || 0),
      (a.keyColumn = a.keyColumn || 0),
      (a.newLine = a.newLine || void 0),
      (a.stripCarriageReturn = a.stripCarriageReturn || !1),
      (a.ignoreNewLine = !0),
      console.log("trans.importSheet"),
      console.log(arguments),
      0 == Array.isArray(n) && (n = [n]),
      ui.showLoading(),
      ui.loadingProgress(0, t("Collecting paths"), {
        consoleOnly: !0,
        mode: "consoleOutput",
      }),
      ui.log("Building indexes"),
      0 == a.files?.length && (a.files = this.getAllFiles()),
      (a.indexes = this.buildIndexes(a.files, !1, { stripCarriageReturn: !0 }));
    var r,
      i = [];
    for (let e = 0; e < n.length; e++) {
      var s,
        l = n[e];
      0 == common.isExist(l)
        ? (ui.loadingProgress(0, t("Path : '") + l + t("' doesn't exist"), {
            consoleOnly: !0,
            mode: "consoleOutput",
          }),
          console.log("Error, path not exist"))
        : common.isDir(l)
        ? ((s = common.dirContentSync(l)), (i = i.concat(s)))
        : i.push(l);
    }
    ui.loadingProgress(0, i.length + t(" file(s) collected!"), {
      consoleOnly: !0,
      mode: "consoleOutput",
    }),
      ui.loadingProgress(0, t("Start importing data!"), {
        consoleOnly: !0,
        mode: "consoleOutput",
      }),
      (r = common.parseSheet
        ? (ui.log("Import using sheet parser add-on"),
          async function (e) {
            var t,
              n = await common.parseSheet(e),
              r = [];
            for (t in n)
              console.log("Merging data", n[t]),
                n[t] && n[t].length && (r = r.concat(n[t]));
            console.log("output data :"),
              console.log(r),
              trans.translateFromArray(r, o, a);
          })
        : (ui.log("Import using legacy sheet importer"),
          function (e) {
            (e = e || l),
              php.spawnSync("import.php", {
                args: {
                  path: e,
                  output: null,
                  mergeSheet: !0,
                  prettyPrint: !0,
                },
                onDone: function (e) {
                  console.log("output data :"),
                    console.log(e),
                    trans.translateFromArray(e, o, a);
                },
              });
          }));
    for (let e = 0; e < i.length; e++) {
      var c = i[e];
      ui.loadingProgress(
        Math.round((e / i.length) * 100),
        t("Importing : ") + c,
        { consoleOnly: !0, mode: "consoleOutput" }
      ),
        await r(c),
        ui.loadingProgress(Math.round(((e + 1) / i.length) * 100), t("Done!"), {
          consoleOnly: !0,
          mode: "consoleOutput",
        });
    }
    trans.refreshGrid(),
      trans.evalTranslationProgress(),
      ui.loadingProgress(t("Done!"), t("All Done!"), {
        consoleOnly: !0,
        mode: "consoleOutput",
      }),
      ui.loadingEnd();
  }),
  (Trans.prototype.importRPGMTrans = function (e, n, r) {
    (n = n || 1),
      ((r = r || {}).sourceColumn = r.sourceColumn || "auto"),
      (r.overwrite = r.overwrite || !1),
      (r.files = r.files || trans.getCheckedFiles() || []),
      (r.sourceKeyColumn = r.sourceKeyColumn || 0),
      (r.keyColumn = r.keyColumn || 0),
      (r.newLine = r.newLine || void 0),
      (r.stripCarriageReturn = r.stripCarriageReturn || !1),
      (r.ignoreNewLine = !0),
      console.log("trans.importRPGMTrans"),
      console.log(arguments),
      0 == Array.isArray(e) && (e = [e]),
      ui.showLoading(),
      ui.loadingProgress(0, t("Collecting paths"), {
        consoleOnly: !0,
        mode: "consoleOutput",
      });
    for (var o = [], a = 0; a < e.length; a++) {
      var i,
        s = e[a];
      0 == common.isExist(s)
        ? (ui.loadingProgress(0, t("Path : '") + s + t("' doesn't exist"), {
            consoleOnly: !0,
            mode: "consoleOutput",
          }),
          console.log("Error, path not exist"))
        : common.isDir(s)
        ? ((i = common.dirContentSync(s)), (o = o.concat(i)))
        : o.push(s);
    }
    ui.loadingProgress(0, o.length + t(" file(s) collected!"), {
      consoleOnly: !0,
      mode: "consoleOutput",
    }),
      ui.loadingProgress(0, t("Start importing data!"), {
        consoleOnly: !0,
        mode: "consoleOutput",
      });
    for (let e = 0; e < o.length; e++) {
      var l = o[e];
      ui.loadingProgress(
        Math.round((e / o.length) * 100),
        t("Importing : ") + l,
        { consoleOnly: !0, mode: "consoleOutput" }
      ),
        (l = (l = l) || s),
        php.spawnSync("parseTrans.php", {
          args: { path: l, prettyPrint: !0 },
          onDone: function (e) {
            console.log("output data :"),
              console.log(e),
              Array.isArray(e.data) && trans.translateFromArray(e.data, n, r);
          },
        }),
        ui.loadingProgress(Math.round(((e + 1) / o.length) * 100), t("Done!"), {
          consoleOnly: !0,
          mode: "consoleOutput",
        });
    }
    trans.refreshGrid(),
      trans.evalTranslationProgress(),
      ui.loadingProgress(t("Done!"), t("All Done!"), {
        consoleOnly: !0,
        mode: "consoleOutput",
      }),
      ui.loadingEnd();
  }),
  (Trans.prototype.clearFooter = function () {
    $(".footer .footer1 span").html(""),
      $(".footer .footer2 span").html(""),
      $(".footer .footer3 span").html(""),
      $(".footer .footer4 span").html(""),
      $(".footer .footer5 span").html("");
  }),
  (Trans.prototype.setStatusBarContext = function (e) {
    void 0 === e &&
      Array.isArray(trans.grid.getSelected()) &&
      (e = trans.grid.getSelected()[0][0]);
    var t = trans.getSelectedId();
    try {
      "> ANTI TES PATCH FILE VERSION 0.2" ==
        trans.project.files[t].originalFormat &&
      "rmrgss" !== this.project.parser
        ? $(".footer .footer1>span").html(
            trans.buildContextFromParameter(
              trans.project.files[t].parameters[e]
            )
          )
        : $(".footer .footer1>span").html(
            trans.project.files[t].context[e].join("; ")
          ),
        $(".footer .footer1>span").addClass("icon-th-2");
    } catch (e) {
      $(".footer .footer1>span").html(""),
        $(".footer .footer1>span").removeClass("icon-th-2");
    }
  }),
  (Trans.prototype.setStatusBarNumData = function () {
    if (void 0 === trans.project) return !1;
    try {
      $(".footer .footer3 span").html(
        "rows : " + trans.project.files[trans.getSelectedId()].data.length
      );
    } catch (e) {
      $(".footer .footer3 span").html("");
    }
  }),
  (Trans.prototype.setStatusBarEngine = function () {
    if (void 0 === trans.project) return !1;
    try {
      var e = "";
      trans.project.parser &&
        (e = `/<span title='parser'>${trans.project.parser}</span>`),
        $(".footer .footer4 span").html(trans.project.gameEngine + e);
    } catch (e) {
      $(".footer .footer4 span").html("");
    }
  }),
  (Trans.prototype.setTrayIcon = function (e) {
    e = e || "translatorPlusPlus";
    var t = $('<i class="icon trayIcon"></i>');
    t.addClass(e), $(".footer .footer5 span").html(t);
  }),
  (Trans.prototype.goToNewKey = function () {
    if (0 == Array.isArray(this.data)) return !1;
    this.grid.scrollViewportTo(this.data.length - 1),
      this.grid.selectCell(this.data.length - 1, 0);
  }),
  (Trans.prototype.clearEditor = function () {
    var e = $("#currentCellText");
    return (
      e.val(""),
      e.prop("readonly", !0),
      e.data("column", null),
      e.data("row", null),
      !0
    );
  }),
  (Trans.prototype.clearCellInfo = function () {
    return $("#currentCoordinate").val(""), !0;
  }),
  (Trans.prototype.setCellInfo = function (e, t) {
    $("#currentCoordinate").val(e + 1 + "," + (t + 1)),
      (trans.lastSelectedCell = [e, t]);
  }),
  (Trans.prototype.drawCellEmblem = function () {
    var e = this.lastSelectedCell[0],
      t = this.lastSelectedCell[1];
    $(".cellEmblems > i").addClass("hidden"),
      t != this.keyColumn &&
        ($(".cellEmblems > .emblemComment").attr("title", ""),
        this.isOrganicCell(e, t) &&
          $(".cellEmblems > .emblemOrganic").removeClass("hidden"),
        (this.isVisitedCell(e, t)
          ? $(".cellEmblems > .emblemFootprint")
          : $(".cellEmblems > .emblemFirstVisit")
        ).removeClass("hidden"),
        (e = this.getCellComment(e, t))) &&
        ($(".cellEmblems > .emblemComment").removeClass("hidden"),
        $(".cellEmblems > .emblemComment").attr(
          "title",
          "<b>Cell comment:</b><br />" + e
        ));
  }),
  (Trans.prototype.connectData = function () {
    return this.getSelectedId() && this.project.files[this.getSelectedId()].data
      ? void (this.project.files[this.getSelectedId()].data = trans.data)
      : console.warn("unable to connect data with selected id");
  }),
  (Trans.prototype.isLastRow = function (e) {
    return (
      0 == Boolean(trans.data) && ((trans.data = []), trans.connectData()),
      (e = e || 0) == trans.data.length - 1
    );
  }),
  (Trans.prototype.getCurrentData = function () {
    return this.data;
  }),
  (Trans.prototype.getTextFromLastSelected = function () {
    var e = this.getCurrentData();
    return empty(this.lastSelectedCell)
      ? ""
      : e[this.lastSelectedCell[0]][this.lastSelectedCell[1]];
  }),
  (Trans.prototype.textEditorSetValue = function (e, t = !1) {
    $("#currentCellText").val(e),
      ui.generateBackgroundNumber(),
      t && $("#currentCellText").trigger("change");
  }),
  (Trans.prototype.doAfterSelection = function (e, t, n, r) {
    var o = $("#currentCellText"),
      a = (o.val(trans.data[e][t]), o.prop("readonly", !1), trans.isLastRow(e));
    if (
      (0 == t && 0 == a && o.prop("readonly", !0),
      o.data("column", t),
      o.data("row", e),
      trans.setCellInfo(e, t),
      trans.setStatusBarContext(e),
      trans.translateSelectedRow(e),
      ui.generateBackgroundNumber(o),
      "undefined" != typeof romaji)
    ) {
      if (0 == trans.config.loadRomaji) return !0;
      romaji.resolve(trans.data[e][0], $("#currentRomaji .text"));
    }
    $("#currentRomaji .header").text(this.getRowInfoText(e, !0) || ""),
      this.drawCellEmblem(),
      this.getOption("gridInfo")?.isRuleActive &&
        this.getOption("gridInfo")?.enableTrail &&
        (this._cellInfoTrack && clearTimeout(this._cellInfoTrack),
        t != this.keyColumn) &&
        this.getText(e, t) &&
        (this._cellInfoTrack = setTimeout(() => {
          clearTimeout(this._cellInfoTrack),
            (this._cellInfoTrack = void 0),
            console.log("Setting cellInfo", "v", 1, this.getSelectedId(), e, t),
            this.cellInfo.set("v", 1, this.getSelectedId(), e, t),
            $(`table tbody td[data-coord="${e}-${t}"]`).addClass("viewed");
        }, 1e3)),
      (this.getSelectedObject().lastSelectedCell = [e, t]),
      this.trigger("onAfterSelectCell", {
        fromRow: e,
        fromCol: t,
        toRow: n,
        toCol: r,
        isLastRow: a,
      });
  }),
  (Trans.prototype.resetCurentCellEditor = function () {
    var e = $("#currentCellText");
    e.val(""),
      e.data("row", 0),
      e.data("column", 0),
      trans.setCellInfo(0, 0),
      trans.setStatusBarContext(0),
      $("#currentRomaji .text").text(""),
      $("#currentRomaji .header").text("");
  }),
  (Trans.prototype.createFile = function (e, n, r) {
    ((r = r || {}).originalFormat = r.originalFormat || ""),
      (r.type = r.type || null);
    var o = require("is-valid-path");
    return (
      (n = n || "/"),
      o(e)
        ? o(n) || "*" === n
          ? ((o = nwPath.join("/", n, e)),
            this.getObjectById(o)
              ? { error: !0, msg: o + t(" is already exist") }
              : ((r =
                  "*" == n
                    ? ((o = e),
                      (r.type = r.type || "reference"),
                      this.createFileData(o, {
                        originalFormat:
                          r.originalFormat || "TRANSLATOR++ GENERATED TABLE",
                        type: r.type,
                        dirname: "*",
                      }))
                    : ((o = o.replace(/\\/g, "/")),
                      this.createFileData(o, {
                        originalFormat: r.originalFormat,
                        type: r.type,
                      }))),
                (trans.project.files[o] = r),
                trans.addFileItem(o, r),
                this.evalTranslationProgress(),
                ui.fileList.reIndex(),
                ui.initFileSelectorDragSelect(),
                {}))
          : { error: !0, msg: n + t(" is not a valid directory name") }
        : { error: !0, msg: e + t(" is not a valid object name") }
    );
  }),
  (Trans.prototype.selectFile = function (e, t) {
    ((t = t || {}).onDone = t.onDone || void 0), this.grid.deselectCell();
    t = (e =
      "string" == typeof e
        ? $(".fileList [data-id=" + common.escapeSelector(e) + "]")
        : e)
      .closest("li")
      .data("id");
    return (
      this.trigger("beforeSelectFile", [trans?.project?.selectedId, t]),
      e.closest(".tree").find("li").removeClass("selected"),
      e.closest("li").addClass("selected"),
      (trans.project.selectedId = t),
      (trans.data = trans.project.files[t].data),
      (trans.selectedData = trans.project.files[t]),
      trans.buildIndex(),
      trans.clearCellInfo(),
      trans.clearEditor(),
      trans.setStatusBarNumData(),
      trans.resetCurentCellEditor(),
      $(".menu-button.addNote").hasClass("checked") && ui.openFileNote(),
      $(".fileId").val(t),
      ui.disableGrid(!1),
      ui.evalFileNoteIcon(),
      this.trigger("objectSelected", t),
      this.grid.loadData(trans.data),
      trans.loadComments(),
      trans.renderGridInfo(),
      trans.grid.setFixedTableHeightByData(trans.data),
      trans.grid.scrollViewportTo(0, 0),
      e
    );
  }),
  (Trans.prototype.renderGridInfo = function () {
    var e = this.getOption("gridInfo") || {};
    e?.isRuleActive && e?.rowHeaderInfo
      ? ((e = e.rowHeaderWidth || 130),
        trans.grid.updateSettings({ rowHeaderWidth: e }),
        $("#table").css("--row-header-width", e + "px"))
      : (trans.grid.updateSettings({ rowHeaderWidth: null }),
        (e = $('#table [data-role="tablecorner"]').outerWidth()),
        $("#table").css("--row-header-width", e + "px"));
  }),
  (Trans.prototype.addFileGroup = function (e, t) {
    return (
      $("#fileList [data-group='" + CSS.escape(e) + "']").length < 1 &&
      ((e = $(
        "<li class='group-header'  data-group='" + e + "'>" + e + "</li>"
      )),
      0 < $("#fileList .fileListUl .group-header[data-group='*']").length
        ? $("#fileList .fileListUl .group-header[data-group='*']").before(e)
        : $("#fileList .fileListUl").append(e),
      !0)
    );
  }),
  (Trans.prototype.fileItemExist = function (e, t) {
    return (
      0 <
      $(
        "#fileList [data-group='" +
          CSS.escape(t.dirname) +
          "'][data-id='" +
          CSS.escape(e) +
          "']"
      ).length
    );
  }),
  (Trans.prototype.drawFileStatus = function (o) {
    "string" == typeof o && (o = [o]);
    for (var a = $("#fileList"), i = 0; i < o.length; i++)
      (() => {
        var e,
          t = o[i],
          n = this.getObjectById(t),
          r = a.find(`[data-id="${CSS.escape(o[i])}"]`);
        0 != r.length &&
          (r.removeClass("isCompleted"),
          r.removeClass("isRequireAttention"),
          n.isCompleted && r.addClass("isCompleted"),
          n.isRequireAttention && r.addClass("isRequireAttention"),
          r.data("noteTooltipIsActive") &&
            (r.tooltip("destroy"), r.data("noteTooltipIsActive", !1)),
          (t = r.find(".markers")).empty(),
          n.note) &&
          (t.append($('<span class="hidden"></span>').text(n.note)),
          (e = $('<i class="icon-commenting"></i>')),
          t.append(e),
          n.noteColor && e.css("color", n.noteColor),
          r.tooltip({
            content: function () {
              var e = $("<div class='fileObjTooltipWindow'></div>");
              return (
                n.noteColor &&
                  (e.css("border-left-color", n.noteColor),
                  e.addClass("hasColor")),
                e.text(n.note),
                e.on("mouseenter", function () {
                  ui.fileObjectTooltip.open(e.clone(), r);
                }),
                e
              );
            },
            tooltipClass: "fileObjTooltipWrapper",
            show: { effect: "fade", duration: 100 },
            hide: { effect: "none", delay: 100 },
            position: { my: "left top", at: "right+6 top-16", of: r },
            open: function (e, t) {},
          }),
          r.data("noteTooltipIsActive", !0));
      })();
  }),
  (Trans.prototype.addFileItem = function (e, t) {
    if (this.fileItemExist(e, t)) return !1;
    this.addFileGroup(t.dirname);
    var n = $("<li></li>");
    n.append(
      "<input type='checkbox' class='fileCheckbox' title='hold shift for bulk selection' /><a href='#' class='filterable'><span class='filename'></span><span class='markers'></span><span class='percent' title='progress'></span><div class='progress' title='progress'></div></a>"
    ),
      n.attr("title", e),
      n.attr("data-group", t.dirname),
      n.find(".fileCheckbox").attr("value", e),
      n.find(".filename").text(t.filename),
      n.addClass("data-selector"),
      n.data("id", e),
      n.attr("data-id", e),
      n.find("a").on("mousedown", function (e) {
        if (2 == e.which) return e.preventDefault(), trans.clearSelection(), !1;
      }),
      n.find("a").on("dblclick", function (e) {
        var t = $(this).closest("li").find(".fileCheckbox");
        t.prop("checked", !t.prop("checked")).trigger("change");
      }),
      n.find("a").on("click", function (e) {
        e.preventDefault(), trans.selectFile($(this).closest("li"));
      }),
      n.find(".fileCheckbox").on("change", function () {
        1 == $(this).prop("checked")
          ? ((trans.$lastCheckedFile = $(this)),
            $(this).closest(".data-selector").addClass("hasCheck"))
          : ((trans.$lastCheckedFile = void 0),
            $(this).closest(".data-selector").removeClass("hasCheck"));
      }),
      n.find(".fileCheckbox").on("mousedown", function (e) {
        if (
          (console.log("mouse down", console.log($(this).closest("li"))),
          (async () => {
            await common.wait(200),
              $(this).closest("li").removeClass("ds-hover");
          })(),
          !trans.$lastCheckedFile)
        )
          return !1;
        if (e.shiftKey) {
          console.log("The SHIFT key was pressed!");
          var t,
            n = $(".fileList .fileCheckbox"),
            e = n.index(trans.$lastCheckedFile),
            r = n.index(this),
            o = e < r ? ((t = e), r) : ((t = r), e);
          console.log("check from index " + t + " to " + o);
          for (var a = t; a < o; a++)
            n.eq(a).prop("checked", !0).trigger("change");
        }
      }),
      $("#fileList [data-group='" + CSS.escape(t.dirname) + "']")
        .last()
        .after(n);
  }),
  (Trans.prototype.drawFileSelector = function () {
    if (void 0 === this.project.files) return !1;
    for (var e in ($("#fileList .fileListUl").empty(),
    this.generateNewDictionaryTable(),
    this.project.files))
      this.addFileItem(e, this.project.files[e]);
    this.drawFileStatus(this.getAllFiles()),
      this.setStatusBarEngine(),
      this.evalTranslationProgress(),
      ui.fileList.reIndex(),
      ui.initFileSelectorDragSelect(),
      ui.enableButtons(),
      this.renderGridInfo();
    var t = require("www/js/TranslationByContext.js");
    (ui.translationByContext = new t()),
      ui.ribbonMenu.select("home"),
      (this.inProject = !0),
      engines.current().triggerHandler("onLoadTrans", this, arguments),
      this.initLocalStorage(),
      this.trigger("onLoadTrans");
  }),
  (Trans.prototype.initLocalStorage = async function () {
    var e = trans?.project?.projectId || "global";
    this.localStorage = new (require("better-localstorage"))("tp" + e);
  }),
  (Trans.prototype.unInitLocalStorage = async function () {
    "function" == typeof this.localStorage?.db?.close &&
      (await this.localStorage.db.close()),
      (this.localStorage = void 0);
  }),
  (Trans.prototype.setMarkAsComplete = function (e, t) {
    (t = t || trans.getCheckedFiles()).length < 1 && (t = trans.getAllFiles());
    for (var n = 0; n < t.length; n++) {
      var r = t[n];
      this.getObjectById(r).isCompleted = e;
    }
    return this.drawFileStatus(t), !0;
  }),
  (Trans.prototype.selectAll = function (t, e) {
    (e = e || !1), "string" == typeof (t = t || []) && (t = [t]);
    var n = $("#fileList .fileCheckbox");
    0 == t.length
      ? n.each(function () {
          $(this).prop("checked", !0).trigger("change");
        })
      : (e || n.prop("checked", !1).trigger("change"),
        n.each(function () {
          var e = $(this);
          t.includes(e.closest("li").data("id")) &&
            e.prop("checked", !0).trigger("change");
        }));
  }),
  (Trans.prototype.selectObjectsByFilter = function (t) {
    var e = $("#fileList .fileCheckbox");
    "function" == typeof t &&
      e.each(function () {
        var e = $(this);
        t(e.closest("li").data("id"), e) &&
          e.prop("checked", !0).trigger("change");
      });
  }),
  (Trans.prototype.invertSelection = function () {
    $("#fileList .fileCheckbox").each(function () {
      $(this).prop("checked", !$(this).prop("checked")).trigger("change");
    });
  }),
  (Trans.prototype.clearSelection = function () {
    $("#fileList .fileCheckbox").each(function () {
      $(this).prop("checked", !1).trigger("change");
    });
  }),
  (Trans.prototype.initFileNav = function () {
    console.log("running trans.initFileNav");
    try {
      void 0 !== trans.project.files
        ? (trans.fileListLoaded = !0)
        : (trans.fileListLoaded = !1);
    } catch (e) {
      trans.fileListLoaded = !1;
    }
    if (0 == trans.fileListLoaded)
      return (
        trans.createProject({
          onAfterLoading: function () {
            trans.drawFileSelector();
          },
        }),
        !1
      );
    this.unInitFileNav(),
      trans.drawFileSelector(),
      this.onFileNavLoaded.call(this),
      this.trigger("transLoaded", this);
  }),
  (Trans.prototype.unInitFileNav = function () {
    $("#fileList .fileListUl").empty(),
      ui.fileList.reIndex(),
      this.onFileNavUnloaded.call(this),
      engines.handler("onUnloadTrans").apply(this, arguments),
      ui.ribbonMenu.clear(),
      ui.disableButtons(),
      this.trigger("onUnloadTrans");
  }),
  (Trans.prototype.evalTranslationProgress = function (e, t) {
    e = e || [];
    var n,
      r = t || trans.countTranslated(e) || {};
    for (n in r) {
      var o = $(".fileList [data-id=" + common.escapeSelector(n) + "]");
      o.find(".percent").text(Math.round(r[n].percent)),
        o
          .find(".progress")
          .css(
            "background",
            "linear-gradient(to right, #3159f9 0%,#3159f9 " +
              r[n].percent +
              "%,#ff0004 " +
              r[n].percent +
              "%,#ff0004 100%)"
          );
    }
  }),
  (Trans.prototype.getStats = function (e) {
    var t = {
        files: 0,
        folders: 0,
        progress: 0,
        words: 0,
        characters: 0,
        rows: 0,
        rowTranslated: 0,
        percent: 0,
        organic: 0,
      },
      n = !1;
    if (this.project && this.project.files) {
      for (var r in (e ||
        (this.project.stats && ((n = !0), (t = this.project.stats))),
      this.project.files)) {
        var o = this.project.files[r];
        if (
          "TRANSLATOR++ GENERATED TABLE" != o.originalFormat &&
          (t.files++,
          o.progress &&
            ((t.rows += o.progress.length),
            (t.rowTranslated += o.progress.translated)),
          !n && !empty(o.data))
        )
          for (var a = 0; a < o.data.length; a++) {
            var i = o.data[a];
            empty(i) ||
              (i[this.keyColumn] &&
                ((t.characters += i[this.keyColumn].length),
                (t.words += i[this.keyColumn].trim().split(/\s+/).length),
                "HU" == this.cellInfo.getBestCellInfo(r, a, "t")) &&
                t.organic++);
          }
      }
      0 < t.rows && (t.percent = (t.rowTranslated / t.rows) * 100),
        (t.folders = $(".fileList  .group-header").length - 1),
        (t.organicPercent = (t.organic / t.rowTranslated) * 100),
        (this.stats = t);
    }
    return t;
  }),
  (Trans.prototype.setFileNoteColor = function (e, t) {
    for (var n in ((t ||= this.getSelectedId()),
    (t = 0 == Array.isArray(t) ? [t] : t))) {
      n = this.getObjectById(t[n]);
      e ? (n.noteColor = e) : n.noteColor && delete n.noteColor;
    }
    this.drawFileStatus(t), ui.evalFileNoteIcon();
  }),
  (Trans.prototype.setFileNote = function (e, t) {
    for (var n in ((t ||= this.getSelectedId()),
    (t = 0 == Array.isArray(t) ? [t] : t)))
      this.getObjectById(t[n]).note = e;
    this.drawFileStatus(t), ui.evalFileNoteIcon(), ui.fileList.reIndex();
  }),
  (Trans.prototype.loadComments = function () {
    trans.grid.comment = trans.grid.comment || trans.grid.getPlugin("comments");
    var e,
      t = trans.getSelectedObject();
    if (!t) return !1;
    if (void 0 === t.comments) return !1;
    for (e in t.comments)
      for (var n in t.comments[e])
        trans.grid.comment.setCommentAtCell(
          parseInt(e),
          parseInt(n),
          t.comments[e][n]
        );
  }),
  (Trans.prototype.runCustomScript = async function (e, n, r) {
    console.log("Running custom script with arguments:", arguments),
      (r = r || {});
    var o = new (require("www/js/CodeRunner.js"))(),
      a = await common.fileGetContents(n);
    if (!a) return alert(t("Error opening file :" + n));
    await ui.showBusyOverlay(), await common.wait(200);
    try {
      var i = await o.run(a, e, r);
      i && alert(i);
    } catch (e) {
      alert(t("Error executing :") + nwPath.basename(n) + "\n" + e.toString());
    }
    await ui.hideBusyOverlay();
  }),
  (Trans.prototype.updateRunScriptMenu = function () {
    console.log("Updating run script menu"),
      (this.fileSelectorMenu = this.fileSelectorMenu || {}),
      (this.fileSelectorMenu.withSelected.items.runScript.items.forEachRowRun.items =
        {});
    var a =
        this.fileSelectorMenu.withSelected.items.runScript.items.forEachRowRun
          .items,
      i = sys.getConfig("codeEditor/rowIterator");
    i || sys.setConfig("codeEditor/rowIterator", { quickLaunch: [] }),
      ((i ||= {}).quickLaunch ||= []);
    for (let n = 0; n < i.quickLaunch.length; n++)
      (() => {
        var r = i.quickLaunch[n],
          o = common.getFilename(r),
          e = common.generateId();
        a[e] = {
          name: o,
          callback: (e, n) => {
            confirm(
              t("Are you sure want to execute the following script?") + "\n" + o
            ) && this.runCustomScript("rowIterator", r);
          },
        };
      })();
    0 < Object.keys(a).length
      ? ((a.sep0 = "---------"),
        (a.clearQuickLaunch = {
          name: t("Clear quick launch"),
          icon: "context-menu-icon icon-trash",
          callback: (e, n) => {
            confirm(t("Are you sure want to clear quick launch?")) &&
              (sys.setConfig("codeEditor/rowIterator", { quickLaunch: [] }),
              sys.saveConfig(),
              this.updateRunScriptMenu());
          },
        }))
      : (a.howToAdd = {
          name: t("How to add Automation here"),
          icon: "context-menu-icon icon-help",
          callback: (e, t) => {
            nw.Shell.openExternal(
              "https://dreamsavior.net/docs/translator/execute-script/pin-your-automation-to-quickly-launch-from-translator/"
            );
          },
        }),
      (this.fileSelectorMenu.withSelected.items.runScript.items.forEachObjectRun.items =
        {});
    var s =
        this.fileSelectorMenu.withSelected.items.runScript.items
          .forEachObjectRun.items,
      l = sys.getConfig("codeEditor/objectIterator");
    l ||
      (sys.setConfig("codeEditor/objectIterator", { quickLaunch: [] }),
      (l = sys.getConfig("codeEditor/objectIterator"))),
      (l.quickLaunch = l.quickLaunch || []);
    for (let n = 0; n < l.quickLaunch.length; n++)
      (() => {
        var r = l.quickLaunch[n],
          o = common.getFilename(r),
          e = common.generateId();
        s[e] = {
          name: o,
          callback: (e, n) => {
            confirm(
              t("Are you sure want to execute the following script?") + "\n" + o
            ) && this.runCustomScript("objectIterator", r);
          },
        };
      })();
    0 < Object.keys(s).length
      ? ((s.sep0 = "---------"),
        (s.clearQuickLaunch = {
          name: t("Clear quick launch"),
          icon: "context-menu-icon icon-trash",
          callback: (e, n) => {
            confirm(t("Are you sure want to clear quick launch?")) &&
              (sys.setConfig("codeEditor/objectIterator", { quickLaunch: [] }),
              sys.saveConfig(),
              this.updateRunScriptMenu());
          },
        }))
      : (s.howToAdd = {
          name: t("How to add Automation here"),
          icon: "context-menu-icon icon-help",
          callback: (e, t) => {
            nw.Shell.openExternal(
              "https://dreamsavior.net/docs/translator/execute-script/pin-your-automation-to-quickly-launch-from-translator/"
            );
          },
        });
  }),
  (Trans.prototype.updateRunScriptGridMenu = function () {
    this.gridContextMenu.runAutomation.submenu = { items: [] };
    var n = this.gridContextMenu.runAutomation.submenu.items,
      a = sys.getConfig("codeEditor/gridSelection");
    a ||
      (sys.setConfig("codeEditor/gridSelection", { quickLaunch: [] }),
      (a = sys.getConfig("codeEditor/gridSelection"))),
      (a.quickLaunch = a.quickLaunch || []);
    for (var i = 0; i < a.quickLaunch.length; i++)
      (() => {
        var r = a.quickLaunch[i],
          o = (console.log("Adding context menu", r), common.getFilename(r)),
          e = common.generateId();
        n.push({
          name: o,
          key: "runAutomation:" + e,
          callback: (e, n) => {
            confirm(
              t("Are you sure want to execute the following script?") + "\n" + o
            ) && this.runCustomScript("gridSelection", r);
          },
        });
      })();
  }),
  (Trans.prototype.fileSelectorContextMenuInit = function () {
    console.log("trans.fileSelectorContextMenuInit");
    var a = this;
    if (
      ((this.fileSelectorMenu = {
        selectAll: {
          name: t("Select all"),
          icon: "context-menu-icon icon-check2-all",
        },
        clearSelection: { name: t("Clear selection") },
        selectCompleted: { name: t("Select 100%") },
        selectIncompleted: { name: t("Select <100%") },
        selectProgressGT: { name: t("Select progress ≥ ...") },
        selectMarkedAsCompleted: { name: t("Select completed") },
        invertSelection: { name: t("Invert selection") },
        sep0: "---------",
        markCompleteCurrent: {
          name: t("Toggle mark as complete"),
          icon: function () {
            return "context-menu-icon icon-ok";
          },
        },
        sep1: "---------",
        withSelected: {
          name: () => {
            var e = $(".fileCheckbox:checked").length;
            return 0 == e
              ? ((a.fileSelectorMenu.withSelected.icon =
                  "context-menu-icon icon-docs-1"),
                (a.fileSelectorMenu.withSelected.items.deleteFiles.visible =
                  !1),
                t("With all"))
              : t("With ") + e + t(" selected");
          },
          icon: function () {
            return "context-menu-icon icon-check";
          },
          items: {
            markComplete: {
              name: t("Mark as complete"),
              icon: "context-menu-icon icon-ok",
            },
            unsetMarkComplete: { name: t("Un-mark as complete") },
            "sep0-0": "---------",
            batchTranslation: {
              name: t("Batch translation"),
              icon: "context-menu-icon icon-language",
            },
            sendTo: {
              name: t("Send to..."),
              icon: "context-menu-icon icon-share-ios-line",
              items: {},
            },
            "sep0-1": "---------",
            wrapText: {
              name: t("Wrap texts"),
              icon: "context-menu-icon icon-wordwrap",
            },
            trim: { name: t("Trim"), icon: "context-menu-icon icon-article" },
            padding: {
              name: t("Auto padding"),
              icon: "context-menu-icon icon-list-nested",
            },
            createScript: {
              name: t("Create Automation"),
              icon: "context-menu-icon icon-code",
              items: {
                forEachObject: {
                  name: t("For each object"),
                  icon: "context-menu-icon icon-doc",
                },
                forEachRow: {
                  name: t("For each row"),
                  icon: "context-menu-icon icon-menu-1",
                },
              },
            },
            runScript: {
              name: t("Run Automation"),
              icon: "context-menu-icon icon-play",
              items: {
                forEachObjectRun: {
                  name: t("For each object"),
                  icon: "context-menu-icon icon-doc",
                  items: {},
                },
                forEachRowRun: {
                  name: () => (
                    console.log("rendering for each row"), t("For each row")
                  ),
                  icon: "context-menu-icon icon-menu-1",
                  items: {},
                },
              },
            },
            "sep0-2": "---------",
            import: {
              name: t("Import from..."),
              icon: "context-menu-icon icon-login",
              items: {
                importFromTrans: {
                  name: t("Trans File"),
                  icon: "context-menu-icon icon-tpp",
                },
                importFromSheet: {
                  name: t("Spreadsheets"),
                  icon: "context-menu-icon icon-file-excel",
                },
                importFromRPGMTransPatch: {
                  name: t("RPGMTransPatch Files"),
                  icon: "context-menu-icon icon-doc-text",
                },
              },
            },
            export: {
              name: t("Export into..."),
              icon: "context-menu-icon icon-export",
              items: {
                exportToGamePatch: {
                  name: t("A folder"),
                  icon: () => "context-menu-icon icon-folder-add",
                },
                exportToGamePatchZip: {
                  name: t("Zipped Game Patch"),
                  icon: () => "context-menu-icon icon-file-archive",
                },
                exportToCsv: {
                  name: t("Comma Separated Value (csv)"),
                  icon: () => "context-menu-icon icon-file-excel",
                },
                exportToXlsx: {
                  name: t("Excel 2007 Spreadsheets (xlsx)"),
                  icon: () => "context-menu-icon icon-file-excel",
                },
                exportToXls: {
                  name: t("Excel Spreadsheets (xls)"),
                  icon: () => "context-menu-icon icon-file-excel",
                },
                exportToOds: {
                  name: t("ODS Spreadsheets"),
                  icon: () => "context-menu-icon icon-file-excel",
                },
                exportToHtml: {
                  name: t("Html Spreadsheets"),
                  icon: () => "context-menu-icon icon-file-code",
                },
                exportToTransPatch: {
                  name: t("RMTrans Patch"),
                  icon: () => "context-menu-icon icon-doc-text",
                },
              },
            },
            inject: {
              name: t("Inject Translation"),
              icon: "context-menu-icon icon-download",
            },
            revert: {
              name: t("Revert to original"),
              icon: "context-menu-icon icon-ccw",
            },
            "sep0-3": "---------",
            clearTranslationSel: {
              name: t("Clear translation"),
              icon: "context-menu-icon icon-eraser",
            },
            deleteFiles: {
              name: t("Delete files"),
              icon: "context-menu-icon icon-trash-empty",
            },
          },
        },
        sep2: "---------",
        properties: {
          name: t("Properties"),
          icon: "context-menu-icon icon-cog",
        },
      }),
      a.fileSelectorContextMenuIsInitialized)
    )
      return !1;
    $.contextMenu({
      selector: ".fileList .data-selector",
      events: { preShow: function (e, t) {}, hide: function (e, t) {} },
      build: function (e, n) {
        return (
          a.updateRunScriptMenu(),
          {
            zIndex: 1e3,
            callback: function (e, n) {
              switch (e) {
                case "selectAll":
                  a.selectAll();
                  break;
                case "clearSelection":
                  a.clearSelection();
                  break;
                case "invertSelection":
                  a.invertSelection();
                  break;
                case "selectCompleted":
                  a.selectAll(a.getAllCompletedFiles());
                  break;
                case "selectIncompleted":
                  a.selectAll(a.getAllIncompletedFiles());
                  break;
                case "selectProgressGT":
                  let n = prompt(t("Select progress greater than"), "0");
                  isNaN(n)
                    ? alert(t("Please input a number"))
                    : a.selectObjectsByFilter((e, t) => {
                        e = a.getObjectById(e);
                        return (
                          !!e.progress &&
                          (e.progress.translated / e.progress.length) * 100 >=
                            parseInt(n)
                        );
                      });
                  break;
                case "selectMarkedAsCompleted":
                  a.selectAll(a.getAllMarkedAsCompleted());
                  break;
                case "markCompleteCurrent":
                  var r = $("#fileList .context-menu-active"),
                    o = !r.hasClass("isCompleted"),
                    r = r.data("id");
                  a.setMarkAsComplete(o, [r]);
                  break;
                case "markComplete":
                  a.setMarkAsComplete(!0);
                  break;
                case "unsetMarkComplete":
                  a.setMarkAsComplete(!1);
                  break;
                case "batchTranslation":
                  ui.translateAllDialog();
                  break;
                case "forEachObject":
                  ui.openAutomationEditor("codeEditor_objectIterator", {
                    workspace: "objectIterator",
                  });
                  break;
                case "forEachRow":
                  ui.openAutomationEditor("codeEditor_rowIterator", {
                    workspace: "rowIterator",
                  });
                  break;
                case "clearTranslationSel":
                  (o = confirm(t("Do you want to clear translation?"))),
                    (r = a.getCheckedFiles());
                  o &&
                    a.removeAllTranslation(a.getCheckedFiles(), {
                      refreshGrid: !0,
                    }),
                    a.evalTranslationProgress(r);
                  break;
                case "clearTranslationAll":
                  (o = confirm(t("Do you want to clear translation?"))),
                    (r = a.getAllFiles());
                  o &&
                    a.removeAllTranslation(a.getAllFiles(), {
                      refreshGrid: !0,
                    }),
                    a.evalTranslationProgress(r);
                  break;
                case "deleteFiles":
                  ui.deleteFiles();
                  break;
                case "wrapText":
                  ui.batchWrapingDialog();
                  break;
                case "trim":
                  ui.openTrimWindow();
                  break;
                case "padding":
                  ui.openPaddingWindow();
                  break;
                case "properties":
                  ui.openFileProperties();
                  break;
                case "importFromSheet":
                  ui.openImportSpreadsheetDialog();
                  break;
                case "importFromTrans":
                  $("#importTrans").trigger("click");
                  break;
                case "importFromRPGMTransPatch":
                  ui.openImportRPGMTransDialog();
                  break;
                case "exportToGamePatch":
                  $("#dialogExport").data("options", {
                    files: a.getCheckedFiles(),
                  }),
                    $("#exportDir").trigger("click");
                  break;
                case "exportToGamePatchZip":
                  $("#dialogExport").data("options", {
                    files: a.getCheckedFiles(),
                  }),
                    $("#export").trigger("click");
                  break;
                case "exportToCsv":
                  $("#exportCSV").trigger("click");
                  break;
                case "exportToXlsx":
                  $("#dialogExport").data("options", {
                    files: a.getCheckedFiles(),
                  }),
                    $("#exportXLSX").trigger("click");
                  break;
                case "exportToXls":
                  $("#dialogExport").data("options", {
                    files: a.getCheckedFiles(),
                  }),
                    $("#exportXLS").trigger("click");
                  break;
                case "exportToOds":
                  $("#dialogExport").data("options", {
                    files: a.getCheckedFiles(),
                  }),
                    $("#exportODS").trigger("click");
                  break;
                case "exportToHtml":
                  $("#dialogExport").data("options", {
                    files: a.getCheckedFiles(),
                  }),
                    $("#exportHTML").trigger("click");
                  break;
                case "exportToTransPatch":
                  $("#dialogExport").data("options", {
                    files: a.getCheckedFiles(),
                  }),
                    $("#exportTrans").trigger("click");
                  break;
                case "inject":
                  ui.openInjectDialog();
                  break;
                case "revert":
                  a.revertToOriginal();
              }
            },
            items: a.fileSelectorMenu,
          }
        );
      },
    }),
      (a.fileSelectorContextMenuIsInitialized = !0);
  }),
  (Trans.prototype.gridBodyContextMenu = function () {
    $.contextMenu({
      selector: ".ht_master .htCore tbody, .ht_clone_left .htCore tbody",
      events: {
        preShow: function (e, t) {
          t = $(t.target);
          console.log(t),
            t.hasClass("highlight") && console.log("previously hightlighted"),
            console.log(arguments);
        },
        show: function (e, t) {
          console.log("selection on show : "),
            (trans.grid.lastContextMenuCellRange =
              trans.grid.getSelectedRange());
        },
        hide: function (e, t) {
          if (
            (console.log("reload selection : "),
            void 0 === trans.grid.lastContextMenuCellRange)
          )
            return !1;
          trans.grid.selectCells(trans.grid.lastContextMenuCellRange),
            console.log(trans.grid.getSelectedRange());
        },
      },
      build: function (e, n) {
        return {
          zIndex: 1e3,
          callback: function (e, t) {
            switch (e) {
              case "addComment":
                var n = void 0;
                try {
                  n = trans.grid.lastContextMenuCellRange[0].highlight;
                } catch (e) {}
                trans.editNoteAtCell(n);
                break;
              case "removeComment":
                trans.removeNoteAtSelected(trans.grid.lastContextMenuCellRange);
            }
          },
          items: {
            addComment: {
              name: t("Add comment"),
              icon: function () {
                return "context-menu-icon icon-commenting-o";
              },
            },
            removeComment: {
              name: t("Remove comment"),
              icon: function () {
                return "context-menu-icon icon-comment-empty";
              },
            },
            selectAll: { name: t("Select all") },
            invertSelection: { name: t("Invert selection") },
            sep0: "---------",
            withSelected: {
              name: "With all",
              items: {
                batchTranslation: { name: t("Batch translation") },
                wordWrap: { name: t("Wrap texts") },
              },
            },
          },
        };
      },
    });
  }),
  (Trans.prototype.evalContextsQuery = function () {
    if (0 == arguments.length) return !1;
    for (var e, t = [], n = 0; n < arguments.length; n++)
      "string" == typeof arguments[n]
        ? 0 != arguments[n].length &&
          ((e = arguments[n].split("\n").map(function (e) {
            return common.stripCarriageReturn(e);
          })),
          (t = t.concat(e)))
        : Array.isArray(arguments[n]) &&
          0 != arguments[n].length &&
          (t = t.concat(arguments[n]));
    return t;
  }),
  (Trans.prototype.isInContext = function (e, t, n) {
    if (0 == (n = n || []).length) return !0;
    if (
      ("string" == typeof n && (n = [n]),
      void 0 !== trans.project.files[e] &&
        void 0 !== trans.project.files[e].context[t])
    )
      for (
        var r = trans.project.files[e].context[t],
          o = (r =
            (r = 0 == Array.isArray(r) ? [r] : r).length < 1 &&
            void 0 !== trans.project.files[e].parameters[t]
              ? [
                  trans.buildContextFromParameter(
                    trans.project.files[e].parameters[t]
                  ),
                ]
              : r).join("\n"),
          a = 0;
        a < n.length;
        a++
      )
        if (-1 != (o = o.toLowerCase()).indexOf(n[a].toLowerCase())) return !0;
    return !1;
  }),
  (Trans.prototype.removeRowByContext = function (e, t, n, r) {
    (n = n || {}).matchAll = n.matchAll || !1;
    var o,
      a = trans.travelContext(e, t, {
        onMatch: function (e, t) {},
        matchAll: n.matchAll,
      });
    for (o in a)
      for (var i = a[o].length - 1; 0 <= i; i--)
        ((1 == a[o][i] && !0 !== r) || (1 != a[o][i] && !0 === r)) &&
          (console.log(
            "removing " +
              o +
              " row " +
              i +
              (!0 === r ? " (Not on whitelist)" : "")
          ),
          trans.removeRow(o, i));
    trans.refreshGrid();
  }),
  (Trans.prototype.collectContextKeyword = function (t, n, e) {
    if (void 0 === (t = t || trans.project)) return !1;
    if ((n = "string" == typeof (n = n || []) ? [n] : n).length < 1)
      for (var r in trans.project.files) n.push(r);
    var o = {};
    for (let e = 0; e < n.length; e++)
      for (var a = n[e], i = t.files[a].context, s = 0; s < i.length; s++)
        if (0 != Array.isArray(i[s]))
          for (var l = 0; l < i[s].length; l++)
            for (var c = (i[s][l] || "").split("/"), d = 0; d < c.length; d++)
              isNaN(c[d]) && ((o[c[d]] = o[c[d]] || 0), (o[c[d]] += 1));
    return o;
  }),
  (Trans.prototype.travelContext = function (t, n, r) {
    if (
      ((t = t || []),
      (n = n || []),
      ((r = r || {}).onMatch = r.onMatch || function () {}),
      (r.onNotMatch = r.onNotMatch || function () {}),
      (r.matchAll = r.matchAll || !1),
      "string" == typeof t && (t = [t]),
      0 == Array.isArray(n) && (n = [n]),
      t.length < 1)
    )
      for (var e in trans.project.files) t.push(e);
    var o = {};
    for (let e = 0; e < t.length; e++) {
      var a = t[e];
      o[a] = [];
      for (let e = 0; e < trans.project.files[a].context.length; e++) {
        var i = trans.project.files[a].context[e];
        if (
          (0 == Array.isArray(i) && (i = [i]), (o[a][e] = !1), i.length < 1)
        ) {
          if (!trans.project.files[a].parameters[e]) continue;
          i = [
            trans.buildContextFromParameter(
              trans.project.files[a].parameters[e]
            ),
          ];
        }
        for (var s = 0; s < i.length; s++)
          for (var l = i[s], c = 0; c < n.length; c++)
            r.matchAll
              ? common.matchAllWords(l, n[c]) && (o[a][e] = !0)
              : 0 <= l.toLowerCase().indexOf(n[c].toLowerCase()) &&
                (o[a][e] = !0);
      }
      for (let e = 0; e < o[a].length; e++)
        (1 == o[a][e] ? r.onMatch : r.onNotMatch).call(
          trans.project.files[a],
          a,
          e
        );
    }
    return o;
  }),
  (Trans.prototype.isOrganicCell = function (e, t, n) {
    return (
      !!this.project &&
      ((n ||= this.getSelectedId()), "HU" == this.cellInfo.getCell(n, e, t)?.t)
    );
  }),
  (Trans.prototype.isVisitedCell = function (e, t, n) {
    return (
      !!this.project &&
      ((n ||= this.getSelectedId()), Boolean(this.cellInfo.get("v", n, e, t)))
    );
  }),
  (Trans.prototype.getData = function (e) {
    return void 0 === e
      ? this.getCurrentData()
      : "string" == typeof e
      ? this.getObjectById(e).data
      : "object" == typeof e && Array.isArray(e.data)
      ? e.data
      : (console.warn("invalid id or object ", e), []);
  }),
  (Trans.prototype.addRow = function (e, t, n) {
    var r,
      o,
      e =
        "object" == typeof e
          ? e
          : ((e = e || this.getSelectedId()), this.getObjectById(e));
    return (
      (e.indexIds ||= {}),
      "string" == typeof t && t
        ? ((r = this.getIndexByKey(e, t)),
          console.log("Existing index is", r),
          void 0 !== r
            ? r
            : (((r = Array(trans.colHeaders.length).fill(null))[
                this.keyColumn
              ] = t),
              n && (r[1] = n),
              console.log("inserting row:", r),
              (n = trans.getData(e)),
              console.log("theData", n),
              empty(n[n.length - 1][0])
                ? ((n[(o = n.length - 1)] = r), (e.indexIds[t] = o))
                : ((o = n.push(r)), (e.indexIds[t] = o - 1), o)))
        : -1
    );
  }),
  (Trans.prototype.appendRow = function (e, t = []) {
    e =
      "object" == typeof e
        ? e
        : ((e = e || this.getSelectedId()), this.getObjectById(e));
    if (((e.indexIds ||= {}), 0 == Array.isArray(t))) return -1;
    if (t.length < 1) return -1;
    var n = t[this.keyColumn];
    if ("string" != typeof n) return -1;
    if (!n) return -1;
    var r = this.getIndexByKey(e, n);
    if ((console.log("Existing index is", r), void 0 !== r)) return r;
    t.length = trans.colHeaders.length;
    var o,
      r = common.clone(t),
      t = trans.getData(e);
    return (
      console.log("theData", t),
      empty(t[t.length - 1][0])
        ? ((t[(o = t.length - 1)] = r), (e.indexIds[n] = o))
        : ((o = t.push(r)), (e.indexIds[n] = o - 1), o)
    );
  }),
  (Trans.prototype.getIndexIds = function (e) {
    var t;
    return "string" == typeof (e = void 0 === e ? this.getSelectedId() : e)
      ? (t = this.getObjectById(e))
        ? (t.indexIsBuilt || this.buildIndex(e), t.indexIds)
        : {}
      : "object" == typeof e
      ? (t = (t = e).indexIsBuilt ? t : this.buildIndexFromData(t)).indexIds
      : (console.warn("Error getting Index ID for file:", e), {});
  }),
  (Trans.prototype.getIndexByKey = function (e, t) {
    return this.getIndexIds(e)[t];
  }),
  (Trans.prototype.isAllSelected = function () {
    return (
      trans.getCheckedFiles().length == Object.keys(trans.project.files).length
    );
  }),
  (Trans.prototype.getActiveTranslator = function () {
    return trans.project
      ? ((trans.project.options = trans?.project.options || {}),
        trans.project?.options?.translator || sys.config.translator)
      : sys.config?.translator;
  }),
  (Trans.prototype.appendTextToReference = function (e) {
    var n, r;
    return (
      !!this.isInProject() &&
      "string" == typeof e &&
      (e.trim()
        ? trans.isKeyExistOn(e, "Common Reference")
          ? trans.alert(
              "Unable to add <b>" +
                e +
                "</b>. That value already exist on Common Reference!"
            )
          : ((r =
              (n = trans.project.files["Common Reference"]).data.length - 1),
            0 == Boolean(n.data[r][0])
              ? (console.log("inserting to ref.data[lastKey][0]"),
                (n.data[r][0] = e),
                (n.indexIds[e] = r))
              : (console.log("append new data"),
                ((r = (r = new Array(trans.colHeaders.length)).fill(null))[0] =
                  e),
                n.data.push(r),
                (n.indexIds[e] = n.data.length - 1)),
            trans.alert("<b>" + e + "</b> " + t("added to reference table!")),
            !0)
        : trans.alert(
            "Cannot add empty text to reference. Please try again with a text selected, or use <b>CTRL+SHIFT+D</b> to add the selected row into reference."
          ))
    );
  }),
  (Trans.prototype.appendSelectedRowToReference = function () {
    var n = common.gridSelectedRows();
    if (this.isInProject()) {
      if (!n?.length) return this.alert("No row selected.");
      if (!this.getObjectById("Common Reference"))
        return this.alert(
          "This project don't have <b>Common Reference</b> file. Please create one first."
        );
      let t = 0;
      for (let e = 0; e < n.length; e++)
        -1 < this.appendRow("Common Reference", this.getData()[e]) && t++;
      return this.alert(t + " row(s) added to Common Reference."), !0;
    }
  }),
  (Trans.prototype.wordWrapFiles = function (e, n, r, o) {
    if (
      (0 == (e = "string" == typeof (e = e || []) ? [e] : e).length &&
        (e = this.getAllFiles()),
      (n = n || 1),
      0 == (r = r || n + 1))
    )
      return trans.alert(t("Can not modify Column 0"));
    ((o = o || {}).maxLength = o.maxLength || 41),
      (o.onDone = o.onDone || function () {}),
      (o.context = o.context || []);
    for (var a = 0; a < e.length; a++) {
      var i = e[a];
      if (
        (console.log("Wordwrapping file : " + i),
        void 0 !== trans.project.files[i])
      ) {
        o.lineBreak = o.lineBreak || trans.project.files[i].lineBreak || "\n";
        for (var s = trans.project.files[i].data, l = 0; l < s.length; l++)
          trans.isInContext(i, l, o.context) &&
            ("string" != typeof s[l][n] && (s[l][r] = s[l][n]),
            (s[l][r] = common.wordwrapLocale(
              s[l][n],
              o.maxLength,
              this.getTl(),
              o.lineBreak
            )));
      }
    }
    o.onDone.call(trans);
  }),
  (Trans.prototype.fillEmptyLine = function (e, t, n, r, o) {
    "string" == typeof (e = e || []) && (e = [e]),
      ((o = o || {}).project = o.project || trans.project),
      (o.keyColumn = o.keyColumn || 0),
      (o.lineFilter =
        o.lineFilter ||
        function () {
          return !0;
        }),
      (o.fromKeyOnly = o.fromKeyOnly || !1),
      (o.filterTag = o.filterTag || []),
      (o.overwrite = o.overwrite || !1),
      o.fromKeyOnly &&
        (console.warn("collecting data from key only"),
        (o.sourceCol = r || o.keyColumn)),
      "number" == typeof (t = t || []) && (t = [t]),
      0 == e.length && (e = trans.getAllFiles()),
      console.log(e);
    for (var a = 0; a < e.length; a++) {
      var i = e[a];
      if (!(0 < t.length))
        for (var s = o.project.files[i].data, l = 0; l < s.length; l++) {
          if ("blacklist" == o.filterTagMode) {
            if (this.hasTags(o.filterTag, l, i)) continue;
          } else if (
            "whitelist" == o.filterTagMode &&
            !this.hasTags(o.filterTag, l, i)
          )
            continue;
          (void 0 === n &&
            null == (n = trans.getTranslationColFromRow(s[l]))) ||
            (0 == o.overwrite && s[l][n]) ||
            (o.project.files[i].data[l][n] = trans.getTranslationByLine(
              s[l],
              o.keyColumn,
              {
                includeIndex: !0,
                priorityCol: n,
                onBeforeLineAdd: o.lineFilter,
                sourceCol: o.sourceCol,
              }
            ));
        }
    }
  }),
  (Trans.prototype.trimTranslation = function (e, t, n) {
    if (!trans.project) return !1;
    (e = e || trans.getSelectedId()),
      ((n = n || {}).refreshGrid = n.refreshGrid || !1),
      0 == Array.isArray(e) && (e = [e]),
      0 == Array.isArray(t) && (t = [t]);
    for (var r = 0; r < e.length; r++)
      for (
        var o = e[r],
          a = trans.project.files[o].data,
          i = trans.project.files[o].lineBreak || "\n",
          s = 0;
        s < a.length;
        s++
      )
        for (var l in t) {
          var c,
            l = t[l];
          l < 1 ||
            ("string" == typeof trans.project.files[o].data[s][l] &&
              ((c = trans.project.files[o].data[s][l]
                .split("\n")
                .map(function (e) {
                  return e.trim();
                })),
              (trans.project.files[o].data[s][l] = c.join(i))));
        }
    trans.refreshGrid();
  }),
  (Trans.prototype.paddingTranslation = function (e, t, n) {
    if (!trans.project) return !1;
    (e = e || trans.getSelectedId()),
      ((n = n || {}).keyId = n.keyId || 0),
      (n.includeInitialWhitespace = n.includeInitialWhitespace || !1),
      (n.refreshGrid = n.refreshGrid || !1),
      0 == Array.isArray(e) && (e = [e]),
      0 == Array.isArray(t) && (t = [t]);
    for (var r = /^[\s\u0009\u200b\u180e\u2060]+/g, o = 0; o < e.length; o++)
      for (
        var a = e[o],
          i = trans.project.files[a].data,
          s = trans.project.files[a].lineBreak || "\n",
          l = 0;
        l < i.length;
        l++
      )
        if ("string" == typeof trans.project.files[a].data[l][n.keyId]) {
          for (
            var c,
              d = trans.project.files[a].data[l][n.keyId].split(s),
              g = [],
              f = 0;
            f < d.length;
            f++
          ) {
            var u = d[f].match(r);
            0 == Boolean(u) && (u = ""), g.push(u);
          }
          for (c in t) {
            var p = t[c];
            if (
              !(p < 1) &&
              "string" == typeof trans.project.files[a].data[l][p]
            ) {
              for (
                var h = trans.project.files[a].data[l][p].split(s),
                  m = [],
                  y = 0;
                y < h.length;
                y++
              ) {
                var v = g[y] || "";
                n.includeInitialWhitespace
                  ? m.push(v + h[y])
                  : m.push(v + h[y].trim());
              }
              trans.project.files[a].data[l][p] = m.join(s);
            }
          }
        }
    trans.refreshGrid();
  }),
  (Trans.prototype.removeAllTranslation = function (e, t) {
    if (!trans.project) return !1;
    (e = e || trans.getSelectedId()),
      ((t = t || {}).refreshGrid = t.refreshGrid || !1),
      0 == Array.isArray(e) && (e = [e]);
    for (var n = 0; n < e.length; n++)
      for (
        var r = e[n], o = trans.project.files[r].data, a = 0;
        a < o.length;
        a++
      )
        for (var i = 1; i < o[a].length; i++)
          trans.project.files[r].data[a][i] = null;
    this.trigger("removeAllTranslation", { files: e, options: t }),
      t.refreshGrid && trans.refreshGrid();
  }),
  (Trans.prototype.deleteFile = function (e, n) {
    if (!trans.project) return !1;
    if (
      ((e = e || trans.getSelectedId()),
      (e = 0 == Array.isArray(e) ? [e] : e).length < 1)
    )
      return !0;
    for (var r = 0; r < e.length; r++) {
      var o,
        a = e[r];
      "reference" == trans.project.files[a].type
        ? alert(t("Unable to delete table : ") + a)
        : (a == trans.getSelectedId() && ui.disableGrid(!0),
          (o = JSON.parse(JSON.stringify(trans.project.files[a]))),
          (trans.project.trash = trans.project.trash || {}),
          (trans.project.trash[a] = o),
          $(
            ".panel-left .fileList [data-id=" + common.escapeSelector(a) + "]"
          ).remove(),
          delete trans.project.files[a]);
    }
    ui.fileList.reIndex(), this.trigger("afterDeleteFile", [e]);
  }),
  (Trans.prototype.stagingFilesRemove = async function (e) {
    Array.isArray(e) || (e = [e]);
    var t = this.getStagingPath();
    if (!t) return [];
    var n,
      r = [];
    for (n in e) {
      var o = nwPath.join(t, "data", e[n]);
      console.log("Removing", o),
        (await common.isFileAsync(o)) || console.log("Not found:", o),
        r.push(await common.unlink(e[n]));
    }
    return r;
  }),
  (Trans.prototype.removeRow = function (e, t, n) {
    if ((console.log("removing row : ", arguments), void 0 === e)) return !1;
    if (void 0 === t) return !1;
    (t = (t = 0 === t ? [0] : t) || []),
      (n = n || {}),
      0 == Array.isArray(t) && (t = [t]),
      (n.permanent = n.permanent || !1),
      (n.refreshGrid = n.refreshGrid || !1),
      (t = common.arrayUnique(t)).sort(function (e, t) {
        return t - e;
      }),
      console.log("Removing rows > should be ordered descendingly:", t);
    for (var r = 0; r < t.length; r++) {
      var o,
        a = t[r];
      void 0 === trans.project.files[e].data[a] ||
        (trans.project.files[e].data.splice(a, 1),
        trans.project.files[e].parameters &&
          trans.project.files[e].parameters.splice(a, 1),
        trans.project.files[e].context &&
          trans.project.files[e].context.splice(a, 1),
        trans.project.files[e].tags && trans.project.files[e].tags.splice(a, 1),
        this.cellInfo.deleteRow(e, a),
        (o = this.getObjectById(e).comments),
        empty(o)) ||
        (Array.isArray(o) ? o.splice(a, 1) : delete o[a]);
    }
    0 < t.length && (trans.project.files[e].indexIsBuilt = !1),
      this.trigger("afterRemoveRow", { file: e, rows: t, options: n }),
      n.refreshGrid && trans.refreshGrid();
  }),
  (Trans.prototype.clearRow = function (e, t, n = {}) {
    if ((e = "string" == typeof e ? trans.getObjectById(e) : e)) {
      if ("object" != typeof e || !Array.isArray(e.data))
        return console.warn("Invalid argument 1");
      Array.isArray(t) || (t = [t]), (n ||= {});
      for (var r = 0, o = 0; o < t.length; o++)
        for (var a = e.data[t[o]], i = 0; i < a.length; i++)
          i != this.keyColumn && ((a[i] = ""), r++);
      return r;
    }
  }),
  (Trans.prototype.removeColumn = function (e, n) {
    if (0 === e) return trans.alert(t("Can not remove key column!"));
    if (
      (((n = n || {}).permanent = n.permanent || !1),
      (n.refreshGrid = n.refreshGrid || !1),
      void 0 === trans.project)
    )
      return trans.alert(t("Please open or create a project first"));
    for (var r in trans.project.files)
      if (
        0 != Array.isArray(trans.project.files[r].data) &&
        0 != trans.project.files[r].data.length
      )
        for (var o = 0; o < trans.project.files[r].data.length; o++)
          trans.project.files[r].data[o].splice(e, 1),
            this.cellInfo.deleteCell(r, o, e);
    trans.colHeaders.splice(e, 1),
      trans.columns.splice(e, 1),
      n.refreshGrid && trans.refreshGrid();
  }),
  (Trans.prototype.renameColumn = function (e, n, r) {
    return 0 === e
      ? trans.alert(t("Can not set column name to blank!"))
      : (((r = r || {}).refreshGrid = r.refreshGrid || !1),
        void 0 !== trans.colHeaders[e] &&
          ((trans.colHeaders[e] = n),
          void (r.refreshGrid && trans.refreshGrid())));
  }),
  (Trans.prototype.rowHasMultipleContext = function (e, t) {
    return (
      !!(t = t || this.getSelectedObject()).context &&
      !(!t.context[e] || t.context[e].length <= 1)
    );
  }),
  (Trans.prototype.isTranslatedRow = function (e, t) {
    t = t || trans.data;
    for (var n = 1; n < t[e].length; n++)
      if (0 < (t[e][n] || "").length) return !0;
    return !1;
  }),
  (Trans.prototype.countFilledCol = function (e, t) {
    t = t || trans.data;
    for (var n = 0, r = 1; r < t[e].length; r++)
      0 < (t[e][r] || "").length && n++;
    return n;
  }),
  (Trans.prototype.getTranslationFromRow = function (t, n, r = []) {
    if (((r ||= []), 0 == Array.isArray(t))) return !1;
    if (0 == (n = n || 0)) {
      for (let e = t.length; 0 < e; e--)
        if (!r.includes(e) && t[e]) return t[e];
    } else
      for (let e = t.length; 0 <= e; e--)
        if (e != n && !r.includes(e) && t[e]) return t[e];
    return null;
  }),
  (Trans.prototype.getTranslationColFromRow = function (t, n) {
    if (0 == Array.isArray(t)) return !1;
    if (0 == (n = n || 0)) {
      for (let e = t.length; e > n; e--) if (t[e]) return e;
    } else for (let e = t.length; 0 <= e; e--) if (e != n && t[e]) return e;
    return null;
  }),
  (Trans.prototype.getTranslationByLine = function (t, e, n) {
    if (0 == Array.isArray(t)) return !1;
    ((n = n || {}).includeIndex = n.includeIndex || !1),
      (n.lineBreak = n.lineBreak || "\n"),
      (n.onBeforeLineAdd =
        n.onBeforeLineAdd ||
        function () {
          return !0;
        });
    var r = [];
    if (void 0 !== n.sourceCol) {
      var o = (t[n.sourceCol] || "").split("\n").map(function (e) {
        return common.stripCarriageReturn(e);
      });
      for (let e = 0; e < o.length; e++)
        0 != Boolean(o[e]) && n.onBeforeLineAdd(o[e]) && (r[e] = o[e]);
    } else
      for (let e = 0; e < t.length; e++)
        if (0 != e && (void 0 === n.priorityCol || e != n.priorityCol)) {
          var a = (t[e] || "").split("\n").map(function (e) {
            return common.stripCarriageReturn(e);
          });
          for (let e = 0; e < a.length; e++)
            0 != Boolean(a[e]) && n.onBeforeLineAdd(a[e]) && (r[e] = a[e]);
        }
    if (n.includeIndex) {
      var i = (t[0] || "").split("\n").map(function (e) {
        return common.stripCarriageReturn(e);
      });
      for (let e = 0; e < i.length; e++)
        0 != Boolean(i[e]) && n.onBeforeLineAdd(i[e]) && (r[e] = i[e]);
    }
    if (void 0 !== n.priorityCol)
      for (
        var s = (t[n.priorityCol] || "").split("\n").map(function (e) {
            return common.stripCarriageReturn(e);
          }),
          l = 0;
        l < s.length;
        l++
      )
        0 != Boolean(s[l]) && (r[l] = s[l]);
    return r.join(n.lineBreak);
  }),
  (Trans.prototype.generateTranslationPair = function (e, t) {
    if (((t = t || 0), 0 == Array.isArray(e))) return {};
    for (var n, r = {}, o = 0; o < e.length; o++)
      0 != Boolean(e[o][0]) &&
        null != (n = trans.getTranslationFromRow(e[o], t)) &&
        (r[e[o][0]] = n);
    return r;
  }),
  (Trans.prototype.getProgressColumnIndices = function () {
    var t = sys.getConfig("progressColumnIndices");
    if (t) {
      let e = t.replaceAll(" ", "").split(",");
      return (
        (e = e.map(function (e) {
          return parseInt(e);
        })),
        common.arrayUnique(e)
      );
    }
  }),
  (Trans.prototype.countTranslated = function (e) {
    0 == (e = "string" == typeof (e = e || []) ? [e] : e).length &&
      (e = this.getAllFiles());
    for (
      var t = this.getProgressColumnIndices(),
        n = (console.log("Progress column indices", t), {}),
        r = 0;
      r < e.length;
      r++
    ) {
      var o = this.project.files[e[r]].data;
      n[e[r]] = { translated: 0, length: 0, percent: 100 };
      for (var a = 0; a < o.length; a++)
        if (0 != Boolean(o[a][this.keyColumn])) {
          if (
            ((o[a][this.keyColumn] = o[a][this.keyColumn] || ""),
            (o[a][this.keyColumn] = o[a][this.keyColumn] + ""),
            this.lineByLineMode)
          ) {
            try {
              var i = o[a][0].split("\n").length;
            } catch (e) {
              throw (
                (console.error(
                  "Error when trying to split key string ",
                  o[a][0]
                ),
                e)
              );
            }
            for (var s = 1; s < o[a].length; s++)
              if (0 != Boolean(o[a][s]))
                if (
                  ("string" != typeof o[a][s] && (o[a][s] = o[a][s] + ""),
                  (o[a][s] = o[a][s] || ""),
                  i <= o[a][s].split("\n").length)
                ) {
                  n[e[r]].translated++;
                  break;
                }
          } else
            this.rowHasTranslation(o[a], this.keyColumn, t) &&
              n[e[r]].translated++;
          n[e[r]].length++;
        }
      0 < n[e[r]].length &&
        (n[e[r]].percent = (n[e[r]].translated / n[e[r]].length) * 100),
        100 < n[e[r]].percent && (n[e[r]].percent = 100),
        n[e[r]].percent < 0 && (n[e[r]].percent = 0),
        (this.project.files[e[r]].progress = n[e[r]]);
    }
    return n;
  }),
  (Trans.prototype.resetIndex = function (e) {
    for (var t in this.project.files) this.project.files[t].indexIsBuilt = !1;
  }),
  (Trans.prototype.buildIndex = function (e, t, n) {
    if (
      ((e = e || trans.getSelectedId()), (n = n || trans.keyColumn || 0), e)
    ) {
      var r = trans.project.files[e];
      if (r.indexIsBuilt && !0 !== t) return r.indexIds;
      var o = {};
      for (let e = 0; e < r.data.length; e++)
        void 0 !== r.data[e] &&
          null != r.data[e][n] &&
          "" != r.data[e][n] &&
          void 0 !== r.data[e][n] &&
          (o[r.data[e][n]] = e);
      return (
        (r.indexIds = o),
        (r.indexIsBuilt = !0),
        e == trans.getSelectedId() &&
          ((trans.indexIds = r.indexIds),
          (trans.indexIsBuilt = r.indexIsBuilt)),
        o
      );
    }
    if (!trans.indexIsBuilt || !0 === t) {
      for (let e = 0; e < trans.data.length; e++)
        void 0 !== trans.data[e] &&
          null != trans.data[e][n] &&
          "" != trans.data[e][n] &&
          void 0 !== trans.data[e][n] &&
          (trans.indexIds[trans.data[e][n]] = e);
      trans.indexIsBuilt = !0;
    }
    return trans.indexIds;
  }),
  (Trans.prototype.buildIndexes = function (n, e = !1, r = {}) {
    if (
      ((r ||= {}).customFilter,
      (r.indexId ||= ""),
      (this.customIndexes ||= {}),
      "function" == typeof r.customFilter)
    ) {
      console.log("Generating custom index mode");
      try {
        if ("string" != typeof r.customFilter("test"))
          return console.error(
            "Invalid customFilter. Custom filter should return string"
          );
      } catch (e) {
        return console.error(
          "Invalid customFilter. Custom filter should return string"
        );
      }
      r.indexId = "#auto.fn." + common.crc32String(r.customFilter.toString());
    }
    r.indexId && (this.customIndexes[r.indexId] = {}),
      0 == (n = (n = "string" == typeof n ? [n] : n) || []).length &&
        (n = this.getAllFiles());
    var o = {};
    if (e) {
      for (let t = 0; t < n.length; t++) {
        var a = this.getObjectById(n[t]);
        if (a) {
          a.indexIsBuilt || this.buildIndex(n[t]);
          var i,
            s = this.getObjectById(n[t]).indexIds;
          for (i in s)
            for (
              var l = i.replaceAll("\r", "").split("\n"), c = 0;
              c < l.length;
              c++
            ) {
              let e = l[c];
              (o[
                (e =
                  "function" == typeof r.customFilter ? r.customFilter(e) : e)
              ] = o[e] || []),
                o[e].push({ file: n[t], row: s[i], line: c });
            }
        }
      }
      r.indexId ? (this.customIndexes[r.indexId] = o) : (this._tempIndexes = o);
    } else {
      console.log("Files is", n);
      for (let e = 0; e < n.length; e++) {
        console.log("handling file:", n[e]);
        var t = this.getObjectById(n[e]);
        if ((console.log("ThisObject:", t), t)) {
          t.indexIsBuilt || this.buildIndex(n[e]);
          var d,
            g = this.getObjectById(n[e]).indexIds;
          for (d in g) {
            o[
              (d = "function" == typeof r.customFilter ? r.customFilter(d) : d)
            ] = o[d] || [];
            var f,
              u = { file: n[e], row: g[d] };
            o[d].push(u),
              d.includes("\r") &&
                r.stripCarriageReturn &&
                ((o[(f = d.replaceAll("\r", ""))] = o[f] || []), o[f].push(u));
          }
        }
      }
      r.indexId ? (this.customIndexes[r.indexId] = o) : (this._tempIndexes = o),
        console.log("Indexes is", o);
    }
    return o;
  }),
  (Trans.prototype.getFromIndexes = function (e, t, n) {
    return (
      "function" == typeof n &&
        ((n = "#auto.fn." + common.crc32String(n.toString())),
        this.customIndexes[n]) &&
        this.customIndexes[n][e],
      (t = t || this._tempIndexes || {})[e]
    );
  }),
  (Trans.prototype.clearTemporaryIndexes = function (e) {
    e
      ? "string" == typeof e
        ? this.customIndexes[e] && delete this.customIndexes[e]
        : "function" == typeof e &&
          ((e = "#auto.fn." + common.crc32String(e.toString())),
          this.customIndexes[e]) &&
          delete this.customIndexes[e]
      : delete this.customIndexes,
      (this._tempIndexes = void 0);
  }),
  (Trans.prototype.findIdByIndex = function (e, t) {
    return (
      null != trans.data &&
      "" != trans.data &&
      void 0 !== trans.data &&
      (void 0 === t
        ? (void 0 === trans.indexIds && trans.buildIndex(),
          void 0 !== trans.indexIds[e] && trans.indexIds[e])
        : (0 == trans.project.files[t].indexIsBuilt && trans.buildIndex(t),
          void 0 === trans.project.files[t].indexIds && trans.buildIndex(t),
          void 0 !== trans.project.files[t].indexIds[e] &&
            trans.project.files[t].indexIds[e]))
    );
  }),
  (Trans.prototype.getClearOnNextHumanInteract = function (e) {
    return (
      (this._clearOnNextHumanInteract = this._clearOnNextHumanInteract || {}),
      e
        ? ((this._clearOnNextHumanInteract[e] =
            this._clearOnNextHumanInteract[e] || {}),
          this._clearOnNextHumanInteract[e])
        : this._clearOnNextHumanInteract
    );
  }),
  (Trans.prototype.getRowIdByTextInsensitive = function (e, t) {
    if (null == this.data || "" == this.data || void 0 === this.data) return !1;
    if (!t) throw "second argument fileId is required!";
    var n = this.getClearOnNextHumanInteract("insensitiveIndex_" + t),
      r = this.getData(t),
      o = (e) => (e ? common.trimRightParagraph(e).toLowerCase() : "");
    if (empty(n))
      for (var a = 0; a < r.length; a++) n[o(r[a][this.keyColumn])] = a;
    return n[o(e)];
  }),
  (Trans.prototype.copyTranslationToRow = function (e, t, n) {
    if ((console.log("copyTranslationToRow", arguments), void 0 === e))
      return !1;
    if (
      (void 0 !== e.files && (e = e.files),
      (t = t || n.targetColumn || 1),
      ((n = n || {}).files = n.files || []),
      (n.mode = n.mode || ""),
      (n.fetch = n.fetch || ""),
      (n.filterTag = n.filterTag || []),
      (n.filterTagMode = n.filterTagMode || ""),
      (n.overwrite = n.overwrite || !1),
      0 == Array.isArray(n.files) && (n.files = [n.files]),
      0 == n.files.length)
    )
      for (var r in e) n.files.push(r);
    for (var o = 0; o < n.files.length; o++) {
      var a = n.files[o];
      if ((console.log("Handling", a), 0 != Boolean(e[a])))
        for (var i = trans.getObjectById(a), s = 0; s < e[a].data.length; s++) {
          var l,
            c = e[a].data[s];
          0 == Boolean(c[0]) ||
            empty(i.data[s]) ||
            (0 == n.overwrite && Boolean(i.data[s][t])) ||
            ((l = trans.getTranslationFromRow(c)),
            0 == Boolean(l) && (l = c[0]),
            (i.data[s][t] = l));
        }
    }
  }),
  (Trans.prototype.generateContextTranslationPair = function (t, n) {
    if ((console.log("Entering trans.generateTranslationTable"), void 0 === t))
      return !1;
    void 0 !== t.files && (t = t.files),
      console.log("obj files inside trans.generateTranslationTable :"),
      console.log(t);
    var r = {};
    if (
      (((n = n || {}).files = n.files || []),
      (n.mode = n.mode || ""),
      (n.fetch = n.fetch || ""),
      (n.filterTag = n.filterTag || []),
      (n.filterTagMode = n.filterTagMode || ""),
      0 == Array.isArray(n.files) && (n.files = [n.files]),
      0 == n.files.length)
    )
      for (var e in t) n.files.push(e);
    console.log("Worked option files : "), console.log(n.files);
    for (let e = 0; e < n.files.length; e++) {
      var o = n.files[e];
      if (0 != Boolean(t[o]))
        for (var a = 0; a < t[o].context.length; a++)
          if (0 != Boolean(t[o].context[a]) && 0 != Boolean(t[o].data[a])) {
            var i = trans.getTranslationFromRow(t[o].data[a]);
            if (
              (0 == Boolean(i) && (i = t[o].data[a][trans.keyColumn]),
              0 != Boolean(i))
            )
              for (var s = 0; s < t[o].context[a].length; s++)
                r[t[o].context[a][s]] = i;
          }
    }
    return console.log("translation table collection is : "), console.log(r), r;
  }),
  (Trans.prototype.generateTranslationTable = function (t, n) {
    if ((console.log("Entering trans.generateTranslationTable"), void 0 === t))
      return !1;
    void 0 !== t.files && (t = t.files),
      console.log("obj files inside trans.generateTranslationTable :"),
      console.log(t);
    var r = {};
    if (
      (((n = n || {}).files = n.files || []),
      (n.caseSensitive = n.caseSensitive || !1),
      (n.mode = n.mode || ""),
      (n.fetch = n.fetch || ""),
      (n.filterTag = n.filterTag || []),
      (n.filterTagMode = n.filterTagMode || ""),
      0 == Array.isArray(n.files) && (n.files = [n.files]),
      0 == n.files.length)
    )
      for (var e in t) n.files.push(e);
    if (
      (console.log("Worked option files : "),
      console.log(n.files),
      "linebyline" == n.mode.toLowerCase())
    )
      for (let e = 0; e < n.files.length; e++) {
        var o = n.files[e];
        console.log(o);
        for (var a = 0; a < t[o].data.length; a++)
          if (0 != Boolean(t[o].data[a][0])) {
            if ("blacklist" == n.filterTagMode) {
              if (this.hasTags(n.filterTag, a, o)) continue;
            } else if (
              "whitelist" == n.filterTagMode &&
              !this.hasTags(n.filterTag, a, o)
            )
              continue;
            var i = trans.getTranslationFromRow(t[o].data[a]);
            if ("untranslated" == n.fetch) {
              if (1 == Boolean(i)) continue;
            } else if ("both" != n.fetch && 0 == Boolean(i)) continue;
            for (
              var s = t[o].data[a][0].split("\n"),
                l = (i = i || "").split("\n").map(function (e) {
                  return (e = e || "").replaceAll(/\r/g, "");
                }),
                c = 0;
              c < s.length;
              c++
            ) {
              if ("untranslated" == n.fetch) {
                if (1 == Boolean(l[c])) continue;
              } else if ("both" != n.fetch && 0 == Boolean(l[c])) continue;
              r[s[c]] = l[c] || "";
            }
          }
      }
    else
      for (let e = 0; e < n.files.length; e++) {
        var d,
          g = n.files[e];
        if (0 != Boolean(t[g]))
          for (let e = 0; e < t[g].data.length; e++)
            0 != Boolean(t[g].data[e][0]) &&
              ((d = trans.getTranslationFromRow(t[g].data[e])),
              0 != Boolean(d)) &&
              (r[t[g].data[e][0]] = d);
      }
    return console.log("translation table collection is : "), console.log(r), r;
  }),
  (Trans.prototype.generateTranslationTableLine = function (t, n) {
    if (
      (console.log("Entering trans.generateTranslationTableLine", t, n),
      void 0 === t)
    )
      return !1;
    void 0 !== t.files && (t = t.files),
      console.log("obj files inside trans.generateTranslationTable :"),
      console.log(t);
    var r = {};
    ((n = n || {}).files = n.files || []),
      (n.caseSensitive = n.caseSensitive || !1),
      (n.mode = n.mode || ""),
      (n.fetch = n.fetch || ""),
      (n.keyColumn = n.keyColumn || 0),
      (n.filterTag = n.filterTag || []),
      (n.filterTagMode = n.filterTagMode || ""),
      (n.ignoreTranslated = n.ignoreTranslated || !1),
      (n.overwrite = n.overwrite || !1),
      (n.collectAddress = n.collectAddress || !1);
    try {
      n.filterLanguage = n.filterLanguage || this.getSl() || "ja";
    } catch (e) {
      n.filterLanguage = "ja";
    }
    if (
      ((n.ignoreLangCheck = n.ignoreLangCheck || !1),
      console.log("ignore language check?"),
      console.log(n.ignoreLangCheck),
      0 == Array.isArray(n.files) && (n.files = [n.files]),
      0 == n.files.length)
    )
      for (var e in t) n.files.push(e);
    console.log("Worked option files : "), console.log(n.files);
    var o = {};
    for (let e = 0; e < n.files.length; e++) {
      var a = n.files[e];
      console.log("fetching translatable data from:", a);
      for (let e = 0; e < t[a].data.length; e++)
        if (0 != Boolean(t[a].data[e][n.keyColumn])) {
          if ("blacklist" == n.filterTagMode) {
            if (this.hasTags(n.filterTag, e, a)) continue;
          } else if (
            "whitelist" == n.filterTagMode &&
            !this.hasTags(n.filterTag, e, a)
          )
            continue;
          if (
            !(
              (n.ignoreTranslated &&
                this.rowHasTranslation(t[a].data[e], n.keyColumn)) ||
              (0 == n.overwrite &&
                n.targetColumn &&
                t[a].data[e][n.targetColumn])
            )
          ) {
            console.log("Reached here!");
            for (
              var i = trans.getTranslationFromRow(t[a].data[e], n.keyColumn, [
                  0,
                ]),
                s =
                  (console.log("current translation", i),
                  t[a].data[e][n.keyColumn].split("\n")),
                l = (i = i || "").split("\n").map(function (e) {
                  return (e = e || "").replaceAll(/\r/g, "");
                }),
                c = 0;
              c < s.length;
              c++
            ) {
              if ("untranslated" == n.fetch) {
                if (1 == Boolean(l[c])) continue;
              } else if ("both" != n.fetch && 0 == Boolean(l[c])) continue;
              (0 == n.ignoreLangCheck &&
                0 == common.isInLanguage(s[c], n.filterLanguage)) ||
                ((r[s[c]] = l[c] || ""),
                n.collectAddress &&
                  ((o[s[c]] ||= []),
                  o[s[c]].push({
                    line: c,
                    file: a,
                    row: e,
                    rowObj: t[a].data[e],
                  })));
            }
          }
        }
    }
    return (
      console.log("result is : "),
      console.log(r),
      console.log("addresses:", o),
      n.collectAddress ? { pairs: r, addresses: o } : r
    );
  }),
  (Trans.prototype.generateTranslationTableFromStrings = function (t, e, n) {
    n = n || {};
    try {
      n.filterLanguage = n.filterLanguage || this.getSl() || "ja";
    } catch (e) {
      n.filterLanguage = "ja";
    }
    var r;
    n.ignoreLangCheck = n.ignoreLangCheck || !1;
    try {
      r = n.ignoreLangCheck || e.getOptions("ignoreLangCheck");
    } catch (e) {
      r = !1;
    }
    "string" == typeof t && (t = [t]);
    var o = { include: {}, exclude: {} };
    if ("rowByRow" == n.mode)
      for (let e = 0; e < t.length; e++)
        "string" != typeof t[e] ||
          t[e].length < 1 ||
          (r || 0 != common.isInLanguage(t[e], n.filterLanguage)
            ? (o.include[t[e]] = "")
            : (o.exclude[t[e]] = t[e]));
    else
      for (let e = 0; e < t.length; e++)
        if ("string" == typeof t[e] && !(t[e].length < 1))
          for (
            var a = t[e].replaceAll("\r", "").split("\n"), i = 0;
            i < a.length;
            i++
          ) {
            if (n.ignoreWhitespace) {
              if (!a[i]) continue;
              if (!a[i].trim()) continue;
            }
            r && 0 == common.isInLanguage(a[i], n.filterLanguage)
              ? (o.exclude[a[i]] = a[i])
              : (o.include[a[i]] = "");
          }
    return o;
  }),
  (Trans.prototype.generateTranslationTableFromResult = function (e, t, n) {
    for (var r = n || {}, o = 0; o < e.length; o++)
      void 0 !== t[o] && (r[e[o]] = t[o]);
    return r;
  }),
  (Trans.prototype.generateSelectedTranslationTable = function (e, t, n) {
    (e = e || this.grid.getSelectedRange() || [[]]),
      (t = t || this.getSelectedId());
    for (
      var r = common.gridSelectedCells(e), o = this.getData(t), a = {}, i = 0;
      i < r.length;
      i++
    ) {
      var s = r[i].row,
        l = r[i].col,
        c = o[s][this.keyColumn];
      (a[c] = a[c] || []),
        a[c].push({ col: l, row: s, value: o[s][l], file: t });
    }
    return a;
  }),
  (Trans.prototype.wordWrapText = function (t, n = [], r = [], o = "\n") {
    if (!empty(r) && !empty(n)) {
      if (window.langTools?.isCJK(this.getTl()))
        for (let e = 0; e < r.length; e++)
          if (0 < common.arrayIntersect(n, r[e].tags).length)
            return common.wordwrapLocale(t, r[e].maxLength, this.getTl(), o);
      for (let e = 0; e < r.length; e++)
        if (0 < common.arrayIntersect(n, r[e].tags).length)
          return common.wordwrap(t, r[e].maxLength, o);
    }
    return t;
  }),
  (Trans.prototype.getTranslationData = function (e, t) {
    ((t = t || {}).keyCol = t.keyCol || 0),
      (t.groupIndex = t.groupIndex || void 0),
      (t.groupBy = t.groupBy || "path"),
      (t.objectGrouping = t.objectGrouping || !1),
      (t.includeTagsInfo = t.includeTagsInfo || !1),
      (e = e || trans.getSaveData()),
      ((e = JSON.parse(JSON.stringify(e))).project = e.project || {}),
      (e.project.files = e.project.files || {}),
      (t.options = t.options || {}),
      (t.filterTag = t.filterTag || t.options.filterTag || []),
      (t.filterTagMode = t.filterTagMode || t.options.filterTagMode || ""),
      (t.wordWrapByTags =
        t.wordWrapByTags ||
        t.options.wordWrapByTags ||
        e.project.options.wordWrapByTags),
      (t.useSelectedFiles ??= !0),
      (t.disableEvent ||= !1),
      (t.collectUntranslated ||= !1);
    var n = t.contextSeparator || "\n",
      r = [];
    if (t.useSelectedFiles)
      for (
        var o = $(".fileList .data-selector .fileCheckbox:checked"), a = 0;
        a < o.length;
        a++
      )
        r.push(o.eq(a).attr("value"));
    if (((t.files = t.files || r || []), "id" == t.groupBy))
      for (var i in e.project.files)
        e.project.files[i] && (e.project.files[i].id = i);
    var s,
      l = {},
      c = { filterTag: t.filterTag, filterTagMode: t.filterTagMode };
    for (s in (empty(t.wordWrapByTags) || (c.wordWrapByTags = t.wordWrapByTags),
    e.project.files)) {
      var d = e.project.files[s];
      if (
        ((d.data = d.data || [[]]),
        (d.tags = d.tags || []),
        !(0 < t.files.length && 0 == t.files.includes(s)))
      ) {
        l[d[t.groupBy]] = l[d[t.groupBy]] || {
          info: { groupLevel: d.groupLevel },
          translationPair: {},
        };
        for (var g = 0; g < d.data.length; g++)
          if (0 != Boolean(d.data[g]) && 0 != Boolean(d.data[g][t.keyCol])) {
            var f = d.tags[g] || [];
            if ("" !== t.filterTagMode) {
              var u = t.filterTag.filter((e) => f.includes(e));
              if ("whitelist" == t.filterTagMode) {
                if (0 == u.length) continue;
              } else if (0 < u.length) continue;
            }
            try {
              var p,
                h,
                m = (d.data[g][t.keyCol] = d.data[g][t.keyCol] || ""),
                y = trans.getTranslationFromRow(d.data[g], t.keyCol),
                v = ui.translationByContext.generateContextTranslation(g, s, m);
              t.collectUntranslated
                ? (0 < v.length &&
                    (l[d[t.groupBy]].translationPair = Object.assign(
                      l[d[t.groupBy]].translationPair,
                      v.translation
                    )),
                  t.objectGrouping
                    ? d[t.groupIndex]
                      ? ((l[d[t.groupBy]].translationPair[d[t.groupIndex]] =
                          l[d[t.groupBy]].translationPair[d[t.groupIndex]] ||
                          {}),
                        (l[d[t.groupBy]].translationPair[d[t.groupIndex]][m] =
                          trans.wordWrapText(y, f, t.wordWrapByTags) || ""))
                      : (l[d[t.groupBy]].translationPair[m] =
                          trans.wordWrapText(y, f, t.wordWrapByTags) || "")
                    : ((p = d[t.groupIndex] ? d[t.groupIndex] + n + m : m),
                      (l[d[t.groupBy]].translationPair[p] =
                        trans.wordWrapText(y, f, t.wordWrapByTags) || "")))
                : (0 == Boolean(y) && 0 == v.length) ||
                  (0 < v.length &&
                    (l[d[t.groupBy]].translationPair = Object.assign(
                      l[d[t.groupBy]].translationPair,
                      v.translation
                    )),
                  t.objectGrouping
                    ? d[t.groupIndex]
                      ? ((l[d[t.groupBy]].translationPair[d[t.groupIndex]] =
                          l[d[t.groupBy]].translationPair[d[t.groupIndex]] ||
                          {}),
                        !1 !== Boolean(y) &&
                          (l[d[t.groupBy]].translationPair[d[t.groupIndex]][m] =
                            trans.wordWrapText(y, f, t.wordWrapByTags)))
                      : !1 !== Boolean(y) &&
                        (l[d[t.groupBy]].translationPair[m] =
                          trans.wordWrapText(y, f, t.wordWrapByTags))
                    : ((h = d[t.groupIndex] ? d[t.groupIndex] + n + m : m),
                      !1 !== Boolean(y) &&
                        (l[d[t.groupBy]].translationPair[h] =
                          trans.wordWrapText(y, f, t.wordWrapByTags))));
            } catch (e) {
              throw (
                (console.log(
                  "Error when processing",
                  s,
                  "row",
                  g,
                  d.data[g][t.keyCol]
                ),
                e)
              );
            }
          }
      }
    }
    return (
      t.disableEvent ||
        this.trigger("onGenerateTranslationData", {
          info: c,
          translationData: l,
        }),
      { info: c, translationData: l }
    );
  }),
  (Trans.prototype.buildContextFromParameter = function (e) {
    return (
      e["VALUE ID"] + "/" + consts.eventCode[trans.gameEngine][e["EVENT CODE"]]
    );
  }),
  (Trans.prototype.getStagingPath = function (e) {
    try {
      return (e ||= this), nwPath.resolve(e?.project?.cache?.cachePath);
    } catch (e) {}
  }),
  (Trans.prototype.getStagingDataPath = function (e) {
    var t = engines.current().getProperty("stagingDataPath") || "data";
    return nwPath.join(this.getStagingPath(e), t);
  }),
  (Trans.prototype.updateStagingInfo = async function (e) {
    e ||= this;
    var t = nwPath.join(this.getStagingPath(e) || "", "gameInfo.json"),
      n = (console.log("Staging info:", t), {});
    return (
      ((n = (await common.isFileAsync(t))
        ? JSON.parse(await common.fileGetContents(t))
        : n).title = e.project.gameTitle),
      (n.engine = e.project.gameEngine),
      await common.filePutContents(t, JSON.stringify(n, void 0, 2), "UTF8", !1),
      n
    );
  }),
  (Trans.prototype.getStagingFile = function (e) {
    if (
      (e = "string" == typeof e ? this.getObjectById(e) : e) &&
      "object" == typeof e &&
      e.path
    )
      return nwPath.join(this.getStagingDataPath(), e.path);
  }),
  (Trans.prototype.insertCell = function (e, n) {
    if (
      ((n = n || null),
      common.batchArrayInsert(trans.data, e, n),
      void 0 === trans.project)
    )
      return trans.alert(t("Please open or create a new project first!"));
    for (var r in trans.project.files)
      r != trans.getSelectedId() &&
        common.batchArrayInsert(trans.project.files[r].data, e, n);
  }),
  (Trans.prototype.copyCol = function (e, t, n, r) {
    if (
      (console.log("Copying column"),
      console.log(arguments),
      void 0 === (n = n || trans.project))
    )
      return console.log("project is undefined");
    if (void 0 === n.files) return console.log("project.files are undefined");
    for (var o in n.files)
      if (0 == Array.isArray(n.files[o].data))
        console.log("no data for files " + o);
      else
        for (var a in n.files[o].data)
          n.files[o].data[a][t] = n.files[o].data[a][e];
  }),
  (Trans.prototype.gridIsModified = function (e) {
    return void 0 === e
      ? this.unsavedChange
      : this.project
      ? (this.unsavedChange !== e &&
          this.trigger("documentModifiedStateChange", e),
        (this.unsavedChange = e),
        (e = this.getSelectedId()),
        0 != Boolean(this.project.files) &&
          !!this.project.files[e] &&
          ((this.project.files[e].cacheResetOnChange = {}), this.unsavedChange))
      : void (this.unsavedChange = !1);
  }),
  (Trans.prototype.walkToAllFile = function () {
    console.log($(".fileList .selected"));
    for (
      var e = $(".fileList li").index($(".fileList .selected")), t = 0;
      t < $(".fileList li").length;
      t++
    )
      $(".fileList li").eq(t).trigger("click");
    $(".fileList li").eq(e).trigger("click");
  }),
  (Trans.prototype.moveColumn = async function (e, t) {
    if (
      (console.log("trans.moveColumn"),
      console.log(arguments),
      void 0 === trans.project)
    )
      return !1;
    if (
      (t > Math.min.apply(null, e) && (console.log("move to rigth"), (t -= 1)),
      e[0] == t)
    )
      return !1;
    for (var n in (t < Math.max.apply(null, e) && console.log("move to left"),
    ui.showBusyOverlay(),
    trans.project.files))
      for (var r = 0; r < trans.project.files[n].data.length; r++)
        (trans.project.files[n].data[r] = common.arrayMoveBatch(
          trans.project.files[n].data[r],
          e,
          t
        )),
          this.cellInfo.moveCell(n, r, e, t);
    return (
      (trans.colHeaders = common.arrayMoveBatch(trans.colHeaders, e, t)),
      (trans.column = common.arrayMoveBatch(trans.column, e, t)),
      await common.wait(250),
      trans.grid.destroy(),
      trans.initTable(),
      ui.hideBusyOverlay(),
      trans.renderGridInfo(),
      trans.gridIsModified(!0),
      trans
    );
  }),
  (Trans.prototype.dataPadding = function () {
    if (void 0 === trans.data) return !1;
    for (var e in (console.log("Trans data : ", trans.data), trans.data)) {
      var t;
      0 == Array.isArray(trans.data[e]) && (trans.data[e] = []),
        trans.data[e].length >= trans.colHeaders.length ||
          (t = trans.colHeaders.length - trans.data[e].length) < 0 ||
          (console.log("trans.data[i] : ", trans.data[e]),
          console.log("trans.data : ", trans.data[e].length),
          console.log("dif length : ", t),
          (t = Array(t).fill(null)),
          (trans.data[e] = trans.data[e].concat(t)));
    }
    if (void 0 === trans.project) return !1;
    for (var n in trans.project.files)
      for (var r in trans.project.files[n].data) {
        var o;
        trans.project.files[n].data[r].length >= trans.colHeaders.length ||
          ((o =
            trans.colHeaders.length - trans.project.files[n].data[r].length),
          (o = Array(o).fill(null)),
          (trans.project.files[n].data[r] =
            trans.project.files[n].data[r].concat(o)));
      }
    return trans.refreshGrid(), trans;
  }),
  (Trans.prototype.generateHeader = function (t, n) {
    n = n || "";
    var e,
      r = 0;
    for (e in (t = t || this).project.files) {
      var o = t.project.files[e].data || [];
      for (let e = 0; e < o.length; e++)
        0 != Array.isArray(o[e]) && o[e].length > r && (r = o[e].length);
    }
    for (let e = t.colHeaders.length - 1; e < r; e++)
      t.colHeaders.push(n + String.fromCharCode(65 + e)), t.columns.push({});
    return t.colHeaders;
  }),
  (Trans.prototype.sanitize = function (e) {
    if (
      ((e = e || this),
      console.log("running trans.sanitize"),
      void 0 === e.project)
    )
      return !1;
    if (void 0 === e.project.files) return !1;
    for (var t in e.project.files) {
      var n = e.project.files[t].data,
        r = e.project.files[t].context || [],
        o = e.project.files[t].tags || [],
        a = e.project.files[t].parameters || [],
        i = {},
        s = [],
        l = [],
        c = [],
        d = [];
      if (((this.colHeaders = this.colHeaders || []), 0 == Array.isArray(n)))
        e.project.files[t].data = [
          JSON.parse(JSON.stringify(this.colHeaders)).fill(null),
        ];
      else if (0 == n.length)
        e.project.files[t].data = [
          JSON.parse(JSON.stringify(this.colHeaders)).fill(null),
        ];
      else {
        for (var g, n = n || [], f = 0; f < n.length; f++)
          "string" != typeof n[f][0] ||
            n[f][0].length < 1 ||
            (void 0 === i[n[f][0]] &&
              (s.push(n[f]),
              (g = s.length - 1),
              r[f] && (l[g] = r[f]),
              o[f] && (c[g] = o[f]),
              a[f] && (d[g] = a[f]),
              (i[n[f][0]] = !0)));
        (e.project.files[t].data = s),
          (e.project.files[t].context = l),
          (e.project.files[t].tags = c),
          (e.project.files[t].parameters = d);
      }
    }
    return (e.project.isDuplicatesRemoved = !0), e;
  }),
  (Trans.prototype.removeDuplicates = function () {
    console.log("running trans.removeDuplicates");
    for (var e = {}, t = [], n = 0; n < trans.data.length; n++)
      void 0 === e[trans.data[n][0]] &&
        (t.push(trans.data[n]), (e[trans.data[n]] = !0));
    return (trans.data = t), trans.data;
  }),
  (Trans.prototype.isKeyExistOn = function (e, t) {
    return (
      void 0 === t && (t = trans.getSelectedId()),
      "number" == typeof trans.findIdByIndex(e, t)
    );
  }),
  (Trans.prototype.isKeyExist = function (e) {
    return "number" == typeof trans.findIdByIndex(e);
  }),
  (Trans.prototype.setTags = function (e, t, n, r) {
    return (
      (r = r || {}),
      0 == Array.isArray(n) && (n = [n]),
      void 0 !== this.project &&
        void 0 !== this.project.files[e] &&
        "number" == typeof t &&
        (void 0 === this.project.files[e].tags &&
          (this.project.files[e].tags = []),
        1 == Boolean(r.append)
          ? ((this.project.files[e].tags[t] =
              this.project.files[e].tags[t] || []),
            this.project.files[e].tags[t].push.apply(
              this.project.files[e].tags[t],
              n
            ),
            (this.project.files[e].tags[t] = this.project.files[e].tags[
              t
            ].filter((e, t, n) => n.indexOf(e) === t)))
          : (this.project.files[e].tags[t] = n),
        this.project.files[e].tags[t])
    );
  }),
  (Trans.prototype.removeTags = function (e, t, n, r) {
    if (
      (console.log("removeTags", arguments),
      (e = e || this.getSelectedId()),
      0 == Array.isArray(n) && (n = [n]),
      void 0 === this.project)
    )
      return !1;
    if (void 0 === this.project.files[e]) return !1;
    if ("number" != typeof t) return !1;
    void 0 === this.project.files[e].tags && (this.project.files[e].tags = []);
    let o = this.project.files[e].tags?.[t];
    return (
      console.log("Current tags", o),
      0 == Array.isArray(o)
        ? []
        : ((o = o.filter((e) => !n.includes(e))),
          (this.project.files[e].tags[t] = o),
          this.project.files[e].tags[t])
    );
  }),
  (Trans.prototype.clearTags = function (t, n, e) {
    if (((t = t || this.getSelectedId()), void 0 === this.project)) return !1;
    if (void 0 === this.project.files[t]) return !1;
    if ("number" == typeof n)
      return (
        (this.project.files[t].tags[n] = []), this.project.files[t].tags[n]
      );
    for (let e = 0; e < n.length; e++) {
      var r = n[e].start || n[e].from,
        o = n[e].end || n[e].to;
      if (void 0 !== r.row && void 0 !== o.row) {
        this.project.files[t].tags = this.project.files[t].tags || [];
        for (var a = r.row; a <= o.row; a++) this.project.files[t].tags[a] = [];
      }
    }
    return this.project.files[t].tags[a];
  }),
  (Trans.prototype.resetTags = function (e, t) {
    return (
      (e = e || this.getSelectedId()),
      void 0 !== this.project &&
        void 0 !== this.project.files[e] &&
        (this.project.files[e].tags = [])
    );
  }),
  (Trans.prototype.appendTags = function (e, t, n, r) {
    return this.setTags(e, t, n, { append: !0, noRefresh: !0 });
  }),
  (Trans.prototype.setTagForSelectedRow = function (t, n, r, o) {
    if (
      (void 0 === (o = o || {}).append && (o.append = !0),
      (r = r || this.getSelectedId()),
      0 == Boolean(n))
    )
      return !1;
    if (0 == Array.isArray(n)) return !1;
    for (let e = 0; e < n.length; e++) {
      var a = n[e].start || n[e].from,
        i = n[e].end || n[e].to;
      if (void 0 !== a.row && void 0 !== i.row)
        for (var s = a.row; s <= i.row; s++) this.setTags(r, s, t, o);
    }
    return this.grid.render(), !0;
  }),
  (Trans.prototype.removeTagForSelectedRow = function (t, n, r, o) {
    if (
      (console.log("removeTagForSelectedRow", arguments),
      ((o = o || {}).append = o.append || !0),
      (r = r || this.getSelectedId()),
      0 == Boolean(n))
    )
      return !1;
    if (0 == Array.isArray(n)) return !1;
    for (let e = 0; e < n.length; e++) {
      var a = n[e].start || n[e].from,
        i = n[e].end || n[e].to;
      if (void 0 !== a.row && void 0 !== i.row)
        for (var s = a.row; s <= i.row; s++) this.removeTags(r, s, t, o);
    }
    return this.grid.render(), !0;
  }),
  (Trans.prototype.hasTags = function (e, t, n) {
    if (!e) return !1;
    if (void 0 === t) return !1;
    n = n || this.getSelectedId();
    var r = this.getObjectById(n);
    if (!r) return !1;
    if (!r.tags) return !1;
    if (!Array.isArray(r.tags[t])) return !1;
    Array.isArray(e) || (e = [e]);
    try {
      for (var o in e) if (r.tags[t].includes(e[o])) return !0;
      return !1;
    } catch (e) {
      return !1;
    }
  }),
  (Trans.prototype.alert = async function (t, r) {
    return (
      (r = r || 3e3),
      $("#appInfo").attr("title", t),
      new Promise((n, e) => {
        $("#appInfo").tooltip({
          content: function () {
            return t;
          },
          show: { effect: "slideDown", duration: 200 },
          hide: { effect: "fade", delay: 250 },
          position: { my: "left top", at: "left bottom", of: "#table" },
          open: function (e, t) {
            setTimeout(function () {
              $("#appInfo").tooltip("close"),
                $("#appInfo").attr("title", ""),
                n();
            }, r);
          },
        }),
          $("#appInfo").tooltip("open");
      })
    );
  }),
  (Trans.prototype.refreshGrid = function (e) {
    if (
      (((e = e || {}).rebuild = e.rebuild || !1),
      trans.getSelectedId() &&
        (trans.data = trans?.project?.files[trans.getSelectedId()].data),
      trans.data || (trans.data = [[null]]),
      1 == trans.data.length &&
        (0 == Array.isArray(trans.data[0]) && (trans.data = [[null]]),
        0 == Boolean(trans.data[0][0])) &&
        (trans.data = [[null]]),
      0 == trans.data.length && (trans.data = [[null]]),
      trans.getSelectedId() &&
        (trans.project.files[trans.getSelectedId()].data = trans.data),
      "function" == typeof e.onDone &&
        trans.grid.addHookOnce("afterRender", function () {
          e.onDone.call(trans.grid);
        }),
      e.rebuild)
    )
      return trans.grid.destroy(), trans.initTable(), !0;
    trans.grid.updateSettings({
      data: trans.data,
      colHeaders: trans.colHeaders,
      columns: trans.columns,
    }),
      trans.loadComments();
  }),
  (Trans.prototype.editNoteAtCell = function (e) {
    if (void 0 === e)
      try {
        e = trans.grid.getSelectedRange()[0].highlight;
      } catch (e) {
        return console.log(e), !1;
      }
    trans.grid.getPlugin("comments").showAtCell(e.row, e.col),
      $(".htCommentTextArea").trigger("click"),
      $(".htCommentTextArea").focus();
  }),
  (Trans.prototype.removeNoteAtSelected = function (e) {
    if (
      (console.log("trans.removeNoteAtSelected"),
      void 0 === e && (e = trans.grid.getSelectedRange()),
      0 == Boolean(e))
    )
      return console.log("no selection were made"), !1;
    console.log(e);
    for (
      var t = Math.min(e[0].from.row, e[0].to.row),
        n = Math.max(e[0].from.row, e[0].to.row),
        r = Math.min(e[0].from.col, e[0].to.col),
        o = Math.max(e[0].from.col, e[0].to.col),
        a = trans.grid.getPlugin("comments"),
        i = t;
      i <= n;
      i++
    )
      for (var s = r; s <= o; s++) a.removeCommentAtCell(i, s);
  }),
  (Trans.prototype.drawGridTranslatorMenu = function () {
    if (!this.translatorContextMenuIsInitialized) {
      if (
        (console.log("Initializing translator context menu"),
        (TranslatorEngine.translators = TranslatorEngine.translators || {}),
        empty(TranslatorEngine.translators))
      )
        return;
      for (var n in ((this.gridContextMenu.translateUsing.submenu.items = []),
      TranslatorEngine.translators))
        (() => {
          var e = n,
            t = TranslatorEngine.translators[n];
          this.gridContextMenu.translateUsing.submenu.items.push({
            key: "translateUsing:" + e,
            name: t.name,
            callback: () => {
              this.translateSelection(void 0, { translatorEngine: t });
            },
            hidden: () =>
              !!this.grid.isColumnHeaderSelected() ||
              !!this.grid.isRowHeaderSelected() ||
              void 0,
          });
        })();
      this.translatorContextMenuIsInitialized = !0;
    }
    return this.gridContextMenu;
  }),
  (Trans.prototype.getGridContextMenu = function () {
    return this.drawGridTranslatorMenu(), this.gridContextMenu;
  }),
  (Trans.prototype.updateGridContextMenu = function (e) {
    console.log("updateGridContextMenu", e), this.gridContextMenuIsModified;
  }),
  (Trans.prototype.modifyGridContextMenu = function (e) {
    this.gridContextMenuIsModified = !0;
  }),
  (Trans.prototype.calculateTableHeights = async function (e = this.data) {
    console.log("Calculating table height");
    return e?.length
      ? e.length < 1e3
        ? 23 * t(e) + 46
        : (e = await new (require("www/js/CommonWorker.js").Handler)(
            "./www/js/trans.worker.js",
            {
              command: "calculateHeights",
              data: e,
              options: { logTarget: "ui" },
            }
          ).getResult())?.result
        ? 23 * e.result + 46
        : 23
      : 23;
    function t(r) {
      let e = 0;
      for (let n = 0; n < r.length; n++)
        if (r[n]?.length) {
          let t = 1;
          for (let e = 0; e < r[n].length; e++) {
            var o;
            r[n][e] && (o = r[n][e].split("\n").length) > t && (t = o);
          }
          e += t;
        }
      return e < r.length ? r.length : e;
    }
  }),
  (Trans.prototype.initTable = function (e) {
    var n = document.getElementById("table");
    if (0 == Boolean(n)) return !1;
    Handsontable.dom.addEvent(n, "blur", function (e) {
      console.log("event", e);
    }),
      (Handsontable.debugLevel = common.debugLevel()),
      (this.grid = new Handsontable(n, {
        data: trans.data,
        comments: !0,
        rowHeaders: !0,
        colHeaders: trans.colHeaders,
        columns: trans.columns,
        formulas: !1,
        search: !0,
        outsideClickDeselects: !1,
        viewportColumnRenderingOffset: 15,
        maxCols: Trans.maxCols,
        autoRowSize: !1,
        minSpareRows: 1,
        filters: !1,
        dropdownMenu: !1,
        autoWrapRow: !0,
        manualColumnMove: !0,
        manualColumnResize: !0,
        copyPaste: { columnsLimit: 15, rowsLimit: 1e5 },
        beforeChange: function (e, n) {
          if (
            (console.log("beforeChange", arguments),
            console.log(e),
            console.log(n),
            void 0 === trans.selectedData)
          )
            return console.warn("unknown selected data");
          for (var r = 0; r < e.length; r++) {
            if (0 == e[r][1] && e[r][0] < trans.grid.getData().length - 1)
              return (
                console.log(JSON.stringify(e, void 0, 2)),
                trans.alert(t("You should not edit key value")),
                !1
              );
            if (0 == e[r][1]) {
              if (0 == Boolean(e[r][3])) return !1;
              if (trans.isKeyExistOn(e[r][3]))
                return (
                  trans.alert(
                    t("Ilegal value") +
                      " <b>'" +
                      e[r][3] +
                      "'</b> " +
                      t("That value already exist!")
                  ),
                  !1
                );
              "number" == typeof trans.findIdByIndex(e[r][2]) &&
                delete trans.indexIds[e[r][2]],
                (trans.selectedData.indexIds[e[r][3]] = e[r][0]);
            }
          }
        },
        afterChange: function (e, t) {
          if ((trans.gridIsModified(!0), null == e)) return !0;
          if (!trans.getSelectedId()) return !0;
          var n,
            r,
            o = !1,
            a = trans.project.files[trans.getSelectedId()].progress;
          for (n in e)
            0 != Array.isArray(e[n]) &&
              trans.data[e[n][0]][0] &&
              ((e[n][2] = e[n][2] || ""),
              (e[n][3] = e[n][3] || ""),
              e[n][0] == trans.lastSelectedCell[0] &&
                e[n][1] == trans.lastSelectedCell[1] &&
                trans.textEditorSetValue(e[n][3]),
              0 < e[n][2].length && 0 == e[n][3].length
                ? 0 != trans.countFilledCol(e[n][0]) ||
                  a.translated <= 0 ||
                  (a.translated--,
                  0 < a.length
                    ? (a.percent = (a.translated / a.length) * 100)
                    : (a.percent = 0),
                  (o = !0))
                : 0 == e[n][2].length &&
                  0 < e[n][3].length &&
                  (1 != trans.countFilledCol(e[n][0]) ||
                    a.translated >= a.length ||
                    (a.translated++,
                    0 < a.length
                      ? (a.percent = (a.translated / a.length) * 100)
                      : (a.percent = 0),
                    (o = !0))));
          o &&
            (((r = {})[trans.getSelectedId()] = a),
            trans.evalTranslationProgress(trans.getSelectedId(), r)),
            trans.trigger("afterCellChange", [e, t]);
        },
        beforeContextMenuShow: (e) => {
          trans.updateGridContextMenu(e);
        },
        contextMenu: { items: trans.getGridContextMenu() },
        cells: function (e, t, n) {
          var r = {};
          if (0 == t) {
            if (void 0 === trans.data[e]) return r;
            null !== trans.data[e][t] &&
              "" !== trans.data[e][t] &&
              (r.readOnly = !0);
          }
          return r;
        },
        afterSelection: function (e, t, n, r, o, a) {
          console.log("do after selection", arguments),
            trans.trigger("beforeProcessSelection", arguments),
            trans.doAfterSelection(e, t, n, r);
        },
        beforeInit: function () {
          console.log("running before init");
        },
        afterInit: function () {
          trans.buildIndex();
        },
        beforeColumnMove: function (e, t) {
          return (
            console.log("beforeColumnMove"),
            0 != t && 1 != e.includes(0) && (trans.moveColumn(e, t), !0)
          );
        },
        afterColumnMove: function (e, t) {
          return console.log("afterColumnMove"), 0 != t && 1 != e.includes(0);
        },
        afterSetCellMeta: function (t, n, e, r) {
          if ("comment" == e) {
            e = trans.getSelectedObject();
            if (e)
              if (null == r)
                try {
                  delete e.comments[t][n];
                } catch (e) {
                  console.log(
                    "unable to delete comment.\nData row:" +
                      t +
                      ", col:" +
                      n +
                      " is not exist on trans.project.files[trans.getCurrentID].comments!"
                  );
                }
              else
                (e.comments = e.comments || []),
                  (e.comments[t] = e.comments[t] || []),
                  (e.comments[t][n] = r.value);
            return !0;
          }
        },
        afterRender: function (e) {
          if (1 == e) return !0;
          $("#currentCellText").is(":focus") &&
            !1 !== (e = ui.getCurrentEditedCellElm()) &&
            ($("#table .currentCell").removeClass("currentCell"),
            e.addClass("currentCell"));
        },
        afterRenderer: function (e, t, n, r, o, a) {
          e.setAttribute("data-coord", t + "-" + n),
            0 < n &&
              trans.getOption("gridInfo")?.isRuleActive &&
              (trans.getOption("gridInfo")?.viewOrganicCellMarker &&
              trans.isOrganicCell(t, n)
                ? $(e).addClass("organic")
                : trans.getOption("gridInfo")?.viewTrail &&
                  trans.isVisitedCell(t, n) &&
                  $(e).addClass("viewed")),
            0 < n ||
              (t >= trans.data.length - 1 && $(e).addClass("newKeyField"));
        },
        afterGetColHeader: function (e, t) {
          -1 == e && $(t).attr("data-role", "tablecorner");
        },
        afterGetRowHeader: function (t, n) {
          var e,
            r = $(n),
            n = $(n).closest("tr"),
            o = r.find(".rowInfo");
          if (
            (o.length ||
              ((e = r.find(">div")),
              (o = $('<span class="rowInfo"></span>').appendTo(e))),
            void 0 !== trans.selectedData &&
              0 != Array.isArray(trans.selectedData.tags) &&
              0 != Array.isArray(trans.selectedData.tags[t]) &&
              1 != n.hasClass("tagRendered"))
          ) {
            var a = [];
            let e = 0;
            for (var i = 0; i < trans.selectedData.tags[t].length; i++) {
              var s = trans.selectedData.tags[t][i];
              void 0 !== consts.tagColor[s] &&
                ((e += consts.tagStripThickness),
                a.push("inset " + e + "px 0px 0px 0px " + consts.tagColor[s])),
                r.addClass("tag-" + trans.selectedData.tags[t][i]);
            }
            0 != a.length && r.css("box-shadow", a.join(",")),
              n.addClass("hasTag"),
              n.addClass("tagRendered");
          }
          ui.translationByContext &&
            trans.rowHasMultipleContext(t, trans.selectedData) &&
            (r.addClass("hasMC"),
            ui.translationByContext.rowHasContextTranslation(
              t,
              trans.selectedData
            )) &&
            r.addClass("hasTC"),
            (e = trans.getRowInfoText(t)) ? o.text(e) : o.text("");
        },
        afterCreateRow: function (e, t, n) {
          var r = trans.getSelectedId();
          if (0 == Boolean(r)) return !1;
          trans.evalTranslationProgress([r]);
        },
        beforePaste: function (e, t) {},
        afterScrollVertically() {
          this.skipScrollEvent ||
            (this._scrollTimer && clearTimeout(this._scrollTimer),
            (this._scrollTimer = setTimeout(async () => {
              $("#table .wtHolder>*:eq(0)").height() -
                $("#table .wtHolder").scrollTop() -
                $("#table .wtHolder").height() <=
                0 &&
                ($(".newKeyField").visible() ||
                  (this.render(),
                  (this.skipScrollEvent = !0),
                  trans.grid.scrollViewportTo(ui.getFirstFullyVisibleRow()),
                  await common.wait(50),
                  (this.skipScrollEvent = !1)));
            }, 200)));
        },
      })),
      Handsontable.dom.addEvent($("#quickFind")[0], "input", function (e) {
        var t = trans.grid.getPlugin("search").query(this.value);
        console.log(t), trans.grid.render();
      }),
      (trans.grid.autoRowSize = trans.grid.getPlugin("autoRowSize")),
      (trans.grid.isFixedHeight = !0),
      (trans.grid.view.wt.ignoreAdjustElementSize = !1);
    async function r(e = trans.getSelectedId()) {
      !trans.grid.getSettings().autoRowSize ||
        trans.grid.isFixedHeight ||
        trans.data?.length < 1e3 ||
        (console.log("Saving cache rowheights for ", e),
        trans?.localStorage &&
          (console.log(
            "Calculated row heights length ",
            trans.grid.autoRowSize.heights.length,
            "Current row length",
            trans.data.length
          ),
          trans.grid &&
            trans.localStorage.set(
              trans.getSelectedId() + "?rowHeights",
              trans.grid.autoRowSize.heights
            ),
          trans.localStorage.set(trans.getSelectedId() + "?hiderDimension", {
            width: trans.grid.view.wt.wtTable.hider.style.width,
            height: trans.grid.view.wt.wtTable.hider.style.height,
          })));
    }
    (trans.grid.loadRowHeightsCache = async function (e) {
      if (
        trans.grid.getSettings().autoRowSize &&
        !trans.grid.isFixedHeight &&
        !(trans.data?.length < 1e3) &&
        (console.log("start counting rows height on colRange", e),
        trans?.localStorage)
      ) {
        e = await trans.localStorage.get(trans.getSelectedId() + "?rowHeights");
        if ((console.log("Cache row height is", e), e?.length))
          return (
            (trans.grid.autoRowSize.heights = await trans.localStorage.get(
              trans.getSelectedId() + "?rowHeights"
            )),
            (trans.grid.autoRowSize.inProgress = !1),
            (trans.grid.cachedDimension = await trans.localStorage.get(
              trans.getSelectedId() + "?hiderDimension"
            )),
            !0
          );
      }
    }),
      (trans.grid.onCalculateAllRowsHeightStart = async function () {
        ui.tableCornerShowLoading(
          "Counting total rows height. The grid may jumpy while in counting process."
        );
      }),
      (trans.grid.onCalculateAllRowsHeightEnd = async function () {
        trans.data?.length < 1e3 || (ui.tableCornerHideLoading(), r());
      }),
      trans.off("beforeSelectFile"),
      trans.on("beforeSelectFile", function (e, t) {
        console.log("%cbeforeSelectFile", "color:pink", t),
          t?.[0] && t[0] != t[1] && r(t[0]);
      }),
      (trans.grid.setFixedTableHeightByData = async function (e = []) {
        var t, n;
        trans.grid.isFixedHeight &&
          e?.length &&
          ((n = 22 * e.length * 10),
          (t = trans.getSelectedId()),
          trans.grid.setFixedTableHeight(n),
          (n = await trans.calculateTableHeights(e)),
          trans.getSelectedId() === t) &&
          (console.log("Setting actual height", n),
          trans.grid.setFixedTableHeight(n));
      }),
      (trans.grid.setFixedTableHeight = function (e) {
        if (trans.grid.isFixedHeight)
          return (
            "string" == typeof e && e.includes("px")
              ? ((trans.grid.view.wt.wtTable.hider.style.height = e),
                (trans.grid.view.wt.ignoreAdjustElementSize = !0))
              : "number" == typeof e
              ? ((trans.grid.view.wt.wtTable.hider.style.height = e + "px"),
                (trans.grid.view.wt.ignoreAdjustElementSize = !0))
              : "boolean" == typeof e &&
                !1 === e &&
                (trans.grid.view.wt.ignoreAdjustElementSize = !1),
            trans.grid.view.wt.wtTable.hider.style.height
          );
      }),
      (trans.grid.addHeight = function (e = 0) {
        var t = parseInt(trans.grid.view.wt.wtTable.hider.style.height);
        return (
          (trans.grid.view.wt.wtTable.hider.style.height = t + e + "px"),
          trans.grid.view.wt.wtTable.hider.style.height
        );
      }),
      (trans.grid.getTableHeight = function () {
        return trans.grid.view.wt.wtTable.hider.style.height;
      }),
      (trans.grid.isColumnHeaderSelected = function () {
        return Boolean($(".htCore thead th.ht__active_highlight").length);
      }),
      (trans.grid.isRowHeaderSelected = function () {
        return Boolean($(".htCore tr th.ht__active_highlight").length);
      }),
      (trans.grid.insertColumnRight = function (e, n) {
        var r;
        trans.columns.length >= Trans.maxCols
          ? alert(
              t(
                "The maximum number of columns for this project has been reached, so you cannot add any more."
              )
            )
          : ((e = e || "New Col"),
            (n = n || trans.grid.getSelected()[0][1]),
            (r = trans.columns.length),
            trans.columns.push({}),
            common.arrayExchange(trans.columns, r, n + 1),
            common.arrayInsert(trans.colHeaders, n + 1, e),
            console.log(trans.columns),
            trans.insertCell(n + 1, null),
            trans.grid.updateSettings({ colHeaders: trans.colHeaders }));
      }),
      (trans.grid.setColWidth = function (e, t) {
        trans.columns[e] && ((trans.columns[e].width = t), trans.refreshGrid());
      });
  }),
  (Trans.prototype.findAndInsertWithIndexes = function (t = "", n, r, e, o) {
    (r = r || 1),
      (t ||= ""),
      ((o = o || {}).overwrite = o.overwrite || !1),
      (o.files = o.files || []),
      (o.keyColumn = o.keyColumn || this.keyColumn || 0),
      (o.insensitive = o.insensitive || !1),
      (o.lineByLine = o.lineByLine || !1),
      (e = e || this._tempIndexes),
      void 0 === o.ignoreNewLine && (o.ignoreNewLine = !0),
      0 == o.files.length && (o.files = this.getAllFiles());
    var a = { keyword: t, count: 0, executionTime: 0, files: {} },
      i = this.getFromIndexes(t, e, o.customFilter);
    if (
      (!i &&
        t.includes("\r") &&
        ((t = t.replaceAll("\r", "")),
        (a.find = t),
        (i = this.getFromIndexes(t, e, o.customFilter))),
      i)
    )
      for (let e = 0; e < i.length; e++) {
        var s = i[e],
          l = s.file,
          c = s.row;
        if (
          (o.ignoreNewLine &&
            !1 !== Boolean(this.project.files[l].lineBreak) &&
            (t = common.replaceNewLine(t, this.project.files[l].lineBreak)),
          "number" == typeof c)
        ) {
          var d = this.getData(l)[c];
          if (d) {
            if ("blacklist" == o.filterTagMode) {
              if (this.hasTags(o.filterTag, c, l)) continue;
            } else if (
              "whitelist" == o.filterTagMode &&
              !this.hasTags(o.filterTag, c, l)
            )
              continue;
            if (o.lineByLine) {
              var g = (d[r] || "").replaceAll("\r", "").split("\n");
              if (0 == o.overwrite && 1 == Boolean(g[s.line])) continue;
              (g[s.line] = n), (d[r] = g.join("\n"));
            } else {
              if (0 == o.overwrite && 1 == Boolean(d[r])) continue;
              d[r] = n;
            }
            (a.files[l] = a.files[l] || []),
              a.files[l].push({
                fullString: d[r],
                row: c,
                col: r,
                type: "cell",
                lineIndex: null,
              }),
              a.count++;
          }
        }
      }
    return a;
  }),
  (Trans.prototype.findAndInsert = function (t, n, r, o) {
    (r = r || 1),
      ((o = o || {}).overwrite = o.overwrite || !1),
      (o.files = o.files || []),
      (o.keyColumn = o.keyColumn || this.keyColumn || 0),
      (o.insensitive = o.insensitive || !1),
      void 0 === o.ignoreNewLine && (o.ignoreNewLine = !0),
      0 == o.files.length && (o.files = this.getAllFiles());
    var a = { keyword: t, count: 0, executionTime: 0, files: {} };
    for (let e = 0; e < o.files.length; e++) {
      var i,
        s = o.files[e];
      if (
        (o.ignoreNewLine &&
          !1 !== Boolean(this.project.files[s].lineBreak) &&
          (t = common.replaceNewLine(t, this.project.files[s].lineBreak)),
        "number" ==
          typeof (i = o.insensitive
            ? this.getRowIdByTextInsensitive(t, s)
            : this.findIdByIndex(t, s)))
      ) {
        var l = this.getData(s)[i];
        if (l) {
          if ("blacklist" == o.filterTagMode) {
            if (this.hasTags(o.filterTag, i, s)) continue;
          } else if (
            "whitelist" == o.filterTagMode &&
            !this.hasTags(o.filterTag, i, s)
          )
            continue;
          (0 == o.overwrite && 1 == Boolean(l[r])) ||
            ((l[r] = n),
            (a.files[s] = a.files[s] || []),
            a.files[s].push({
              fullString: l[r],
              row: i,
              col: r,
              type: "cell",
              lineIndex: null,
            }),
            a.count++);
        }
      }
    }
    return a;
  }),
  (Trans.prototype.findAndInsertLine = function (t, n, r, o) {
    if (
      ((r = r || 1),
      ((o = o || {}).overwrite = o.overwrite || !1),
      (o.files = o.files || []),
      (o.keyColumn = o.keyColumn || 0),
      (o.newLine = o.newLine || void 0),
      (o.stripCarriageReturn = o.stripCarriageReturn || !1),
      o.stripCarriageReturn && (t = common.stripCarriageReturn(t)),
      0 == o.files.length)
    )
      if (void 0 !== trans.allFiles) o.files = trans.allFiles;
      else {
        for (var a in trans.project.files) o.files.push(a);
        trans.allFiles = o.files;
      }
    for (var e = 0; e < o.files.length; e++)
      for (
        var i,
          a = o.files[e],
          s = trans.project.files[a].data,
          l = o.newLine || trans.project.files[a].lineBreak || "\n",
          c = 0;
        c < s.length;
        c++
      ) {
        let e;
        if (s[c][o.keyColumn]) {
          if ("blacklist" == o.filterTagMode) {
            if (this.hasTags(o.filterTag, c, a)) continue;
          } else if (
            "whitelist" == o.filterTagMode &&
            !this.hasTags(o.filterTag, c, a)
          )
            continue;
          (s[c][o.keyColumn] = s[c][o.keyColumn] || ""),
            0 !=
              (e = (
                o.stripCarriageReturn
                  ? s[c][o.keyColumn].replaceAll("\r", "")
                  : s[c][o.keyColumn]
              ).split("\n")).includes(t) &&
              ((s[c][r] = s[c][r] || ""),
              (i = s[c][r].replaceAll("\r", "").split("\n")),
              (i = common.searchReplaceArray(e, i, t, n, {
                overwrite: o.overwrite,
              })),
              (s[c][r] = i.join(l)));
        }
      }
  }),
  (Trans.prototype.findAndInsertByContext = function (t, n, r, o) {
    (r = r || 1),
      ((o = o || {}).overwrite = o.overwrite || !1),
      (o.files = o.files || []),
      (o.ignoreNewLine = o.ignoreNewLine || !1),
      0 == o.files.length && (o.files = this.getAllFiles());
    for (let e = 0; e < o.files.length; e++) {
      var a = o.files[e],
        i = this.getObjectById(a);
      if (0 != Boolean(i) && 0 != Boolean(i.context))
        for (var s = 0; s < i.context.length; s++) {
          var l = i.context[s];
          if (
            0 != Array.isArray(l) &&
            !(l.length < 1) &&
            0 != Array.isArray(i.data[s])
          )
            for (var c = 0; c < l.length; c++)
              t !== l[c] ||
                (0 == o.overwrite && 1 == Boolean(i.data[s][r])) ||
                (i.data[s][r] = n);
        }
    }
  }),
  (Trans.prototype.translateTextByLine = function (e, t, n) {
    if ("string" != typeof e) return e;
    if (e.length < 1) return e;
    for (
      var r = [], o = e.replace(/(\r\n)/gm, "\n").split("\n"), a = 0;
      a < o.length;
      a++
    ) {
      var i = o[a];
      t[i] ? r.push(t[i]) : r.push("");
    }
    return r.join("\n");
  }),
  (Trans.prototype.translateFromArray = function (e, t, n) {
    if (
      (console.log("insert trans.translateFromArray", arguments),
      (t = t || 1),
      ((n = n || {}).sourceColumn = n.sourceColumn || "auto"),
      (n.overwrite = n.overwrite || !1),
      (n.files = n.files || []),
      (n.sourceKeyColumn = n.sourceKeyColumn || 0),
      (n.keyColumn = n.keyColumn || 0),
      (n.newLine = n.newLine || void 0),
      (n.stripCarriageReturn = n.stripCarriageReturn || !1),
      (n.ignoreNewLine = !0),
      0 == (e = e || []).length)
    )
      return !1;
    n.indexes ||
      (console.log("%cbuilding index", "color:salmon;"),
      0 == n.files?.length && (n.files = this.getAllFiles()),
      (n.indexes = this.buildIndexes(n.files, !1))),
      console.log("options.indexes", n.indexes);
    for (var r = 0; r < e.length; r++) {
      var o,
        a = e[r];
      0 != Boolean(a[n.sourceKeyColumn]) &&
        ((o = a[n.sourceKeyColumn]),
        (a =
          "auto" == n.sourceColumn
            ? trans.getTranslationFromRow(a, n.sourceKeyColumn)
            : a[n.sourceColumn]),
        trans.findAndInsertWithIndexes(o, a, t, n.indexes, {
          overwrite: n.overwrite,
          files: n.files,
        }));
    }
  }),
  (Trans.prototype.abortTranslation = function () {
    (trans.translator = trans.translator || []),
      void 0 !== trans.translationTimer && clearTimeout(trans.translationTimer);
    for (var e = 0; e < trans.translator.length; e++) {
      var t = trans.translator[e],
        t = trans.getTranslatorEngine(t);
      if (t) {
        if ("function" == typeof t.abort)
          try {
            t.abort();
          } catch (e) {
            ui.log("Failed to abort with message", e.toString());
          }
        (t.job = t.job || {}), (t.job.wordcache = {}), (t.job.batch = []);
      }
    }
    ui.hideLoading(), trans.refreshGrid(), trans.evalTranslationProgress();
  }),
  (Trans.prototype.translateStringByPair = function (e, t, n) {
    if (((n = n || !1), "string" == typeof e && "object" == typeof t))
      for (var r in t) e = e.replaces(r, t[r], n);
    return e;
  }),
  (Trans.prototype.translateFromTrans = function (e, r = [], t = this) {
    if (!e) return "";
    "string" == typeof r && (r = [r]);
    var t = t?.project?.files || {},
      n =
        (r?.length || (r = this.getAllFiles(t)),
        (e) => {
          for (var t in r) {
            var t = r[t],
              n = this.getIndexByKey(t, e);
            if (void 0 !== n) {
              t = this.getData(t);
              if (empty(t[n])) return "";
              t = this.getTranslationFromRow(t[n]);
              if (t) return t;
            }
          }
        });
    if (Array.isArray(e)) {
      var o,
        a = [];
      for (o in e) a[o] = n(e[o]) || "";
      return a;
    }
    return n(e);
  }),
  (Trans.prototype.getReference = function (e, t = "Common Reference") {
    return (
      (e &&
        void 0 !== (e = this.getIndexByKey(t, e)) &&
        ((t = this.getData(t)), !empty(t[e])) &&
        this.getTranslationFromRow(t[e])) ||
      ""
    );
  }),
  (Trans.prototype.translateByReference = function (
    e,
    t,
    n = "Common Reference"
  ) {
    if (((t = t || !1), trans.project.files[n])) {
      var r;
      if (
        ((trans.project.files[n].cacheResetOnChange =
          trans.project.files[n].cacheResetOnChange || {}),
        !1 !== Boolean(trans.project.files[n].cacheResetOnChange.transPair)
          ? (r = trans.project.files[n].cacheResetOnChange.transPair)
          : ((r = trans.generateTranslationPair(trans.project.files[n].data)),
            (trans.project.files[n].cacheResetOnChange.transPair = r)),
        "string" == typeof e)
      )
        return (o = trans.translateStringByPair(e, r, t));
      if (Array.isArray(e)) {
        for (var o = [], a = 0; a < e.length; a++)
          o[a] = trans.translateStringByPair(e[a], r, t);
        return o;
      }
    }
    return e;
  }),
  (Trans.prototype.rowHasTranslation = function (
    t = [],
    n = this.keyColumn,
    r
  ) {
    if (t && t.length)
      if (((n = this.keyColumn || 0), null == r)) {
        for (let e = 0; e < t.length; e++) if (e != n && t[e]) return !0;
      } else {
        Array.isArray(r) || (r = [r]);
        for (let e = 0; e < r.length; e++) if (r[e] != n && t[r[e]]) return !0;
      }
    return !1;
  }),
  (Trans.prototype.translateAll = async function (e, t) {
    var n = this.getTranslatorEngine(e);
    return (
      this.buildIndex("Common Reference", !0),
      "function" == n.translateAll
        ? n.translateAll(t)
        : "v2" == n.translatorType
        ? this.batchTranslate(n, t)
        : void ("rowByRow" == n.mode
            ? trans.translateAllByRows(e, t)
            : trans.translateAllByLines(e, t))
    );
  }),
  (Trans.prototype.batchTranslate = async function (e, n) {
    let r = new BatchTranslate(e, n);
    await ui.log.start({
      buttons: [
        {
          text: "Abort",
          onClick: function (e) {
            confirm(t("Are you sure want to abort this process?")) && r.abort();
          },
        },
        {
          text: "Pause",
          onClick: function (e) {
            alert(t("Process paused!\nPress OK to continue!"));
          },
        },
      ],
    }),
      await r.translateAll(),
      await ui.log.end(),
      await this.onBatchTranslationDone(n);
  }),
  (Trans.prototype.translateAllByRows = async function (e, i) {
    console.log("Running trans.translateAll", i),
      ui.loadingProgress(0, "Running trans.translateAll");
    var s = this.getTranslatorEngine(e);
    if (void 0 === trans.project)
      return trans.alert(t("Unable to process, project not found"));
    if (void 0 === trans.project.files)
      return trans.alert(t("Unable to process, data not found"));
    if (void 0 === s) return trans.alert(t("Translation engine not found"));
    if (s.isDisabled)
      return trans.alert(t("Translation engine ") + e + t(" is disabled!"));
    trans.getSelectedId() ||
      trans.selectFile($(".fileList .data-selector").eq(0)),
      ((i = i || {}).onFinished = i.onFinished || function () {}),
      (i.keyColumn = i.keyColumn || 0),
      (i.translateOther = i.translateOther || !1),
      (i.ignoreTranslated = i.ignoreTranslated || !1),
      (i.overwrite = i.overwrite || !1),
      (i.saveOnEachBatch = i.saveOnEachBatch || !1),
      (s.job = s.job || {}),
      (s.job.wordcache = {}),
      (s.job.batch = []),
      (s.batchDelay = s.batchDelay || trans.config.batchDelay);
    var n,
      r = trans.config.maxRequestLength,
      o =
        (s.maxRequestLength < r && (r = s.maxRequestLength),
        ui.showLoading({
          buttons: [
            {
              text: "Abort",
              onClick: function (e) {
                confirm(t("Are you sure want to abort this process?")) &&
                  trans.abortTranslation();
              },
            },
            {
              text: "Pause",
              onClick: function (e) {
                alert(t("Process paused!\nPress OK to continue!"));
              },
            },
          ],
        }),
        ui.log("Start batch translation in Row by Row mode, with options:", i),
        ui.log("Translator is: " + e),
        console.log("Current maximum request length : " + r),
        console.log("Start collecting data!"),
        ui.loadingProgress(0, "Start collecting data!"),
        0),
      a = 0,
      l = {},
      c = trans.getCheckedFiles();
    for (n in (ui.loadingProgress(void 0, t("Selected files :") + c.join(", ")),
    (c = 0 == c.length ? this.getAllFiles() : c))) {
      var d = c[n];
      ui.loadingProgress(void 0, t("Collecting data from :") + d);
      try {
        var g = trans.project.files[d].data;
      } catch (e) {
        console.warn("Can not access", d, "in trans.project.files");
        continue;
      }
      void 0 === s.job.batch[o] && (s.job.batch[o] = []);
      for (var f = 0; f < g.length; f++)
        if (g[f][0]) {
          var u = g[f][i.keyColumn],
            p = str_ireplace(
              $DV.config.lineSeparator,
              s.lineSubstitute,
              s.escapeCharacter(u)
            );
          if (u) {
            if ("blacklist" == i.filterTagMode) {
              if (this.hasTags(i.filterTag, f, d)) continue;
            } else if (
              "whitelist" == i.filterTagMode &&
              !this.hasTags(i.filterTag, f, d)
            )
              continue;
            (i.ignoreTranslated && this.rowHasTranslation(g[f], i.keyColumn)) ||
              (0 == i.overwrite && g[f][s.targetColumn]
                ? console.log(
                    "Ignored because overwite options",
                    i.overwrite,
                    g[f][s.targetColumn]
                  )
                : 0 != u.trim().length &&
                  ((l[u] = g[f][0]),
                  p.length > r
                    ? (console.log(
                        "current sentence is bigger than maxRequestLength!"
                      ),
                      o++,
                      (s.job.batch[o] = s.job.batch[o] || []),
                      s.job.batch[o].push(u),
                      o++,
                      (a = 0))
                    : p.length + a > r
                    ? (o++,
                      (s.job.batch[o] = s.job.batch[o] || []),
                      s.job.batch[o].push(u),
                      (a = 0))
                    : void 0 === s.job.wordcache[u] &&
                      ((s.job.wordcache[u] = !0),
                      (s.job.batch[o] = s.job.batch[o] || []),
                      s.job.batch[o].push(u),
                      (a += p.length))));
          }
        }
    }
    await ui.log("Generating indexes");
    var h = this.buildIndexes(c),
      m =
        ((s.job.batchLength = s.job.batch.length),
        console.log("current batch:", s.job.batch),
        ui.loadingProgress(0, "Data collection is done!"),
        console.log("Data collection is done!"),
        console.log("We have " + s.job.batch.length + " batch totals!"),
        console.log("=========================================="),
        console.log("Begin translating using " + e + "!"),
        async function () {
          if (void 0 === s.job.batch) return "batch job undefined, quiting!";
          if (s.job.batch.length < 1)
            return (
              console.log("Batch job is finished"),
              trans.refreshGrid(),
              trans.evalTranslationProgress(),
              "function" == typeof i.onFinished && i.onFinished.call(this),
              ui.loadingProgress(100, t("Translation finished")),
              ui.loadingClearButton(),
              ui.loadingEnd(),
              trans.onBatchTranslationDone(i),
              (trans.translationTimer = void 0),
              "batch job is finished!"
            );
          console.log("running processPart");
          var e,
            a = s.job.batch.pop();
          console.log("current data : "),
            console.log(a),
            (e = s.skipReferencePair ? a : trans.translateByReference(a)),
            s.translate(e, {
              mode: "rowByRow",
              onAfterLoading: async function (e) {
                if ((console.log(e), void 0 !== e.translation)) {
                  console.log("applying translation to table !"),
                    console.log("calculating progress");
                  var n,
                    r = 100 - (s.job.batch.length / s.job.batchLength) * 100,
                    o =
                      (ui.loadingProgress(
                        r,
                        t("applying translation to table!")
                      ),
                      c);
                  for (n in (i.translateOther && (o = trans.getAllFiles()),
                  trans.trigger("batchTranslationResult", {
                    original: a,
                    translation: e.translation,
                    translator: s,
                  }),
                  e.translation))
                    trans.findAndInsertWithIndexes(
                      l[a[n]],
                      e.translation[n],
                      s.targetColumn,
                      h,
                      {
                        filterTag: i.filterTag || [],
                        filterTagMode: i.filterTagMode,
                        keyColumn: i.keyColumn,
                        overwrite: i.overwrite,
                        files: o,
                      }
                    );
                  i.saveOnEachBatch &&
                    (ui.log("Saving your project"), await trans.save()),
                    ui.loadingProgress(
                      void 0,
                      s.job.batchLength -
                        s.job.batch.length +
                        "/" +
                        s.job.batchLength +
                        " batch done, waiting " +
                        s.batchDelay +
                        " ms..."
                    ),
                    (trans.translationTimer = setTimeout(function () {
                      m();
                    }, s.batchDelay));
                }
              },
              onError: function (e, n, r) {
                console.log("ERROR on transling data");
                var o = 100 - (s.job.batch.length / s.job.batchLength) * 100;
                ui.loadingProgress(
                  o,
                  t("Error when translating data!") +
                    "\r\n" +
                    t("\tHTTP Status : ") +
                    e.status +
                    "\r\n" +
                    t("\tError Type : ") +
                    r +
                    "\r\n" +
                    t(
                      "You are probably temporarily banned by your translation service!\r\nPlease use online translation service in moderation\r\nThis usualy fixed by itself within a day or two.\r\n"
                    )
                ),
                  ui.loadingProgress(
                    void 0,
                    s.job.batchLength -
                      s.job.batch.length +
                      "/" +
                      s.job.batchLength +
                      t(" batch done, ") +
                      t("waiting ") +
                      s.batchDelay +
                      t(" ms...")
                  ),
                  (trans.translationTimer = setTimeout(function () {
                    m();
                  }, s.batchDelay));
              },
            });
        });
    m();
  }),
  (Trans.prototype.translateAllByLines = async function (e, i) {
    console.log("Running trans.translateAllByLines", arguments),
      ui.loadingProgress(0, t("Running trans.translateAll"));
    var s = this.getTranslatorEngine(e);
    if (void 0 === trans.project)
      return trans.alert(t("Unable to process, project not found"));
    if (void 0 === trans.project.files)
      return trans.alert(t("Unable to process, data not found"));
    if (void 0 === s) return trans.alert(t("Translation engine not found"));
    if (s.isDisabled)
      return trans.alert(t("Translation engine ") + e + t(" is disabled!"));
    trans.getSelectedId() ||
      trans.selectFile($(".fileList .data-selector").eq(0)),
      ((i = i || {}).onFinished = i.onFinished || function () {}),
      (i.keyColumn = i.keyColumn || 0),
      (i.translateOther = i.translateOther || !1),
      (i.ignoreTranslated = i.ignoreTranslated || !1),
      (i.overwrite = i.overwrite || !1),
      (i.saveOnEachBatch = i.saveOnEachBatch || !1);
    var n,
      r = i.ignoreTranslated ? "untranslated" : "both",
      o =
        ((s.job = s.job || {}),
        (s.job.wordcache = {}),
        (s.job.batch = []),
        (s.batchDelay = s.batchDelay || trans.config.batchDelay),
        trans.config.maxRequestLength),
      a =
        (s.maxRequestLength < o && (o = s.maxRequestLength),
        ui.showLoading({
          buttons: [
            {
              text: "Abort",
              onClick: function (e) {
                confirm(t("Are you sure want to abort this process?")) &&
                  trans.abortTranslation();
              },
            },
            {
              text: "Pause",
              onClick: function (e) {
                alert(t("Process paused!\nPress OK to continue!"));
              },
            },
          ],
        }),
        ui.log(
          "Start batch translation in Line by Line mode, with options:",
          i
        ),
        ui.log("Translator is: " + e),
        console.log("Current maximum request length : " + o),
        console.log("Start collecting data!"),
        ui.loadingProgress(0, t("Start collecting data!")),
        0),
      l = 0,
      c = trans.getCheckedFiles(),
      d =
        (ui.loadingProgress(void 0, t("Selected files :") + c.join(", ")),
        trans.generateTranslationTableLine(trans.project, {
          files: c,
          mode: "lineByLine",
          fetch: r,
          keyColumn: i.keyColumn,
          filterLanguage: this.getSl(),
          filterTag: i.filterTag || [],
          filterTagMode: i.filterTagMode,
          ignoreTranslated: i.ignoreTranslated,
          targetColumn: s.targetColumn,
          overwrite: i.overwrite,
          ignoreWhitespace: s.ignoreWhitespace,
          collectAddress: !0,
        })),
      g = d.pairs;
    for (n in (console.log("Fetch mode : ", r),
    console.log("Translatable : ", g),
    (l = a = 0),
    g)) {
      s.job.batch[a] = s.job.batch[a] || [];
      var f = n,
        u = str_ireplace(
          $DV.config.lineSeparator,
          s.lineSubstitute,
          s.escapeCharacter(f)
        );
      0 != Boolean(f) &&
        "string" == typeof f &&
        0 != f.trim().length &&
        (u.length > o
          ? (console.log("current sentence is bigger than maxRequestLength!"),
            a++,
            (s.job.batch[a] = s.job.batch[a] || []),
            s.job.batch[a].push(f),
            a++,
            (l = 0))
          : u.length + l > o
          ? (a++,
            (s.job.batch[a] = s.job.batch[a] || []),
            s.job.batch[a].push(f),
            (l = 0))
          : ((s.job.batch[a] = s.job.batch[a] || []),
            s.job.batch[a].push(f),
            (l += u.length)));
    }
    (s.job.batchLength = s.job.batch.length),
      ui.loadingProgress(0, t("Data collection is done!")),
      console.log("Data collection is done!"),
      console.log("We have " + s.job.batch.length + " batch totals!"),
      console.log("=========================================="),
      console.log("Begin translating using " + e + "!"),
      await ui.log("Generating indexes");
    var r = this.buildIndexes(c, !0),
      p =
        (console.log("indexes:", r),
        async function () {
          var e, n;
          return void 0 === s.job.batch
            ? "batch job undefined, quiting!"
            : s.job.batch.length < 1
            ? (console.log("Batch job is finished"),
              (e = []),
              0 == i.translateOther && (e = trans.getCheckedFiles()),
              trans.fillEmptyLine(e, [], s.targetColumn, i.keyColumn, {
                lineFilter: function (e) {
                  return !common.isInLanguage(e, trans.getSl());
                },
                fromKeyOnly: i.ignoreTranslated,
                filterTag: i.filterTag || [],
                filterTagMode: i.filterTagMode,
                overwrite: i.overwrite,
              }),
              trans.refreshGrid(),
              trans.evalTranslationProgress(),
              "function" == typeof i.onFinished && i.onFinished.call(this),
              ui.loadingProgress(100, t("Translation finished")),
              ui.loadingClearButton(),
              ui.loadingEnd(),
              trans.onBatchTranslationDone(i),
              (trans.translationTimer = void 0),
              "batch job is finished!")
            : ((n = async function () {
                console.log("running processPart");
                var e,
                  o = [],
                  a =
                    (0 == i.translateOther && (o = trans.getCheckedFiles()),
                    trans.fillEmptyLine(o, [], s.targetColumn, i.keyColumn, {
                      lineFilter: function (e) {
                        return !common.isInLanguage(e, trans.getSl());
                      },
                      fromKeyOnly: i.ignoreTranslated,
                      filterTag: i.filterTag || [],
                      filterTagMode: i.filterTagMode,
                      overwrite: i.overwrite,
                    }),
                    s.job.batch.pop());
                console.log("current data : "),
                  console.log(a),
                  (e = s.skipReferencePair ? a : trans.translateByReference(a)),
                  s.translate(e, {
                    onAfterLoading: async function (e) {
                      if (
                        (console.log("onAfterLoading translation result:", e),
                        void 0 !== e.translation)
                      ) {
                        console.log("applying translation to table !");
                        var n,
                          r =
                            100 -
                            (s.job.batch.length / s.job.batchLength) * 100;
                        for (n in (ui.loadingProgress(
                          r,
                          t("applying translation to table!")
                        ),
                        trans.trigger("batchTranslationResult", {
                          original: a,
                          translation: e.translation,
                          translator: s,
                        }),
                        e.translation))
                          trans.findAndInsertWithIndexes(
                            a[n],
                            e.translation[n],
                            s.targetColumn,
                            d.addresses,
                            {
                              files: o,
                              keyColumn: i.keyColumn,
                              stripCarriageReturn: !0,
                              filterTag: i.filterTag || [],
                              filterTagMode: i.filterTagMode,
                              overwrite: i.overwrite,
                              lineByLine: !0,
                            }
                          );
                        i.saveOnEachBatch &&
                          (ui.log("Saving your project"), await trans.save()),
                          ui.loadingProgress(
                            void 0,
                            s.job.batchLength -
                              s.job.batch.length +
                              "/" +
                              s.job.batchLength +
                              " batch done!"
                          ),
                          p();
                      }
                    },
                    onError: function (e, n, r) {
                      console.log("ERROR on transling data");
                      var o =
                        100 - (s.job.batch.length / s.job.batchLength) * 100;
                      ui.loadingProgress(
                        o,
                        t("Error when translating data!") +
                          "\r\n" +
                          t("\tHTTP Status : ") +
                          e.status +
                          "\r\n" +
                          t("\tError Type : ") +
                          r +
                          "\r\n" +
                          t(
                            "You are probably temporarily banned by your translation service!\r\nPlease use online translation service in moderation\r\nThis usualy fixed by itself within a day or two.\r\n"
                          )
                      ),
                        ui.loadingProgress(
                          void 0,
                          s.job.batchLength -
                            s.job.batch.length +
                            "/" +
                            s.job.batchLength +
                            " batch done!"
                        ),
                        p();
                    },
                  });
              }),
              void (s.job.batchLength == s.job.batch.length
                ? n()
                : (ui.loadingProgress(
                    void 0,
                    "Waiting " + s.batchDelay + " ms..."
                  ),
                  (trans.translationTimer = setTimeout(function () {
                    n();
                  }, s.batchDelay)))));
        });
    p();
  }),
  (Trans.prototype.onBatchTranslationDone = function (e) {
    var t;
    e.playSoundOnComplete &&
      (t = new Audio("/www/audio/done.mp3")).addEventListener(
        "canplay",
        (e) => {
          t.play();
        }
      );
  }),
  (Trans.prototype.getTranslatorEngine = function (e) {
    return (
      TranslatorEngine.translators[e] ||
      (this[e] instanceof TranslatorEngine
        ? this[e]
        : e instanceof TranslatorEngine
        ? e
        : void console.warn(e, " is not a translator engine"))
    );
  }),
  (Trans.prototype.getActiveTranslatorEngine = function () {
    return this.getTranslatorEngine(this.getActiveTranslator());
  }),
  (Trans.prototype.setActiveTranslator = function (e) {
    (e = "string" == typeof e ? this.getTranslatorEngine(e) : e)?.id &&
      this.setOption("translator", e.id);
  }),
  (Trans.prototype.translateSelection = async function (n, r = {}) {
    this.buildIndex("Common Reference", !0);
    var o = this;
    if (void 0 === (n = n || o.grid.getSelectedRange() || [[]]))
      return alert(t("nothing is selected")), !1;
    if (void 0 === o.translator || o.translator.length < 1)
      return alert(t("no translator loaded")), !1;
    var a = r.translatorEngine || this.getActiveTranslatorEngine();
    if (
      ((r.mode ||= a.mode),
      (r.ignoreWhitespace ||= a.ignoreWhitespace),
      console.log("translating selection ", r.mode),
      1 == a.isDisabled)
    )
      return alert(a.id + " is disabled!");
    ui.tableCornerShowLoading();
    for (
      var i = [],
        e = o.grid.getData(),
        s = common.gridSelectedCells() || [],
        l = [],
        c = 0;
      c < s.length;
      c++
    )
      s[c].col != this.keyColumn && l.push(e[s[c].row][this.keyColumn]);
    if (l) {
      console.log("Text pool", l);
      var d,
        g,
        f = o.generateTranslationTableFromStrings(l, a, r);
      for (d in (console.log(
        "Translation table:",
        JSON.stringify(f, void 0, 2)
      ),
      (f = (await this.processWith("translationTableFilter", f, a)) || f),
      console.warn("Filtered translationTable", JSON.stringify(f, void 0, 2)),
      f.include))
        i.push(d);
      console.log(i),
        console.log(s),
        s.length < 1
          ? ui.tableCornerHideLoading()
          : ((g = a.skipReferencePair ? i : o.translateByReference(i)),
            console.log("Translate using : ", a.id),
            a.translate(g, {
              onAfterLoading: async function (e) {
                console.log("Translation result:"),
                  console.log(e),
                  console.log("text pool :"),
                  console.log(i),
                  console.log("rowpool:"),
                  console.log(s),
                  console.log("translation result : "),
                  o.trigger("batchTranslationResult", {
                    original: i,
                    translation: e.translation,
                    translator: a,
                  });
                e = o.generateTranslationTableFromResult(
                  i,
                  e.translation,
                  f.exclude
                );
                console.log("translation table : "),
                  console.log(e),
                  o.applyTransTableToSelectedCell(e, n, void 0, r),
                  ui.tableCornerHideLoading(),
                  o.grid.render(),
                  o.evalTranslationProgress(),
                  o.textEditorSetValue(o.getTextFromLastSelected());
              },
            }));
    }
  }),
  (Trans.prototype.translateSelectionByRow = async function (e, t = {}) {
    return (t.mode = "rowByRow"), this.translateSelection(e, (t = {}));
  }),
  (Trans.prototype.translateSelectionByLine = async function (e, t = {}) {
    return (t.mode = "lineByLine"), this.translateSelection(e, (t = {}));
  }),
  (Trans.prototype.translateSelectionAsOneLine = async function (o, e = {}) {
    if (
      (console.log("Merge to one line then translate"),
      void 0 === (o = o || trans.grid.getSelectedRange() || [[]]))
    )
      return alert(t("nothing is selected")), !1;
    if (void 0 === trans.translator || trans.translator.length < 1)
      return alert(t("no translator loaded")), !1;
    for (
      var e = e.translatorEngine || this.getActiveTranslatorEngine(),
        a = this.getSelectedOriginalTexts(o),
        n = this.getSelectedOriginalTextsAsOneLine(o),
        r = common.gridSelectedRows(o),
        i = {},
        s = 0;
      s < r.length;
      s++
    )
      i[r[s]] = s;
    console.log("Row index:", i);
    var l = this.getData();
    console.log("Original text:", a),
      ui.tableCornerShowLoading(),
      (n = e.skipReferencePair ? n : trans.translateByReference(n)),
      console.log("Translating", n),
      e.translate(n, {
        mode: "rowByRow",
        onAfterLoading: (e) => {
          if (void 0 !== e.translation) {
            console.log("result translation:", e.translation);
            for (
              var t = common.cloneFormatting(a, e.translation.join(" ")),
                n =
                  (console.log("Formatted result:", t),
                  console.log(
                    "Write back the translated result according to the row"
                  ),
                  common.gridSelectedCells(o)),
                r = 0;
              r < n.length;
              r++
            )
              n[r].col != this.keyColumn &&
                (l[n[r].row][n[r].col] = t[i[n[r].row]]);
          }
          ui.tableCornerHideLoading(),
            trans.grid.render(),
            trans.evalTranslationProgress(),
            trans.textEditorSetValue(trans.getTextFromLastSelected());
        },
      });
  }),
  (Trans.prototype.translateSelectionIntoDef = function (e) {
    if (
      (console.log("translating selection into default coloumn"),
      void 0 === (e = e || trans.grid.getSelected() || [[]]))
    )
      return alert(t("nothing is selected")), !1;
    if (void 0 === trans.translator || trans.translator.length < 1)
      return alert(t("no translator loaded")), !1;
    for (var n = [], r = trans.grid.getData(), o = [], a = 0; a < e.length; a++)
      for (var i = e[a][0]; i <= e[a][2]; i++) o.push(i), n.push(r[i][0]);
    var s = n;
    console.log(s), console.log(o);
    for (var l = 0; l < trans.translator.length; l++) {
      console.log(l);
      var c = trans.translator[l],
        d = this.getTranslatorEngine(c);
      1 != d.isDisabled &&
        (void 0 === d.targetColumn
          ? console.warn(
              "Skipping. Reason : TargetColumn property is not set for engine ",
              c
            )
          : ((c = trans.translateByReference(s)),
            d.translate(c, {
              onAfterLoading: function (e) {
                if (void 0 !== e.translation)
                  for (var t in e.translation)
                    trans.data[o[t]][d.targetColumn] = e.translation[t];
                trans.grid.render(), trans.evalTranslationProgress();
              },
            })));
    }
  }),
  (Trans.prototype.applyTransTableToSelectedCell = function (n, e, r, o) {
    if (
      ((r = r || trans.data),
      (e = e || trans.grid.getSelected() || [[]]),
      ((o = o || {}).indexKey = o.indexKey || 0),
      void 0 === e)
    )
      return alert(t("nothing is selected")), !1;
    var a = common.gridSelectedCells(e) || [];
    if ("rowByRow" == o.mode)
      for (let e = 0; e < a.length; e++) {
        var i = a[e].col,
          s = a[e].row;
        i != this.keyColumn &&
          0 != Array.isArray(r[s]) &&
          (r[s][i] = n[r[s][o.indexKey]]);
      }
    else
      for (let e = 0; e < a.length; e++) {
        var l = a[e].col,
          c = a[e].row;
        l != this.keyColumn &&
          0 != Array.isArray(r[c]) &&
          (r[c][l] = this.translateTextByLine(r[c][o.indexKey], n));
      }
  }),
  (Trans.prototype.translateSelectedRow = function (e, n) {
    return (
      void 0 !== e &&
      0 != trans.config.autoTranslate &&
      !!(e = trans.data[e][(n = n || 0)]) &&
      ((n = $("#translationPane")[0].contentWindow),
      (n = ui.windows.translator ? ui.windows.translator : n).translator
        ? (n.translator.translateAll(e), !0)
        : t("unable to load translator window"))
    );
  }),
  (Trans.prototype.getTranslationByIndex = function (e) {
    var t;
    return (
      void 0 !== e &&
      ((t = $("#translationPane")[0].contentWindow),
      (t = ui.windows.translator ? ui.windows.translator : t)
        .$(".mainPane .portlet")
        .eq(e)
        .find(".portlet-content")
        .text())
    );
  }),
  (Trans.prototype.importTranslation = async function (r, f) {
    if ((console.log("importTranslation", arguments), void 0 === r))
      return trans.alert(t("Reference path cannot empty!"));
    ((f = f || {}).targetColumn = f.targetColumn || 1),
      (f.overwrite = f.overwrite || !1),
      (f.files = f.files || []),
      (f.destination = f.destination || []),
      (f.compareMode = f.compareMode || 0),
      (f.ignoreLangCheck = !0),
      (f.destinationMode = f.destinationMode || "selected"),
      (f.caseInsensitive ||= !1),
      console.log("refPath & options : "),
      console.log(arguments),
      trans.getSelectedId() ||
        trans.selectFile($(".panel-left .fileList .data-selector").eq(0));
    var u = void 0,
      o =
        (f.caseInsensitive &&
          (u = function (e) {
            return e.toLowerCase().replaceAll("\r", "");
          }),
        async (n) => {
          console.log("Applying translation"),
            ui.loadingProgress(30, t("Collecting translation refference")),
            await ui.log("Collecting translation refference");
          var r,
            o = {};
          if ("lineByLine" == f.compareMode) {
            o = trans.generateTranslationTableLine(n.project.files, f);
            let e;
            "selected" == f.destinationMode && (e = this.getCheckedFiles()),
              (r = this.buildIndexes(e, !0, { customFilter: u }));
          } else if ("rowByRow" == f.compareMode) {
            o = trans.generateTranslationTable(n.project.files, f);
            let e;
            "selected" == f.destinationMode && (e = this.getCheckedFiles()),
              (r = this.buildIndexes(e, !1, { customFilter: u }));
          } else
            "contextTrans" == f.compareMode &&
              (o = trans.generateContextTranslationPair(n.project.files, f));
          n = trans.mergeReference(n);
          var e = Object.keys(o).length,
            a =
              (await ui.log(`Processing ${e} reference(s)`),
              ui.loadingProgress(50, t("Applying translation!")),
              0),
            i = 50;
          if ("lineByLine" == f.compareMode)
            for (var s in o) {
              var l = s;
              f.caseInsensitive && (s = u(s)),
                trans.findAndInsertWithIndexes(s, o[l], f.targetColumn, r, {
                  overwrite: f.overwrite,
                  files: f.destination,
                  lineByLine: !0,
                  customFilter: u,
                }),
                ui.loadingProgress(50 + (a / e) * 50),
                a++;
            }
          else if ("rowByRow" == f.compareMode)
            for (var c in (console.log("Row by Row translation"), o)) {
              var d = c,
                c =
                  (f.caseInsensitive && (c = u(c)),
                  trans.findAndInsertWithIndexes(c, o[d], f.targetColumn, r, {
                    overwrite: f.overwrite,
                    files: f.destination,
                    insensitive: !0,
                    customFilter: u,
                  }),
                  Math.round(50 + (a / e) * 50));
              i < c &&
                (ui.loadingProgress(50 + (a / e) * 50),
                await ui.log(`Handled: ${a}/` + e),
                (i = c)),
                a++;
            }
          else if ("contextTrans" == f.compareMode)
            for (var g in (console.log("Translation by context"), o))
              trans.findAndInsertByContext(g, o[g], f.targetColumn, {
                overwrite: f.overwrite,
                files: f.destination,
              }),
                ui.loadingProgress(50 + (a / e) * 50),
                a++;
          else
            "copyByRow" == f.compareMode &&
              this.copyTranslationToRow(n.project.files, f.targetColumn, f);
          trans.trigger("onAfterImportTranslations", {
            options: f,
            loadedData: n,
            refTranslation: o,
          }),
            await common.wait(20),
            trans.evalTranslationProgress(),
            trans.refreshGrid(),
            ui.loadingProgress(100, "Done!"),
            ui.loadingEnd();
        });
    if (
      (ui.showLoading(),
      ui.loadingProgress(0, t("Importing translation")),
      await common.wait(200),
      "object" == typeof r && void 0 !== r.project)
    )
      return console.log("refPath is an object : "), await o(r), !0;
    console.log("Opening " + r),
      fs.readFile(r, async function (e, n) {
        if (e)
          throw (
            (console.log("error opening file : " + r),
            (n = n.toString()),
            "function" == typeof f.onFailed && f.onFailed.call(trans, n),
            e)
          );
        ui.loadingProgress(20, t("Parsing data")),
          await ui.log("Parsing data"),
          await common.wait(200),
          (n = n.toString());
        e = JSON.parse(n);
        console.log("Result data : "),
          console.log(e),
          o(e),
          console.log("Done!"),
          "function" == typeof f.onSuccess && f.onSuccess.call(trans, e),
          (trans.isOpeningFile = !1);
      });
  }),
  (Trans.prototype.translateAllBySelectedCells = async function (e, t, n) {
    (e = e || this.grid.getSelectedRange() || [[]]),
      (t = t || this.getSelectedId()),
      (n = n || {}),
      ui.showBusyOverlay(),
      await common.wait(100);
    var r,
      o = this.getAllFilesExcept([t]),
      a = this.generateSelectedTranslationTable(e, t, n),
      i = (console.log("Selected transtable", a), this.buildIndexes(o)),
      s = [];
    for (r in a) {
      var l = this.getFromIndexes(r, i);
      if (l)
        for (var c = 0; c < l.length; c++)
          for (
            var d = l[c], g = this.getData(d.file), f = 0;
            f < a[r].length;
            f++
          ) {
            var u = a[r][f],
              p = g[d.row][u.col];
            u.col != this.keyColumn &&
              ((g[d.row][u.col] = u.value),
              s.push({
                file: d.file,
                row: d.row,
                col: u.col,
                oldValue: p,
                newValue: u.value,
              }));
          }
    }
    return ui.hideBusyOverlay(), s;
  }),
  (Trans.prototype.getSelectedTexts = function (e, t) {
    (e = e || this.grid.getSelectedRange() || [[]]),
      (t = t || this.getSelectedId());
    for (
      var n = this.getData(t), r = common.gridSelectedCells(e), o = [], a = 0;
      a < r.length;
      a++
    )
      o.push(n[r[a].row][r[a].col] || "");
    return o;
  }),
  (Trans.prototype.getText = function (e, t, n) {
    return (n ? trans.getObjectById(n) : this.data)?.[e]?.[t];
  }),
  (Trans.prototype.getCellComment = function (e, t, n) {
    let r;
    if ((r = n ? this.getObjectById(n) : this.getSelectedObject()).comments)
      return r.comments?.[e]?.[t];
  }),
  (Trans.prototype.getSelectedOriginalTexts = function (e, t) {
    (e = e || this.grid.getSelectedRange() || [[]]),
      (t = t || this.getSelectedId());
    for (
      var n = this.getData(t), r = common.gridSelectedCells(e), o = [], a = 0;
      a < r.length;
      a++
    )
      o.push(n[r[a].row][this.keyColumn] || "");
    return o;
  }),
  (Trans.prototype.getSelectedTextsAsOneLine = function (e, t) {
    return (this.getSelectedTexts(e, t) || [])
      .join(" ")
      .replaceAll("\r", "")
      .replaceAll("\n", " ");
  }),
  (Trans.prototype.getSelectedOriginalTextsAsOneLine = function (e, t) {
    (e = e || this.grid.getSelectedRange() || [[]]),
      (t = t || this.getSelectedId());
    for (
      var n = this.getData(t), r = common.gridSelectedRows(), o = [], a = 0;
      a < r.length;
      a++
    )
      o.push(n[r[a]][this.keyColumn] || "");
    return o.join(" ");
  }),
  (Trans.prototype.getSelectedId = function () {
    return !!trans.project && trans.project?.selectedId;
  }),
  (Trans.prototype.getSelectedContext = function (t) {
    t = t || trans.lastSelectedCell[0];
    var n = trans.getSelectedObject().context;
    try {
      return n[t];
    } catch (e) {
      return (n[t] = []), n[t];
    }
  }),
  (Trans.prototype.getSelectedParameters = function () {
    var e, t;
    if (trans.lastSelectedCell)
      return (
        (e = trans.lastSelectedCell[0]),
        ((t = trans.getSelectedObject()).parameters = t.parameters || []),
        (t.parameters[e] = t.parameters[e] || []),
        t.parameters[e]
      );
  }),
  (Trans.prototype.getParamatersByRow = function (e, t) {
    return (
      (t = t || this.getSelectedId()),
      "number" == typeof e &&
        !!(t = trans.getObjectById(t))?.parameters &&
        t.parameters[e]
    );
  }),
  (Trans.prototype.setParametersByRow = function (e, t, n) {
    n = n || this.getSelectedId();
    n = this.getObjectById(n);
    (n.parameters = n.parameters || []), (n.parameters[e] = t);
  }),
  (Trans.prototype.getRowInfoText = function (e, t = !1, n = "", r = !1) {
    n = n || this.getSelectedId();
    var o = this.getParamatersByRow(e, n);
    if (!o) return "";
    var a,
      i,
      s = (this.getOption("gridInfo") || {}).referenceName || "Actor Reference";
    if (t) {
      for (var l in ((a = []), o))
        o[l] &&
          "object" == typeof o[l] &&
          (r
            ? o[l].rowInfoText && a.push(o[l].rowInfoText)
            : o[l].rowInfoText &&
              a.push(this.translateByReference(o[l].rowInfoText, !1, s)));
      return [...new Set(a)].join(", ");
    }
    for (i in ((a = ""), o))
      if (o[i] && "object" == typeof o[i]) {
        if (a) return a + "++";
        r
          ? o[i].rowInfoText && (a = o[i].rowInfoText)
          : o[i].rowInfoText &&
            (a = this.translateByReference(o[i].rowInfoText, !1, s));
      }
    return a;
  }),
  (Trans.prototype.setRowInfoText = function (e, t, n) {
    n = n || this.getSelectedId();
    e = this.getParamatersByRow(e, n);
    return !!e && ((e[0] ||= {}), (e[0].rowInfoText = t), !0);
  }),
  (Trans.prototype.getSelectedKeyText = function (e) {
    e = e || trans.lastSelectedCell[0];
    try {
      return trans.getSelectedObject().data[e][trans.keyColumn];
    } catch (e) {}
  }),
  (Trans.prototype.getSelectedObject = function () {
    var e;
    return (
      0 != $(".fileList .selected").length &&
      ((e = trans.getSelectedId()), trans.project.files[e])
    );
  }),
  (Trans.prototype.getObjectById = function (e) {
    if (e)
      try {
        return trans.project?.files?.[e];
      } catch (e) {
        console.warn(e);
      }
  }),
  (Trans.prototype.getCheckedFiles = function () {
    for (
      var e = [],
        t = $(".fileList .data-selector .fileCheckbox:checked"),
        n = 0;
      n < t.length;
      n++
    )
      e.push(t.eq(n).attr("value"));
    return e;
  }),
  (Trans.prototype.getCheckedObjects = function () {
    for (
      var e = {},
        t = $(".fileList .data-selector .fileCheckbox:checked"),
        n = 0;
      n < t.length;
      n++
    ) {
      var r = t.eq(n).attr("value");
      e[r] = this.getObjectById(r);
    }
    return e;
  }),
  (Trans.prototype.getAllFiles = function (e, t) {
    var n = [];
    if (void 0 !== (e = e || trans?.project?.files))
      if ((e?.project?.files && (e = e?.project?.files), t))
        for (var r in e) "*" != e[r]?.dirname && n.push(r);
      else for (var o in e) n.push(o);
    return n;
  }),
  (Trans.prototype.getAllFilesExcept = function (e, t) {
    e = (e = "string" == typeof e ? [e] : e) || [];
    var n,
      r = [];
    for (n in (t = t || trans.project.files)) e.includes(n) || r.push(n);
    return r;
  }),
  (Trans.prototype.getAllCompletedFiles = function (e) {
    var t = [];
    if (void 0 !== (e = e || this.project.files))
      for (var n in e)
        "object" == typeof e[n] &&
          "object" == typeof e[n].progress &&
          100 == e[n].progress.percent &&
          t.push(n);
    return t;
  }),
  (Trans.prototype.getAllIncompletedFiles = function (e) {
    var t = [];
    if (void 0 !== (e = e || this.project.files))
      for (var n in e)
        "object" == typeof e[n] &&
          "object" == typeof e[n].progress &&
          e[n].progress.percent < 100 &&
          t.push(n);
    return t;
  }),
  (Trans.prototype.getAllMarkedAsCompleted = function (e) {
    var t = [];
    if (void 0 !== (e = e || this.project.files))
      for (var n in e)
        "object" == typeof e[n] &&
          "object" == typeof e[n].progress &&
          e[n].isCompleted &&
          t.push(n);
    return t;
  }),
  (Trans.prototype.getAttachmentContent = function (e) {
    if (e && trans.project?.attachments?.[e])
      return trans.project.attachments[e].data;
  }),
  (Trans.prototype.scrollHToCol = function (e) {
    var t = $("#table .ht_master .wtHolder");
    if (!e) return (t[0].scrollLeft = 0);
    for (
      var n = $("#table .ht_master .wtHolder colgroup col"), r = 0, o = 1;
      o < e;
      o++
    )
      r += n.eq(o + 1).outerWidth();
    console.log(r), (t[0].scrollLeft = r);
  }),
  (Trans.prototype.goTo = function (e, t, n) {
    console.log(arguments),
      (n = n || this.getSelectedId()),
      this.grid.deselectCell(),
      n !== this.getSelectedId() &&
        ((n = this.selectFile(n)), $(n)[0].scrollIntoView({ block: "center" })),
      this.grid.selectCell(e, t, e, t),
      this.grid.scrollViewportTo(e, t),
      this.scrollHToCol(t);
  }),
  (Trans.prototype.getLastSelectedCell = function () {
    return this.lastSelectedCell;
  }),
  (Trans.prototype.goToNextUntranslated = function () {
    for (
      var e = this.getLastSelectedCell(),
        t = this.getCurrentData(),
        n = e[0] + 1,
        r = (n = n >= t.length ? 0 : n);
      r < t.length && this.rowHasTranslation(t[r]);
      r++
    );
    return t.length <= r && (r = t.length - 1), this.goTo(r, e[1]);
  }),
  (Trans.prototype.goToPreviousUntranslated = function () {
    var e = this.getLastSelectedCell(),
      t = this.getCurrentData(),
      n = e[0] - 1;
    n <= 0 && (n = t.length - 1), console.log("starting", n);
    for (var r = n; 0 <= r && this.rowHasTranslation(t[r]); r--);
    return console.log("Move to row", r), this.goTo((r = r < 0 ? 0 : r), e[1]);
  }),
  (Trans.prototype.search = function (n, r) {
    var e = require("glob-to-regexp");
    if ((console.log("entering trans.search", arguments), void 0 === n))
      return null;
    if (typeof n.length <= 1) return "Keyword too short!";
    if (void 0 === trans.project) return null;
    if (void 0 === trans.project.files) return null;
    if (
      (((r = r || {}).caseSensitive = r.caseSensitive || !1),
      (r.lineMatch = r.lineMatch || !1),
      (r.isRegexp = r.isRegexp || !1),
      (r.searchLocations = r.searchLocations || []),
      0 == r.searchLocations.length && (r.searchLocations = ["grid"]),
      r.lineMatch && (r.searchInContext = !1),
      0 == Array.isArray(r.files))
    )
      for (var o in ((r.files = []), trans.project.files)) r.files.push(o);
    0 == r.caseSensitive && 0 == r.isRegexp && (n = n.toLowerCase());
    var a = new Date().getTime(),
      i = {
        keyword: n,
        count: 0,
        isRegexp: r.isRegexp,
        executionTime: 0,
        files: {},
      };
    if (r.isRegexp) {
      if (0 == (l = common.evalRegExpStr(n)))
        return (
          alert(
            n +
              t(
                " is not a valid javascript's regexp!\r\nFind out more about Javascipt's Regular Expression at :\r\nhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions"
              )
          ),
          i
        );
    } else if (n.includes("*"))
      try {
        var s = e(n)
            .toString()
            .replace(/\/\^(.*?)\$\//, "$1"),
          l = new RegExp(s, "i");
        console.log("Glob style keyword detected", l);
      } catch (e) {
        console.warn("Error when converting glob pattern to RegExp");
      }
    if (r.lineMatch) {
      for (var c in r.files) {
        var d = r.files[c];
        if (0 != Array.isArray(trans.project.files[d].data)) {
          var g = trans.project.files[d].data;
          for (let t = 0; t < g.length; t++)
            if (0 != g[t].length)
              for (let e = 0; e < g[t].length; e++)
                if ("string" == typeof g[t][e])
                  if (l) {
                    if (l.test(g[t][e])) {
                      var f = common.lineIndexRegExp(g[t][e], l);
                      (i.files[d] = i.files[d] || []),
                        i.files[d].push({
                          fullString: g[t][e],
                          row: t,
                          col: e,
                          type: "cell",
                          lineIndex: f,
                        }),
                        i.count++;
                      break;
                    }
                  } else {
                    if (r.caseSensitive) {
                      if (-1 == g[t][e].indexOf(n)) continue;
                    } else if (-1 == g[t][e].toLowerCase().indexOf(n)) continue;
                    f = common.lineIndex(g[t][e], n, r.caseSensitive);
                    if (-1 != f) {
                      (i.files[d] = i.files[d] || []),
                        i.files[d].push({
                          fullString: g[t][e],
                          row: t,
                          col: e,
                          type: "cell",
                          lineIndex: f,
                        }),
                        i.count++;
                      break;
                    }
                  }
        }
      }
      e = new Date().getTime();
      i.executionTime = e - a;
    } else {
      if (
        (console.log("Search location:", r.searchLocations),
        r.searchLocations.includes("grid"))
      )
        for (var u in r.files) {
          var p = r.files[u];
          if (0 != Array.isArray(trans.project.files[p].data)) {
            var h = trans.project.files[p].data;
            for (let t = 0; t < h.length; t++)
              if (0 != h[t].length)
                for (let e = 0; e < h[t].length; e++)
                  if ("string" == typeof h[t][e])
                    if (l) {
                      if (l.test(h[t][e])) {
                        (i.files[p] = i.files[p] || []),
                          i.files[p].push({
                            fullString: h[t][e],
                            row: t,
                            col: e,
                            type: "cell",
                          }),
                          i.count++;
                        break;
                      }
                    } else {
                      if (r.caseSensitive) {
                        if (-1 == h[t][e].indexOf(n)) continue;
                      } else if (-1 == h[t][e].toLowerCase().indexOf(n))
                        continue;
                      (i.files[p] = i.files[p] || []),
                        i.files[p].push({
                          fullString: h[t][e],
                          row: t,
                          col: e,
                          type: "cell",
                        }),
                        i.count++;
                    }
          }
        }
      if (r.searchLocations.includes("context"))
        for (var m in r.files) {
          var y = r.files[m];
          if (0 != Array.isArray(trans.project.files[y].context)) {
            var v = trans.project.files[y].context;
            for (let t = 0; t < v.length; t++)
              if (0 != Array.isArray(v[t]) && 0 != v[t].length)
                for (let e = 0; e < v[t].length; e++)
                  if ("string" == typeof v[t][e]) {
                    if (l) {
                      if (0 == l.test(v[t][e])) continue;
                    } else if (r.caseSensitive) {
                      if (-1 == v[t][e].indexOf(n)) continue;
                    } else if (-1 == v[t][e].toLowerCase().indexOf(n)) continue;
                    (i.files[y] = i.files[y] || []),
                      i.files[y].push({
                        fullString: v[t][e],
                        row: t,
                        col: 0,
                        type: "context",
                      }),
                      i.count++;
                  }
          }
        }
      if (r.searchLocations.includes("tag"))
        for (var T in r.files) {
          var w = r.files[T],
            j = n.split(" "),
            b = trans.project.files[w].data;
          for (let e = 0; e < b.length; e++)
            0 != trans.hasTags(j, e, w) &&
              ((i.files[w] = i.files[w] || []),
              i.files[w].push({
                fullString: b[e][this.keyColumn],
                row: e,
                col: 0,
                type: "cell",
              }),
              i.count++);
        }
      if (r.searchLocations.includes("comment"))
        for (var C in (console.log("searching comment"), r.files)) {
          var x = r.files[C];
          if (0 != Boolean(trans.project.files[x].comments)) {
            var S,
              I = trans.project.files[x].comments;
            for (S in (console.log("processing", x), I))
              if (0 != Boolean(I[S]))
                for (var k in I[S])
                  if ("string" == typeof I[S][k]) {
                    if (l) {
                      if (0 == l.test(I[S][k])) continue;
                    } else if (r.caseSensitive) {
                      if (-1 == I[S][k].indexOf(n)) continue;
                    } else if (-1 == I[S][k].toLowerCase().indexOf(n)) continue;
                    (i.files[x] = i.files[x] || []),
                      i.files[x].push({
                        fullString: I[S][k],
                        row: S,
                        col: k,
                        type: "comment",
                      }),
                      i.count++;
                  }
          }
        }
      s = new Date().getTime();
      i.executionTime = s - a;
    }
    return i;
  }),
  (Trans.prototype.replace = function (n, r, o) {
    if ((console.log("entering trans.search"), void 0 === n)) return null;
    if (typeof n.length <= 1) return t("Keyword too short!");
    if (void 0 === trans.project) return null;
    if (void 0 === trans.project.files) return null;
    if (
      ((r = r || ""),
      ((o = o || {}).caseSensitive = o.caseSensitive || !1),
      (o.isRegexp = o.isRegexp || !1),
      0 == Array.isArray(o.files))
    )
      for (var e in ((o.files = []), trans.project.files)) o.files.push(e);
    0 == o.caseSensitive && 0 == o.isRegexp && (n = n.toLowerCase());
    var a,
      i = new Date().getTime(),
      s = {
        keyword: n,
        count: 0,
        isRegexp: o.isRegexp,
        executionTime: 0,
        files: {},
      };
    if (o.isRegexp) {
      var l = common.evalRegExpStr(n);
      if (0 == l)
        return (
          alert(
            n +
              t(
                " is not a valid javascript's regexp!\r\nFind out more about Javascipt's Regular Expression at :\r\nhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions"
              )
          ),
          s
        );
    }
    for (a in o.files) {
      var c = o.files[a];
      if (0 != Array.isArray(trans.project.files[c].data)) {
        var d = trans.project.files[c].data;
        for (let t = 0; t < d.length; t++)
          if (0 != d[t].length)
            for (let e = 1; e < d[t].length; e++)
              if ("string" == typeof d[t][e])
                if (o.isRegexp) {
                  if (l.test(d[t][e])) {
                    var g = trans.project.files[c].data[t][e];
                    (trans.project.files[c].data[t][e] = d[t][e].replace(l, r)),
                      (s.files[c] = s.files[c] || []),
                      s.files[c].push({
                        fullString: trans.project.files[c].data[t][e],
                        row: t,
                        col: e,
                        originalString: g,
                      }),
                      s.count++;
                    break;
                  }
                } else {
                  if (o.caseSensitive) {
                    if (-1 == d[t][e].indexOf(n)) continue;
                  } else if (-1 == d[t][e].toLowerCase().indexOf(n)) continue;
                  g = trans.project.files[c].data[t][e];
                  (trans.project.files[c].data[t][e] = d[t][e].replaces(
                    n,
                    r,
                    !o.caseSensitive
                  )),
                    (s.files[c] = s.files[c] || []),
                    s.files[c].push({
                      fullString: trans.project.files[c].data[t][e],
                      row: t,
                      col: e,
                      originalString: g,
                    }),
                    s.count++;
                }
      }
    }
    var f = new Date().getTime();
    return (s.executionTime = f - i), trans.refreshGrid(), s;
  }),
  (Trans.prototype.findPut = function (n, r, o, a) {
    if ((console.log("entering trans.search"), void 0 === n)) return null;
    if (typeof n.length <= 1) return t("Keyword too short!");
    if (void 0 === trans.project) return null;
    if (void 0 === trans.project.files) return null;
    if (o < 1) return !1;
    if (
      (((a = a || {}).caseSensitive = a.caseSensitive || !1),
      (a.lineMatch = a.lineMatch || !1),
      void 0 === a.overwrite && (a.overwrite = !0),
      0 == Array.isArray(a.files))
    )
      for (var e in ((a.files = []), trans.project.files)) a.files.push(e);
    0 == a.caseSensitive && (n = n.toLowerCase());
    var i = new Date().getTime(),
      s = { keyword: n, count: 0, executionTime: 0, files: {} };
    if (n.includes("\n") || "rowByRow" == a.mode)
      console.log("Entering row by row search"),
        (s = this.findAndInsert(n, r, o, {
          insensitive: !a.caseSensitive,
          overwrite: a.overwrite,
        }));
    else
      for (var l in a.files) {
        var c = a.files[l];
        if (0 != Array.isArray(trans.project.files[c].data)) {
          var d = trans.project.files[c].data;
          for (let t = 0; t < d.length; t++)
            if (0 != d[t].length)
              for (let e = 0; e < d[t].length; e++)
                if ("string" == typeof d[t][e]) {
                  if (a.caseSensitive) {
                    if (-1 == d[t][e].indexOf(n)) continue;
                  } else if (-1 == d[t][e].toLowerCase().indexOf(n)) continue;
                  var g = common.lineIndex(d[t][e], n, a.caseSensitive);
                  if (-1 != g) {
                    var f = common.insertLineAt(d[t][o], r, g, {
                      lineBreak: trans.project.files[c].lineBreak || "\n",
                    });
                    (d[t][o] = f),
                      (s.files[c] = s.files[c] || []),
                      s.files[c].push({
                        fullString: d[t][e],
                        row: t,
                        col: e,
                        type: "cell",
                        lineIndex: g,
                      }),
                      s.count++;
                    break;
                  }
                }
        }
      }
    var u = new Date().getTime();
    return (s.executionTime = u - i), trans.refreshGrid(), s;
  });
class TransProjectHook {
  constructor() {
    this.hooks = {};
  }
}
(TransProjectHook.prototype.defineHook = function (e, t) {
  if ("string" != typeof e)
    throw new Error(`hookName must be a string ${typeof e} given`);
  if ("function" != typeof t)
    throw new Error(`hookName must be a function ${typeof t} given`);
  this.hooks[e] = t;
}),
  (TransProjectHook.prototype.getHook = function (e) {
    return this.hooks[e];
  }),
  (TransProjectHook.prototype.run = async function (e, ...t) {
    "function" == typeof this.hooks[e] &&
      (await this.hooks[e].apply(window.trans, t));
    e = trans.getOption("hooks");
    if (e && "string" == typeof e?.afterExport && (await ui.confirmRunScript()))
      return new (Object.getPrototypeOf(async function () {}).constructor)(
        e.afterExport
      ).apply(trans, t);
  });
var trans = new Trans();
((window.trans = trans).cellInfo = new Trans.CellInfo()),
  (trans.projectHook = new TransProjectHook()),
  (trans.gridContextMenu = {
    commentsAddEdit: {
      name: t("Add comment"),
      hidden: function () {
        return (
          !!trans.grid.isColumnHeaderSelected() ||
          !!trans.grid.isRowHeaderSelected()
        );
      },
    },
    commentsRemove: {
      name: t("Delete comment"),
      hidden: function () {
        return (
          !!trans.grid.isColumnHeaderSelected() ||
          !!trans.grid.isRowHeaderSelected()
        );
      },
    },
    sepx: "---------",
    translateThisCell: {
      name: function () {
        var e =
          "<span class='HOTMenuTranslateHere'>" +
          t("Translate here") +
          " <kbd>ctrl+g</kbd></span>";
        if (void 0 === trans.project) return e;
        trans.project.options = trans.project.options || {};
        var n,
          r,
          o = trans.getActiveTranslator();
        return (
          console.log("thisTrans", o),
          void 0 !== o &&
          ((n = trans.getSl() || "??"),
          (r = trans.getTl() || "??"),
          (o = trans.getTranslatorEngine(o)?.name))
            ? t("Translate here using ") +
              o +
              " (" +
              n +
              "<i class='icon-right-bold'></i>" +
              r +
              ") <kbd>ctrl+g</kbd>"
            : e
        );
      },
      callback: function () {
        trans.translateSelection();
      },
      hidden: function () {
        return (
          !!trans.grid.isColumnHeaderSelected() ||
          !!trans.grid.isRowHeaderSelected() ||
          !trans.getActiveTranslator()
        );
      },
    },
    translateUsing: {
      name: function () {
        return trans.drawGridTranslatorMenu(), t("Translate using...");
      },
      submenu: { items: [] },
      hidden: function () {
        return !!trans.grid.isRowHeaderSelected();
      },
    },
    mergeThenTranslate: {
      name: "<span>Merge then translate <kbd>ctrl+shift+g</kbd></span>",
      hidden: function () {
        return !!trans.grid.isRowHeaderSelected();
      },
      callback: async function () {
        trans.translateSelectionAsOneLine();
      },
    },
    translateSimiliar: {
      name: "<span>Translate like this <kbd>ctrl+l</kbd></span>",
      hidden: function () {
        return !!trans.grid.isRowHeaderSelected();
      },
      callback: async function () {
        var e;
        confirm(
          t(
            "Do you want to translate all the same texts found across this project with the translation on the selected cell(s)?"
          )
        ) &&
          ((e = await trans.translateAllBySelectedCells()),
          alert(e.length + t(" cell(s) has been written!")));
      },
    },
    "---------": {},
    columnWidth: {
      name: t("Column width"),
      callback: function (e, n, r) {
        console.log("column width : ", arguments);
        var o = common.gridSelectedCols(),
          a = prompt("Enter new width", this.getColWidth(o[0]));
        if ((a = parseInt(a)) < 1) return alert(t("Width must greater than 0"));
        for (var i = 0; i < o.length; i++) this.setColWidth(o[i], a);
      },
      hidden: function () {
        return (
          !this.isColumnHeaderSelected() && (this.isRowHeaderSelected(), !0)
        );
      },
    },
    sepn: {
      name: "---------",
      hidden: function () {
        return (
          !this.isColumnHeaderSelected() && (this.isRowHeaderSelected(), !0)
        );
      },
    },
    "col-right": {
      name: t("Insert column right"),
      callback: function () {
        trans.grid.insertColumnRight();
      },
      hidden: function () {
        return (
          !trans.grid.isColumnHeaderSelected() &&
          (trans.grid.isRowHeaderSelected(), !0)
        );
      },
    },
    duplicateCol: {
      name: t("Duplicate column"),
      callback: function () {
        var e = trans.grid.getSelected()[0][1],
          t = trans.columns.length,
          n = trans.colHeaders[e] || "New Col";
        trans.columns.push({}),
          common.arrayExchange(trans.columns, t, e + 1),
          common.arrayInsert(trans.colHeaders, e + 1, n),
          console.log(trans.columns),
          trans.insertCell(e + 1, null),
          trans.copyCol(e, e + 1),
          trans.grid.updateSettings({ colHeaders: trans.colHeaders });
      },
      hidden: function () {
        return (
          !trans.grid.isColumnHeaderSelected() ||
          trans.grid.getSelected()[0][1] != trans.grid.getSelected()[0][3] ||
          1 < trans.grid.getSelected().length
        );
      },
    },
    removeColumn: {
      name: t("Remove this column"),
      callback: function (e, n, r) {
        console.log(arguments),
          confirm(t("Remove selected column?\nThis can not be undone!")) &&
            trans.removeColumn(n[0].start.col, { refreshGrid: !0 });
      },
      hidden: function () {
        return (
          !trans.grid.isColumnHeaderSelected() &&
          (trans.grid.isRowHeaderSelected(), !0)
        );
      },
    },
    renameColumn: {
      name: t("Rename this column"),
      callback: function (e, n, r) {
        console.log(arguments);
        var n = n[0].start.col,
          o = trans.colHeaders[n],
          o = prompt(t("Please enter new name"), o);
        o && trans.renameColumn(n, o, { refreshGrid: !0 });
      },
      hidden: function () {
        return (
          !trans.grid.isColumnHeaderSelected() &&
          (trans.grid.isRowHeaderSelected(), !0)
        );
      },
    },
    sep0: "---------",
    tags: {
      name: "Tags",
      submenu: {
        items: [
          {
            key: "tags:red",
            name: '<i class="tag red icon-circle"></i> ' + t("Red"),
            callback: function (e, t, n) {
              trans.setTagForSelectedRow("red", t);
            },
          },
          {
            key: "tags:yellow",
            name: '<i class="tag yellow icon-circle"></i> ' + t("Yellow"),
            callback: function (e, t, n) {
              trans.setTagForSelectedRow("yellow", t);
            },
          },
          {
            key: "tags:green",
            name: '<i class="tag green icon-circle"></i> ' + t("Green"),
            callback: function (e, t, n) {
              trans.setTagForSelectedRow("green", t);
            },
          },
          {
            key: "tags:blue",
            name: '<i class="tag blue icon-circle"></i> ' + t("Blue"),
            callback: function (e, t, n) {
              trans.setTagForSelectedRow("blue", t);
            },
          },
          {
            key: "tags:gold",
            name: '<i class="tag gold icon-circle"></i> ' + t("Gold"),
            callback: function (e, t, n) {
              trans.setTagForSelectedRow("gold", t);
            },
          },
          {
            key: "tags:more",
            name:
              '<i class="tag icon-tags"></i> ' +
              t("More tags...") +
              " <kbd>ctrl+t</kbd>",
            callback: function (e, t, n) {
              ui.taggingDialog(t);
            },
          },
          {
            key: "tags:clear",
            name: '<i class="tag icon-blank"></i> ' + t("Clear tags"),
            callback: function (e, t, n) {
              trans.clearTags(void 0, t), trans.grid.render();
            },
          },
        ],
      },
    },
    sep1: "---------",
    deleteRow: {
      name: function () {
        return t("Delete Row") + " <kbd>shift+del</kbd>";
      },
      callback: function (e, n, r) {
        confirm(t("Do you want to remove the currently selected row(s)?")) &&
          (trans.removeRow(trans.getSelectedId(), common.gridSelectedRows()),
          trans.refreshGrid(),
          trans.grid.deselectCell());
      },
      hidden: function () {
        return (
          !!trans.grid.isColumnHeaderSelected() ||
          (trans.grid.isRowHeaderSelected(), !1)
        );
      },
    },
    clearContextTranslation: {
      name: t("Clear Context Translation") + " <kbd>alt+del</kbd>",
      callback: function (e, t, n) {
        trans.trigger("clearContextTranslationByRow", {
          file: trans.getSelectedId(),
          row: trans.grid.getSelectedRange(),
          type: "range",
        });
      },
      hidden: function () {
        return (
          !!trans.grid.isColumnHeaderSelected() ||
          (trans.grid.isRowHeaderSelected(), !1)
        );
      },
    },
    sep2: "---------",
    createAutomation: {
      name: t("Create Automation"),
      callback: function (e, t, n) {
        console.log(arguments);
        var r = {
          workspace: "gridSelection",
          cellRange: trans.grid.getSelectedRange(),
        };
        ui.openAutomationEditor("codeEditor_gridSelection", r);
      },
    },
    runAutomation: {
      name: () => (trans.updateRunScriptGridMenu(), t("Run Automation")),
    },
    clearAutomation: {
      name: t("Clear Automation"),
      callback: function () {
        confirm(t("Are you sure want to clear all quick launch scripts?")) &&
          (sys.setConfig("codeEditor/gridSelection", { quickLaunch: [] }),
          sys.saveConfig());
      },
    },
    sep3: "---------",
    appendToReference: {
      name: t("Append rows to reference") + " <kbd>ctrl+shift+d</kbd>",
      callback: function (e, t, n) {
        trans.appendSelectedRowToReference();
      },
      hidden: function () {
        return !!trans.grid.isColumnHeaderSelected();
      },
    },
    properties: {
      name: t("Row properties"),
      callback: function (e, t, n) {
        console.log(arguments), ui.openRowProperties();
      },
      hidden: function () {
        return (
          !!trans.grid.isColumnHeaderSelected() ||
          (trans.grid.isRowHeaderSelected(), !1)
        );
      },
    },
  }),
  (trans.fileLoader = new FileLoader()),
  trans.fileLoader.add("json", function (e) {
    trans.open(e);
  }),
  trans.fileLoader.add("trans", function (e) {
    trans.open(e);
  }),
  trans.fileLoader.add("tpp", function (e) {
    trans.importTpp(e);
  }),
  (window.Attachment = function (e) {
    (e = e || {}), Object.assign(this, e);
  }),
  $(document).ready(function () {
    0 != $("body").is('[data-window="trans"]') &&
      (trans.fileSelectorContextMenuInit(),
      $(window).resize(
        debounce(function () {
          $(document).trigger("windowResizeStop"),
            trans.grid.render(),
            ui.fixCellInfoSize();
        }, 100)
      ),
      trans.initTable(),
      (trans.isLoaded = !0),
      trans.on("transLoaded", async () => {
        console.warn("Trans loaded"),
          $(".menu-button > .button-gridInfo.gridInfo").removeClass("checked"),
          trans.getOption("gridInfo")?.isRuleActive &&
            $(".menu-button > .button-gridInfo.gridInfo").addClass("checked");
      }));
  });
Hi, I noticed you're still using version 7.4.24C of Translator++. Just wondering—is there a specific reason you're sticking with that one?

Version 7.5.28 has already been shared with the community (see post #1326), and the developer has even released version 7.6.25 as the latest build.
update: this new version you mentioned also works in the way I described
 
Last edited:
  • Like
Reactions: Garter2269

ripno

Newbie
Jan 27, 2023
63
105
update: this code that is fetched is also encrypted, a bad sign, and the decrypted code is minified as well, a very bad sign. I'll share it here

JavaScript:
/**=====LICENSE STATEMENT START=====
    Translator++
    CAT (Computer-Assisted Translation) tools and framework to create quality
    translations and localizations efficiently.
  
    Copyright (C) 2018  Dreamsavior<dreamsavior@gmail.com>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.
=====LICENSE STATEMENT END=====*/
/**
* @file trans.js The core class of Translator++
* @author Dreamsavior
* File version: 2024-04-03 14:22:34.304
*/

(window.fs = require("graceful-fs")),
  (window.afs = require("await-fs")),
  (window.nwPath = require("path")),
  (window.spawn = require("child_process").spawn),
  (window.debounce = require("debounce")),
  (window.BatchTranslate = require("www/js/BatchTranslate.js")),
  (window.insertArrayAt = function (e, t, n) {
    return Array.prototype.splice.apply(e, [t, 0].concat(n)), e;
  }),
  (global.common ||= {}),
  (common.arrayExchange = function (e, t, n) {
    var r = e[t];
    e.splice(t, 1), e.splice(n, 0, r);
  }),
  (common.arrayExchangeBatch = function (e, t, n) {
    0 == Array.isArray(t) && common.arrayExchange(e, t, n);
    for (var r = t.length - 1; 0 <= r; r--) common.arrayExchange(e, t[r], n);
    return e;
  }),
  (common.arrayMove = function (e, t, n) {
    if (0 != Array.isArray(e) && n !== t) {
      for (var r = e[t], o = n < t ? -1 : 1, a = t; a != n; a += o)
        e[a] = e[a + o];
      e[n] = r;
    }
    return e;
  }),
  (common.arrayMoveBatch = function (e, t, n) {
    if (0 == Array.isArray(t)) return common.arrayMove(e, t, n);
    for (var r = 0, o = t.length - 1; 0 <= o; o--)
      (e = common.arrayMove(e, t[o] + r, n)), r++;
    return e;
  }),
  (common.escapeSelector = function (e) {
    return "string" == typeof (e = e || "") && '"' + CSS.escape(e) + '"';
  }),
  (common.arrayInsert = function (e, t, n) {
    return e.splice(t, 0, n), e;
  }),
  (common.batchArrayInsert = function (e, t, n) {
    for (var r = 0; r < e.length; r++) this.arrayInsert(e[r], t, n);
    return e;
  });
var FileLoader = function () {
  this.handler = {};
};
(FileLoader.prototype.add = function (e, t) {
  this.handler[e] = t;
}),
  (FileLoader.prototype.open = function (e, t) {}),
  (window.FileLoader = FileLoader);
class Trans extends require("www/js/BasicEventHandler.js") {
  constructor() {
    super($(document)), this.init();
  }
}
(Trans.maxCols = 15),
  (Trans.CellInfo = function () {}),
  (Trans.CellInfo.prototype.getAll = function (e) {
    if (e && trans?.project?.files?.[e])
      return (
        (e = trans.getObjectById(e)).cellInfo || (e.cellInfo = []), e.cellInfo
      );
  }),
  (Trans.CellInfo.prototype.getRow = function (e, t) {
    e = this.getAll(e);
    if (e) return e[t];
  }),
  (Trans.CellInfo.prototype.getCell = function (e, t, n) {
    e = this.getRow(e, t);
    if (e) return e[n];
  }),
  (Trans.CellInfo.prototype.getBestCellInfo = function (e, t, n) {
    var r = trans.getData(e),
      r = trans.getTranslationColFromRow(r[t]),
      e = this.getCell(e, t, r);
    return e && (n ? e[n] : e);
  }),
  (Trans.CellInfo.prototype.get = function (e, t, n, r) {
    t = this.getCell(t, n, r);
    if (t) return t[e];
  }),
  (Trans.CellInfo.prototype.set = function (e, t, n, r, o) {
    n = this.getAll(n);
    return (n[r] = n[r] || []), (n[r][o] = n[r][o] || {}), (n[r][o][e] = t), !0;
  }),
  (Trans.CellInfo.prototype.delete = function (e, t, n, r) {
    t = this.getAll(t);
    return (
      (t[n] = t[n] || []), (t[n][r] = t[n][r] || {}), delete t[n][r][e], !0
    );
  }),
  (Trans.CellInfo.prototype.deleteRow = function (e, t) {
    e = this.getAll(e);
    empty(e) || (Array.isArray(e) ? e.splice(t, 1) : delete e[t]);
  }),
  (Trans.CellInfo.prototype.deleteCell = function (e, t, n) {
    e = this.getRow(e, t);
    if (Array.isArray(e)) return e.splice(n, 1), !0;
  }),
  (Trans.CellInfo.prototype.moveCell = function (e, t, n, r) {
    e = this.getRow(e, t);
    if (Array.isArray(e)) return common.arrayMoveBatch(e, n, r), !0;
  }),
  (Trans.prototype.init = function () {
    (this.config = {
      loadRomaji: !0,
      maxRequestLength: 3e3,
      autoSaveEvery: 600,
      batchDelay: 5e3,
      rpgTransFormat: !0,
      autoTranslate: !1,
    }),
      (this.keyColumn = 0),
      (this.isFreeEditing = !1),
      (this.gameTitle = ""),
      (this.gameEngine = ""),
      (this.projectId = ""),
      (this.indexIds = {}),
      (this.fileListLoaded = !1),
      (this.isLoadingFileList = !1),
      (this.unsavedChange = !1),
      (this.gameFolder = ""),
      (this.currentFile = ""),
      (this.skipElement = ["note", "Comment", "Script"]),
      (this.project = void 0),
      (this.timers = {}),
      (this.data = []),
      (this.colHeaders = [
        t("Original Text"),
        t("Initial"),
        t("Machine translation"),
        t("Better translation"),
        t("Best translation"),
      ]),
      (this.onFileNavLoaded = function () {}),
      (this.onFileNavUnloaded = function () {}),
      (this.validateKey = function (e, t) {
        console.log("key validator", e), t("" != e && null != e);
      }),
      (this.columns = [
        { readOnly: !1, validator: this.validateKey, width: 150 },
        { readOnly: !1 },
        { readOnly: !1 },
        { readOnly: !1 },
        { readOnly: !1 },
      ]),
      (this.default = {}),
      (this.default.columns = [
        { readOnly: !1, validator: this.validateKey },
        { readOnly: !1 },
        { readOnly: !1 },
        { readOnly: !1 },
        { readOnly: !1 },
      ]),
      (this.inProject = !1),
      (this.default.colHeaders = [
        t("Original Text"),
        t("Initial"),
        t("Machine translation"),
        t("Better translation"),
        t("Best translation"),
      ]);
  }),
  (Trans.prototype.isTrans = function (e) {
    return !(
      !e ||
      ("Object" !== e.constructor.name && "Trans" !== e.constructor.name) ||
      !e?.project?.files
    );
  }),
  (Trans.prototype.getOption = function (e) {
    if (trans.project)
      return (
        (trans.project.options ||= {}),
        void 0 === trans.project.options.gridInfo &&
          (trans.project.options.gridInfo = {
            isRuleActive: !0,
            enableTrail: !0,
            viewTrail: !1,
            viewOrganicCellMarker: !0,
            rowHeaderInfo: !1,
          }),
        trans.project.options[e]
      );
  }),
  (Trans.prototype.setOption = function (e, t) {
    trans.project &&
      (console.log("Setting option", e, t),
      (trans.project.options ||= {}),
      (trans.project.options[e] = t));
  }),
  (Trans.prototype.getConfig = function (e) {
    if (
      ((trans.project.config = trans.project.config || {}),
      "string" == typeof e)
    )
      return trans.project.config[e];
    if (Array.isArray(e)) {
      var t = trans.project.config;
      try {
        for (var n = 0; n < e.length; n++) t = t[e[n]];
        return t;
      } catch (e) {
        return;
      }
    }
  }),
  (Trans.prototype.setConfig = function (e, t) {
    if (
      ((trans.project.config = trans.project.config || {}),
      "string" == typeof e)
    )
      return (trans.project.config[e] = t), !0;
    if (Array.isArray(e)) {
      var n = trans.project.config;
      try {
        for (var r = 0; r < e.length - 1; r++)
          (n[e[r]] = n[e[r]] || {}), (n = n[e[r]]);
        return (n[e[r]] = t), !0;
      } catch (e) {
        return;
      }
    }
  }),
  (Trans.prototype.isInProject = function () {
    return this.inProject;
  }),
  (Trans.prototype.getTemplatePath = function () {
    var t =
      sys.config.templatePath || nw.App.manifest.localConfig.defaultTemplate;
    fs = fs || require("fs");
    try {
      if (fs.existsSync(t)) return t;
    } catch (e) {
      return nwPath.join(__dirname, t);
    }
  }),
  (Trans.prototype.mergeReference = function (e) {
    for (var t in (console.log("Merging reference"),
    ((e = e || {}).project = e.project || {}),
    (e.project.references = e.project.references || {}),
    (e.project.files = e.project.files || {}),
    e.project.references))
      console.log("assigning : ", t),
        (e.project.files[t] = this.project.references[t]);
    return e;
  }),
  (Trans.prototype.isFileSupported = function (e) {
    return (
      "string" == typeof e &&
      ((e = common.getFileExtension(e)), !!sys.supportedExtension.includes(e))
    );
  }),
  (Trans.prototype.openFile = function (e) {
    var t,
      n = require("child_process").spawn;
    return (
      0 != this.isFileSupported(e) &&
      ((t = common.getFileExtension(e)),
      "function" == typeof this.fileLoader.handler[t]) &&
      void (0 == this.fileListLoaded
        ? (ui.introWindowClose(), this.fileLoader.handler[t].apply(this, [e]))
        : n(nw.process.execPath, [e], { detached: !0 }))
    );
  }),
  (Trans.prototype.initProject = function () {
    if (void 0 !== this.project)
      return console.log("project is already been initialized! skipping!"), !1;
  }),
  (Trans.prototype.closeProject = function () {
    if (void 0 === this.project) return !1;
    "function" == typeof this.grid.destroy() && this.grid.destroy(),
      this.unInitFileNav(),
      this.unInitLocalStorage(),
      (this.project = {}),
      this.init(),
      ui.tableCornerHideLoading(!0),
      ui.closeAllChildWindow(),
      ui.ribbonMenu.clear(),
      ui.clearActiveCellInfo(),
      ui.clearPathInfo(),
      ui.setWindowTitle(""),
      trans.clearFooter(),
      this.initTable(),
      this.gridIsModified(!1);
  }),
  (Trans.prototype.generateNewDictionaryTable = function () {
    var e = "Common Reference";
    if (void 0 !== this.project.files[e]) return this.project.files[e];
    if ("object" == typeof this.project.references)
      for (var t in (console.log("trans.project.reference is an object"),
      this.project.references))
        this.project.files[t] = this.project.references[t];
    else {
      console.log("trans.project.reference is not an object");
      (e = this.getTemplatePath()), (e = this.loadJSONSync(e));
      console.log("template obj : ", e),
        !1 !== Boolean(e) &&
          ((this.project.references = e.project.references),
          console.log("assigning reference : ", this.project.references)),
        this.mergeReference(trans);
    }
    return this.project.references;
  }),
  (Trans.prototype.createProject = function (a) {
    var i, e;
    return (
      console.log("running trans.createProject"),
      !this.isLoadingFileList &&
        "" != this.gameFolder &&
        ((i = this),
        ((a = a || {}).force = a.force || ""),
        (a.selectedFile = a.selectedFile || ""),
        (a.onAfterLoading = a.onAfterLoading || function (e, t) {}),
        (a.options = a.options || {}),
        (this.isLoadingFileList = !0),
        ui.showLoading(),
        (e = {
          gameFolder: this.gameFolder,
          selectedFile: a.selectedFile,
          gameEngine: this.gameEngine,
          gameTitle: this.gameTitle,
          projectId: this.projectId,
          skipElement: this.skipElement,
          indexOriginal: 0,
          indexTranslation: 1,
          force: a.force,
          rpgTransFormat: i.config.rpgTransFormat,
          options: a.options,
        }),
        console.log("Sending this args to loadGameInfo.php : ", e),
        void php.spawn("loadGameInfo.php", {
          args: e,
          onData: function (e) {
            ui.loadingProgress(t("Loading"), e, {
              consoleOnly: !0,
              mode: "consoleOutput",
            });
          },
          onError: function (e) {
            ui.loadingProgress(t("Loading"), e, {
              consoleOnly: !0,
              mode: "consoleOutput",
              classStr: "stderr",
            });
          },
          onDone: function (e) {
            if (
              (console.log("onDone event defined from trans.js"),
              common.isJSON(e))
            )
              (i.project = e),
                (i.currentFile = ""),
                (i.gameTitle = e.gameTitle),
                (i.gameFolder = e.loc),
                (i.projectId = e.projectId),
                (i.gameEngine = e.gameEngine),
                (i.editorName = "Translator++"),
                (i.editorVersion = nw.App.manifest.version),
                i.generateHeader(),
                i.sanitize(),
                i.dataPadding(),
                sys.updateLastOpenedProject(),
                i.autoSave(),
                console.log(e),
                ui.setStatusBar(1, i.gameTitle),
                i.trigger("projectCreated", i, e),
                "function" == typeof a.onAfterLoading &&
                  a.onAfterLoading.call(i, e, this),
                (i.fileListLoaded = !0),
                (i.isLoadingFileList = !1),
                ui.showCloseButton();
            else {
              var e = $("<div>" + e + "</div>"),
                o = e.find("#initialDataPath").attr("data-path");
              if ((console.log("found initPath : " + o), 0 == Boolean(o)))
                ui.loadingProgress(
                  "Error!",
                  "Can not successfully parse your game! Read the documentation here: https://dreamsavior.net/?p=1311",
                  { consoleOnly: !0, mode: "consoleOutput" }
                ),
                  ui.showCloseButton(),
                  (i.fileListLoaded = !1),
                  (i.isLoadingFileList = !1);
              else {
                try {
                  fs.readFile(o, function (e, n) {
                    if (e)
                      throw (
                        (console.log("error opening file : " + o),
                        ui.loadingProgress(
                          "Error!",
                          "Error opening file : " + o,
                          { consoleOnly: !0, mode: "consoleOutput" }
                        ),
                        ui.showCloseButton(),
                        (i.fileListLoaded = !1),
                        (i.isLoadingFileList = !1),
                        e)
                      );
                    var n = n.toString(),
                      r = {};
                    try {
                      r = JSON.parse(n);
                    } catch (e) {
                      return (
                        ui.loadingProgress(
                          t("Error!"),
                          t("Error processing init file : ") + o + "\n" + e,
                          { consoleOnly: !0, mode: "consoleOutput" }
                        ),
                        ui.showCloseButton(),
                        (i.isLoadingFileList = !1)
                      );
                    }
                    if (0 == Boolean(r.files))
                      return (
                        ui.loadingProgress(
                          t("Error!"),
                          t("Error! File list not found in init file at : ") +
                            o,
                          { consoleOnly: !0, mode: "consoleOutput" }
                        ),
                        ui.loadingProgress(
                          t("Error!"),
                          t(
                            "This means that your game was not successfully parsed. Please visit https://dreamsavior.net/?p=1311 for possible solution for this issue."
                          ),
                          { consoleOnly: !0, mode: "consoleOutput" }
                        ),
                        ui.showCloseButton(),
                        (i.isLoadingFileList = !1)
                      );
                    (i.project = r),
                      (i.currentFile = ""),
                      (i.gameTitle = r.gameTitle),
                      (i.gameFolder = r.loc),
                      (i.projectId = r.projectId),
                      (i.gameEngine = r.gameEngine),
                      (i.editorName = "Translator++"),
                      (i.editorVersion = nw.App.manifest.version),
                      i.generateHeader(),
                      i.sanitize(),
                      i.dataPadding(),
                      sys.updateLastOpenedProject(),
                      i.autoSave(),
                      console.log(r),
                      ui.setStatusBar(1, i.gameTitle),
                      i.trigger("projectCreated", i, r),
                      "function" == typeof a.onAfterLoading &&
                        a.onAfterLoading.call(i, r, this),
                      (i.fileListLoaded = !0),
                      (i.isLoadingFileList = !1),
                      ui.loadingProgress(t("Done!"), t("All done!"), {
                        consoleOnly: !1,
                        mode: "consoleOutput",
                      }),
                      ui.loadingEnd();
                  });
                } catch (e) {
                  console.log("error opening file : " + o),
                    ui.loadingProgress(
                      t("Error!"),
                      t("Error opening file : ") + o,
                      { consoleOnly: !1, mode: "consoleOutput" }
                    ),
                    ui.loadingProgress(t("Error!"), e, {
                      consoleOnly: !0,
                      mode: "consoleOutput",
                    }),
                    ui.loadingEnd(),
                    (i.fileListLoaded = !1),
                    (i.isLoadingFileList = !1);
                }
                e = e.find("#tmpPath");
                0 < e.length && ui.showOpenCacheButton(e.text());
              }
            }
          },
        }))
    );
  }),
  (Trans.prototype.procedureCreateProject = function (t, n) {
    if (
      (console.log("running trans.procedureCreateProject"),
      console.log(arguments),
      void 0 === t)
    )
      return !1;
    ((n = n || {}).selectedFile = n.selectedFile || ""),
      (n.force = n.force || ""),
      (n.projectInfo = n.projectInfo || { id: "", title: "" }),
      (n.options = n.options || {}),
      (n.gameEngine = n.gameEngine || ""),
      this.closeProject(),
      (this.projectId = n.projectInfo.id),
      (this.gameTitle = n.projectInfo.title),
      (this.gameFolder = t),
      (this.gameEngine = n.gameEngine),
      ui.newProjectDialog.close(),
      this.createProject({
        selectedFile: n.selectedFile,
        force: n.force,
        onAfterLoading: async function (e) {
          this.drawFileSelector(),
            (this.project.options = this.project.options || {}),
            (this.project.options.init = n.options || {}),
            engines.hasHandler("onAfterCreateProject") &&
              (await common.wait(100),
              await engines.handler("onAfterCreateProject").call(this, t, n));
        },
        options: n.options,
      });
  }),
  (Trans.prototype.getRow = function (e, t) {
    if ("string" == typeof t)
      return (
        console.log("Get row", arguments),
        0 == e.indexIsBuilt &&
          (console.log("building index for the first time"),
          this.buildIndexFromData(e)),
        (e.indexIds = e.indexIds || {}),
        console.log("getRow result is : ", e.indexIds[t]),
        e.indexIds[t]
      );
  }),
  (Trans.prototype.updateProject = function (e, t) {
    "string" == typeof e && (e = JSON.parse(e)),
      ((t = t || {}).onAfterLoading =
        t.onAfterLoading || function (e, t, n) {}),
      (t.onSuccess = t.onSuccess || function (e, t) {}),
      (t.onFailed = t.onFailed || function (e, t) {}),
      (t.filePath = t.filePath || ""),
      (t.purgeNonExistingData ||= !1),
      (e.project = e.project || {}),
      (e.project.files = e.project.files || {});
    var n,
      r = e,
      o = this.getSaveData().project.files || {};
    for (n in (console.log("Base data", e),
    console.log("Preserved current files", o),
    (r.project.files = e.project.files),
    e.project.files)) {
      var a = r.project.files[n];
      if (o[n] && o[n].data && !(o[n].data.length < 1))
        if (
          (console.log("%cprocessing file", "color:aqua", n),
          t.purgeNonExistingData)
        )
          for (let t = 0; t < a.data.length; t++) {
            var i = a.data[t][0],
              s = this.getRow(o[n], i);
            if (
              (console.log("%cKey", "color:aqua", i),
              console.log("%coldFileRow", "color:aqua", s),
              void 0 !== s && o[n].data[s])
            )
              for (let e = 1; e < o[n].data[s].length; e++)
                a.data[t][e] = o[n].data[s][e];
          }
        else {
          var l,
            c,
            d,
            g = o[n];
          let t = 0;
          for (let e = 0; e < g.data.length; e++)
            g.data[e]?.length &&
              (l = g.data[e][0]) &&
              (void 0 === (c = this.getRow(a, l))
                ? ((d = a.data.push(g.data[e]) - 1),
                  (a.data.indexIds ||= {}),
                  (a.data.indexIds[l] = d),
                  (a.context[d] = ["RefreshCarryover/" + t]),
                  g.cellInfo?.[e] &&
                    ((a.cellInfo ||= []), (a.cellInfo[d] = g.cellInfo[e])),
                  g.comments?.[e] &&
                    ((a.comments ||= []), (a.comments[d] = g.comments[e])),
                  g.parameters?.[e] &&
                    ((a.parameters ||= []),
                    (a.parameters[d] = g.parameters[e])),
                  g.tags?.[e] && ((a.tags ||= []), (a.tags[d] = g.tags[e])),
                  t++)
                : ((a.data[c] = g.data[e]),
                  g.cellInfo?.[e] &&
                    ((a.cellInfo ||= []), (a.cellInfo[c] = g.cellInfo[e])),
                  g.comments?.[e] &&
                    ((a.comments ||= []), (a.comments[c] = g.comments[e])),
                  g.parameters?.[e] &&
                    ((a.parameters ||= []),
                    (a.parameters[c] = g.parameters[e])),
                  g.tags?.[e] && ((a.tags ||= []), (a.tags[c] = g.tags[e]))));
        }
    }
    return console.log("updatedProject", r), r;
  }),
  (Trans.prototype.updateProject2 = function (e, t = this.getSaveData()) {
    return e;
  }),
  (Trans.prototype.openFromTransObj = function (e, t) {
    "string" == typeof e && (e = JSON.parse(e)),
      ((t = t || {}).onAfterLoading =
        t.onAfterLoading || function (e, t, n) {}),
      (t.onSuccess = t.onSuccess || function (e, t) {}),
      (t.onFailed = t.onFailed || function (e, t) {}),
      (t.filePath = t.filePath || ""),
      (t.isNew = t.isNew || !1),
      t.isNew && ((e = this.initTransData(e)), console.log(e)),
      (this.currentFile = t.filePath),
      this.applySaveData(e),
      this.sanitize(),
      this.grid.render(),
      sys.insertOpenedFileHistory();
    try {
      ($DV.config.sl = this.project.options.sl || "ja"),
        ($DV.config.tl = this.project.options.tl || "en");
    } catch (e) {
      ($DV.config.sl = "ja"), ($DV.config.tl = "en");
    }
    "function" == typeof t.onSuccess && t.onSuccess.call(this, e),
      "function" == typeof t.onAfterLoading &&
        t.onAfterLoading.call(this, "success", e),
      this.updateStagingInfo(),
      (this.isOpeningFile = !1),
      ui.hideBusyOverlay(),
      e.project.selectedId
        ? this.selectFile(e.project.selectedId)
        : this.selectFile($(".fileList .data-selector").eq(0));
  }),
  (Trans.prototype.detectFormat = async function (e) {
    return (
      !!e &&
      (".tpp" == nwPath.extname(e).toLowerCase()
        ? "tpp"
        : ".trans" == nwPath.extname(e).toLowerCase() && "trans")
    );
  }),
  (Trans.prototype.open = async function (r, o) {
    var a;
    return (
      "" != (r = r || this.currentFile) &&
      null != r &&
      void 0 !== r &&
      (console.log("opening project : ", r),
      "tpp" == (await this.detectFormat(r))
        ? this.importTpp(r)
        : ((a = this),
          ((o = o || {}).onAfterLoading =
            o.onAfterLoading || function (e, t, n) {}),
          (o.onSuccess = o.onSuccess || function (e, t) {}),
          (o.onFailed = o.onFailed || function (e, t) {}),
          (a.isOpeningFile = !0),
          ui.showBusyOverlay(),
          void fs.readFile(r, function (n, e) {
            if (n)
              console.log(n),
                alert(t("error opening file (open): ") + r + "\r\n" + n),
                void 0 !== e &&
                  ((e = e.toString()),
                  "function" == typeof o.onFailed && o.onFailed.call(a, e),
                  "function" == typeof o.onAfterLoading) &&
                  o.onAfterLoading.call(a, "error", e),
                ui.hideBusyOverlay();
            else {
              e = e.toString();
              n = {};
              try {
                n = JSON.parse(e);
              } catch (e) {
                return (
                  console.warn("Failed to parse JSON data"),
                  alert(
                    "Failed to parse JSON data.\nThe .trans file is corrupted."
                  ),
                  "function" == typeof o.onAfterLoading &&
                    o.onAfterLoading.call(a, "Failed", n),
                  (a.isOpeningFile = !1),
                  void ui.hideBusyOverlay()
                );
              }
              console.log(n),
                (a.currentFile = r),
                a.applySaveData(n),
                a.sanitize(),
                a.grid.render(),
                sys.insertOpenedFileHistory();
              try {
                ($DV.config.sl = a.project.options.sl || "ja"),
                  ($DV.config.tl = a.project.options.tl || "en");
              } catch (e) {
                ($DV.config.sl = "ja"), ($DV.config.tl = "en");
              }
              "function" == typeof o.onSuccess && o.onSuccess.call(a, n),
                "function" == typeof o.onAfterLoading &&
                  o.onAfterLoading.call(a, "success", n),
                (a.isOpeningFile = !1),
                ui.hideBusyOverlay(),
                n.project.selectedId
                  ? a.selectFile(n.project.selectedId)
                  : a.selectFile($(".fileList .data-selector").eq(0)),
                a.gridIsModified(!1),
                (a.project.options = a.project.options || {}),
                console.log("displaying info "),
                Boolean(a.project.options.info) &&
                  a.project.options.displayInfo &&
                  ui.showPopup(
                    "infobox_" + a.project.projectId,
                    a.project.options.info,
                    {
                      title: "Project's Info",
                      allExternal: !0,
                      HTMLcleanup: !0,
                    }
                  ),
                a.isCacheError()
                  ? (ui.addIconOverlay($(".button-properties"), "attention"),
                    $(".button-properties").attr(
                      "title",
                      "Project properties - Staging path error!"
                    ))
                  : (ui.clearIconOverlay($(".button-properties")),
                    $(".button-properties").attr(
                      "title",
                      "Project properties"
                    ));
            }
          })))
    );
  }),
  (Trans.prototype.isCacheError = function () {
    return (
      (trans.project.cache = trans.project?.cache || {}),
      !(
        !trans.project.cache.cachePath ||
        0 != common.isDir(trans.project.cache.cachePath)
      )
    );
  }),
  (Trans.prototype.getSl = function () {
    return (
      (sys.config.default = sys.config.default || {}),
      this.getOption("sl") || sys.config.default?.sl || $DV.config.sl
    );
  }),
  (Trans.prototype.getTl = function () {
    return (
      (sys.config.default = sys.config.default || {}),
      this.getOption("tl") || sys.config.default?.tl || $DV.config.tl
    );
  }),
  (Trans.prototype.setSl = function (e) {
    this.project && this.setOption("sl", e);
  }),
  (Trans.prototype.setTl = function (e) {
    this.project && this.setOption("tl", e);
  }),
  (Trans.prototype.applyNewData = function (e) {
    e = e || [[]];
    for (var t = 0; t < e.length; t++) this.data[t] = e[t];
  }),
  (Trans.prototype.applyNewHeader = function (e) {
    e = e || [];
    for (var t = 0; t < e.length; t++) this.colHeaders[t] = e[t];
  }),
  (Trans.prototype.generateId = function () {
    return common.makeid(10, "tppSZ698");
  }),
  (Trans.prototype.initTransData = function (e) {
    e = e || {};
    var t = JSON.parse(fs.readFileSync("data/template.trans")),
      t =
        ((t.project ||= {}),
        (t.project.projectId = void 0),
        (t.project.buildOn = void 0),
        common.mergeDeep(t, e));
    return (
      (t.project = t.project || {}),
      (t.project.options = t.project.options || {}),
      (t.project.options.init = t.project.options.init || {}),
      (t.project.projectId = t.project.projectId || this.generateId(10)),
      (t.project.buildOn = t.project.buildOn || common.formatDate(Date.now())),
      (t.project.editorVersion = nw.App.manifest.version),
      (t.project.editorName = "Translator++"),
      t
    );
  }),
  (Trans.prototype.createFileData = function (e, t, n = {}) {
    return (
      (t = t || {}),
      (e = e.replace(/\\/g, "/")),
      n?.leadSlash && "/" !== e.charAt(0) && (e = "/" + e),
      (t.basename = t.basename || nwPath.basename(e)),
      (t.filename = t.filename || nwPath.basename(e)),
      (t.path = t.path || e),
      (t.relPath = t.relPath || e),
      (t.data = t.data || [[null]]),
      (t.originalFormat = t.originalFormat || "Autogenerated TRANS obj"),
      (t.type = t.type || ""),
      (t.context = t.context || []),
      (t.tags = t.tags || []),
      void 0 === t.extension && (t.extension = nwPath.extname(e)),
      void 0 === t.dirname && (t.dirname = nwPath.dirname(e)),
      t
    );
  }),
  (Trans.prototype.validateTransData = function (e) {
    var n,
      r,
      o,
      a = {};
    if (Array.isArray(e))
      return (
        console.log("Case 1 - transData is array"),
        ((n = this.loadJSONSync(this.getTemplatePath())).project.files[
          "/main"
        ] = this.createFileData("/main", { data: e })),
        n
      );
    if (
      0 == Boolean(e.project) &&
      0 == Boolean(e.files) &&
      Array.isArray(e.data)
    )
      return (
        console.log("Case 1 - transData is file structured"),
        (n = this.loadJSONSync(this.getTemplatePath())),
        (r = e.path || "/main"),
        (n.project.files[r] = this.createFileData(r, { data: e.data })),
        n
      );
    for (o in (0 == Boolean(e.project) && 1 == Boolean(e.files)
      ? (a.project = e)
      : (a = e),
    (a.project.gameTitle = a.project.gameTitle || t("untitled project")),
    (a.project.gameEngine = a.project.gameEngine || ""),
    (a.project.projectId = a.project.projectId || ""),
    (a.project.buildOn = a.project.buildOn || common.formatDate()),
    (a.project.files = a.project.files || {}),
    a.project.files))
      a.project.files[o] = this.createFileData(o, a.project.files[o]);
    return a;
  }),
  (Trans.prototype.normalizeHeader = function () {
    for (var e = 0; e < this.columns.length; e++)
      e == this.keyColumn && (this.columns[e].validator = this.validateKey),
        (this.columns[e].wordWrap = !0);
  }),
  (Trans.prototype.applySaveData = function (t) {
    if (
      (console.log("entering trans.applySaveData"),
      console.log(t),
      (t = this.validateTransData((t = t || {}))),
      (this.data = t.data || [[null]]),
      (this.columns = t.columns || this.default.columns || []),
      this.normalizeHeader(),
      (this.colHeaders = t.colHeaders || this.default.colHeaders || []),
      (this.project = t.project || {}),
      (this.gameTitle = t.project.gameTitle || ""),
      (this.gameEngine = t.project.gameEngine || ""),
      (this.projectId = t.project.projectId || ""),
      (this.gameFolder = t.project.loc || ""),
      0 == t.fileListLoaded)
    )
      try {
        void 0 !== t.project.files && (t.fileListLoaded = !0);
      } catch (e) {
        t.fileListLoaded = !1;
      }
    return (
      this.resetIndex(),
      (this.fileListLoaded = t.fileListLoaded || !1),
      this.initFileNav(),
      this.refreshGrid(),
      ui.setWindowTitle(),
      ui.setStatusBar(1, this.gameTitle),
      this
    );
  }),
  (Trans.prototype.getSaveData = function (e) {
    if (
      (((e = e || {}).filter = e.filter || []),
      (e.type = e.type || ""),
      !empty(this.project) && !empty(this.project.files))
    ) {
      this.project.projectId = this.project.projectId || common.makeid(10);
      var t = JSON.parse(JSON.stringify(this.project)) || {};
      if (
        0 < e.filter.length &&
        (console.log("filtering saved object", e), void 0 !== this.project) &&
        void 0 !== this.project.files
      ) {
        t.files = {};
        for (var n = 0; n < e.filter.length; n++) {
          var r = e.filter[n];
          console.log(
            "testing " + r,
            this.project.files[r],
            this.project.files
          ),
            void 0 !== this.project.files[r] &&
              (console.log("exist, assigning " + r),
              (t.files[r] = JSON.parse(JSON.stringify(this.project.files[r]))));
        }
      }
      var o,
        a = { data: [[null]] };
      (a.columns = this.columns || []),
        (a.colHeaders = this.colHeaders || []),
        (a.project = t),
        (a.fileListLoaded = this.fileListLoaded);
      for (let e = 0; e < this.grid.getColHeader().length; e++)
        a.columns[e] && (a.columns[e].width = this.grid.getColWidth(e));
      for (o in a.project.files)
        "reference" == a.project.files[o].type &&
          ((a.project.references = a.project.references || {}),
          (a.project.references[o] = JSON.parse(
            JSON.stringify(a.project.files[o])
          )),
          delete a.project.files[o]);
      return "json" == e.type ? JSON.stringify(a) : a;
    }
  }),
  (Trans.prototype.compress = async function (e, t) {
    t = t || {};
    var n = Buffer.from([]),
      n = Buffer.isBuffer(e)
        ? e
        : "string" == typeof e
        ? Buffer.from(e)
        : "object" != typeof e || empty(e)
        ? Buffer.from(JSON.stringify(this.getSaveData()))
        : Buffer.from(JSON.stringify(e));
    return common.gzip(n, t);
  }),
  (Trans.prototype.uncompress = async function (e, t) {
    t = t || {};
    var n = Buffer.from([]);
    if (Buffer.isBuffer(e)) n = e;
    else {
      if ("string" != typeof e)
        return console.error(
          "Can not uncompress from data:",
          e,
          "Only buffer or string is accepted"
        );
      n = Buffer.from(e);
    }
    return common.gunzip(n, t);
  }),
  (Trans.prototype.from = async function (e) {
    var t,
      n = "";
    if (
      (Buffer.isBuffer(e)
        ? (n = (
            "31,139,8,0" == e.slice(0, 10).join(",")
              ? (n = await common.gunzip(e))
              : e
          ).toString())
        : "string" == typeof e && (n = e),
      n)
    ) {
      if (0 == JSON.isJSON(n)) return console.error("unknown format :", e);
      t = JSON.parse(n);
    }
    return t;
  }),
  (Trans.prototype.createBackup = async function (e) {
    var t = parseInt(sys.getConfig("backupLevel"));
    if (sys.getConfig("autoBackup") && t) {
      if (!(await common.isFileAsync(e)))
        return console.warn("no such file ", e);
      if (0 != [".trans", ".tpp"].includes(nwPath.extname(e).toLowerCase())) {
        await common.unlink(e + `.${t}.bak`);
        for (var n = t - 1; 0 <= n; n--)
          0 == n
            ? await common.rename(e, e + `.${n + 1}.bak`)
            : 0 != (await common.isFileAsync(e + `.${n}.bak`)) &&
              (await common.rename(e + `.${n}.bak`, e + `.${n + 1}.bak`));
      }
    }
  }),
  (Trans.prototype.saveAs = async function (e, t) {
    e = await ui.saveAs(e || trans.currentFile || "");
    return console.log("Saving into : ", e), e ? this.save(e, t) : "";
  }),
  (Trans.prototype.save = async function (r, o) {
    if (!(r = r || this.currentFile)) return this.saveAs(r, o);
    var a = this;
    if (
      (((o = o || {}).initiator = o.initiator || "user"),
      (o.filter = o.filter || []),
      (o.onAfterLoading = o.onAfterLoading || function (e, t) {}),
      (o.onSuccess = o.onSuccess || function (e, t) {}),
      (o.onFailed = o.onFailed || function (e, t) {}),
      a.isSavingFile)
    )
      return console.warn(
        "Trans.prototype.save() is busy! Please wait until the previous save procedure to be completed before triggering another one!"
      );
    console.log("Saving data to : " + r);
    var i = a.getSaveData(o);
    return (
      console.log(i),
      (a.isSavingFile = !0),
      ui.saveIndicatorStart(),
      "user" == o.initiator && (await this.createBackup(r)),
      new Promise((t, n) => {
        fs.writeFile(r, JSON.stringify(i), (e) => {
          e
            ? ("function" == typeof o.onFailed && o.onFailed.call(a, i, r),
              ui.saveIndicatorEnd(),
              console.warn("Failed to save to : ", r, e),
              n())
            : ("auto" !== o.initiator &&
                (console.log(r + " successfully saved!"),
                sys.insertOpenedFileHistory(
                  r,
                  i.project.projectId,
                  i.project.gameTitle,
                  o.initiator
                ),
                (this.currentFile = r),
                a.gridIsModified(!1),
                ui.setWindowTitle()),
              "function" == typeof o.onSuccess && o.onSuccess.call(a, i, r),
              t(r)),
            o.onAfterLoading.call(a, i, r),
            setTimeout(function () {
              ui.saveIndicatorEnd();
            }, 1e3),
            (a.isSavingFile = !1);
        });
      })
    );
  }),
  (Trans.prototype.generateCachePath = function () {
    (this.project.cache = this.project.cache || {}),
      (this.project.cache.cacheID =
        this.project.cache.cacheID || this.project.projectId),
      this.project.cache.cacheID ||
        (this.project.cache.cacheID = this.project.projectId =
          common.makeid(10)),
      console.log(
        "Joining",
        sys.config.stagingPath,
        this.project.cache.cacheID
      ),
      (this.project.cache.cachePath =
        this.project.cache.cachePath ||
        nwPath.join(sys.config.stagingPath, this.project.cache.cacheID));
    try {
      fs.mkdirSync(this.project.cache.cachePath, { recursive: !0 });
    } catch (e) {
      console.warn(e);
    }
  }),
  (Trans.prototype.autoSave = async function (e) {
    if (((e = e || {}), void 0 === this.project))
      return (
        (e.onSuccess = e.onSuccess || function () {}),
        e.onSuccess.call(this),
        !1
      );
    try {
      (this.project.cache.cachePath &&
        common.isDir(this.project.cache.cachePath)) ||
        this.generateCachePath();
    } catch (e) {
      console.warn(e);
    }
    e.initiator = "auto";
    var t = nwPath.join(this.project.cache.cachePath, "autosave.json");
    return await this.save(t, e), t;
  }),
  (Trans.prototype.buildIndexFromData = function (e, t) {
    if ("object" != typeof e) return console.warn("fileData is not an object");
    if (0 == Array.isArray(e.data))
      return console.warn("fileData.data is not a valid array");
    if (!e.indexIsBuilt || t) {
      (e.data = e.data || []), (e.indexIds = e.indexIds || {});
      for (var n = 0; n < e.data.length; n++) {
        var r = e.data[n];
        r[0] && (e.indexIds[r[0]] = n);
      }
      e.indexIsBuilt = !0;
    }
    return e;
  }),
  (Trans.prototype.mergeTrans = function (e, t, n) {
    ((t = t || this).project = t.project || {}),
      (t.project.files = t.project.files || {}),
      ((e = e || {}).project = e.project || {}),
      (e.project.files = e.project.files || {}),
      ((n = n || {}).overwrite = n.overwrite || !1),
      (n.targetPair = n.targetPair || {}),
      (n.files = n.files || []),
      (n.all = n.all || !1),
      n.all && (n.targetPair = e.project.files);
    var r,
      o = !1;
    for (r in ((t = this.sanitize(t)) instanceof Trans && (o = !0),
    console.log("running mergeTrans with args : ", arguments),
    n.targetPair)) {
      var a = e.project.files[r],
        i = t.project.files[r];
      if (i) {
        if (
          (console.log("merging data", r),
          0 != Array.isArray(a.data) && 0 != a.data.length)
        ) {
          this.buildIndexFromData(i),
            (i.context = i.context || []),
            (a.context = a.context || []);
          for (var s = 0; s < a.data.length; s++) {
            var l,
              c = a.data[s];
            0 != Boolean(c[0]) &&
              (void 0 === (l = i.indexIds[c[0]]) && (l = i.data.length),
              (i.data[l] = common.clone(c)),
              (i.context[l] = common.clone(a.context[s])));
          }
        }
      } else
        (t.project.files[r] = common.clone(a)),
          o && this.addFileItem(r, t.project.files[r]);
    }
    return (
      o &&
        (this.generateHeader(t),
        this.evalTranslationProgress(),
        ui.fileList.reIndex(),
        ui.initFileSelectorDragSelect()),
      this.refreshGrid(),
      t
    );
  }),
  (Trans.prototype.loadJSONSync = function (t, e) {
    if ("" == t || null == t || void 0 === t) return !1;
    ((e = e || {}).onAfterLoading = e.onAfterLoading || function (e, t) {}),
      (e.onSuccess = e.onSuccess || function (e, t) {}),
      (e.onFailed = e.onFailed || function (e, t) {});
    (e = require("fs").readFileSync(t).toString()), (t = !1);
    try {
      return (t = JSON.parse(e));
    } catch (e) {
      return t;
    }
  }),
  (Trans.prototype.loadJSON = async function (t, e) {
    if ("" == t || null == t || void 0 === t) return !1;
    ((e = e || {}).onAfterLoading = e.onAfterLoading || function (e, t) {}),
      (e.onSuccess = e.onSuccess || function (e, t) {}),
      (e.onFailed = e.onFailed || function (e, t) {}),
      (this.isOpeningFile = !0),
      ui.showBusyOverlay();
    try {
      var n = await common.fileGetContents(t, "utf8", !1),
        r = JSON.parse(n);
    } catch (e) {
      alert("Error loading file: " + t);
    }
    return ui.hideBusyOverlay(), (this.isOpeningFile = !1), r;
  }),
  (Trans.prototype.importFromFile = async function (e, n) {
    ((n = n || {}).overwrite = n.overwrite || !1),
      (n.targetPair = n.targetPair || {}),
      (n.files = n.files || []),
      (n.mergeData = n.mergeData || !1);
    var r = this,
      o = this.isTrans(e)
        ? e
        : ((o = await r.loadJSON(e)), r.validateTransData(o));
    if (n.mergeData) r.mergeTrans(o, r, n);
    else {
      for (var a in n.targetPair) {
        "string" != typeof n.targetPair[a] && (n.targetPair[a] = a);
        try {
          "undefined" !== o.project.references[a] &&
            (r.project.files[n.targetPair[a]] = o.project.references[a]),
            void 0 !== o.project.files[a] &&
              ((r.project.files[n.targetPair[a]] = o.project.files[a]),
              console.log(
                t("create file list"),
                n.targetPair[a],
                r.project.files[n.targetPair[a]]
              ),
              r.addFileItem(n.targetPair[a], r.project.files[n.targetPair[a]]));
        } catch (e) {
          console.log(e);
          continue;
        }
      }
      ui.initFileSelectorDragSelect(),
        r.evalTranslationProgress(),
        ui.fileList.reIndex(),
        r.refreshGrid();
    }
  }),
  (Trans.prototype.selectCell = function (e, t) {
    return this.grid.selectCell(e, t);
  }),
  (Trans.prototype.getProjectChecksum = function () {
    if (!this.project.checksum) {
      var e,
        t = [],
        n = this.getAllFiles();
      for (e in (n.sort(), n)) {
        var r = this.project.files[n[e]];
        if (!empty(r) && !empty(r.data) && "*" != r.dirname) {
          for (var o = [], a = 0; a < r.data.length; a++)
            r.data[a][this.keyColumn] && o.push(r.data[a][this.keyColumn]);
          o.length < 1 ||
            (o.sort(), t.push(common.crc32String(JSON.stringify(o))));
        }
      }
      this.project.checksum = common.crc32String(JSON.stringify(t));
    }
    return this.project.checksum;
  }),
  (Trans.prototype.exportTPP = function (n, r) {
    if (void 0 === n) return !1;
    ((r = r || {}).showDetail = r.showDetail || !1),
      (r.onDone = r.onDone || function () {});
    for (
      var e = [],
        o = $(".fileList .data-selector .fileCheckbox:checked"),
        a = 0;
      a < o.length;
      a++
    )
      e.push(o.eq(a).attr("value"));
    (r.files = r.files || e || []),
      ui.saveIndicatorStart(),
      trans.autoSave({
        onSuccess: function () {
          php.spawn("saveTpp.php", {
            args: {
              path: n,
              password: r.password,
              gameFolder: trans.gameFolder,
              gameTitle: trans.gameTitle,
              projectId: trans.projectId,
              gameEngine: trans.gameEngine,
              files: r.files,
              exportMode: r.mode,
              rpgTransFormat: trans.config.rpgTransFormat,
            },
            onData: function (e) {
              r.showDetail &&
                ui.loadingProgress(t("Loading"), e, {
                  consoleOnly: !0,
                  mode: "consoleOutput",
                });
            },
            onError: function (e) {
              r.showDetail &&
                ui.loadingProgress(t("Loading"), e, {
                  consoleOnly: !0,
                  mode: "consoleOutput",
                  classStr: "stderr",
                });
            },
            onDone: function (e) {
              r.showDetail &&
                (ui.loadingProgress(t("Finished"), t("All process finished!"), {
                  consoleOnly: !1,
                  mode: "consoleOutput",
                }),
                ui.showCloseButton(),
                ui.log.addButtons(t("Open Explorer"), function () {
                  common.openExplorer(n);
                })),
                ui.saveIndicatorEnd(),
                r.onDone.call(trans, e);
            },
          });
        },
      });
  }),
  (Trans.prototype.importTpp = async function (e, r) {
    if (void 0 === e) return !1;
    (r = r || {}).onDone = r.onDone || function () {};
    var n = sys.getConfig("stagingPath");
    (await common.isDir(n)) || (await common.mkDir(n));
    trans.closeProject(),
      trans.autoSave({
        onSuccess: function () {
          ui.showLoading(),
            php.spawn("loadTpp.php", {
              args: { path: e, password: r.password },
              onData: function (e) {
                ui.loadingProgress(t("Loading"), e, {
                  consoleOnly: !0,
                  mode: "consoleOutput",
                });
              },
              onError: function (e) {
                ui.loadingProgress(t("Loading"), e, {
                  consoleOnly: !0,
                  mode: "consoleOutput",
                  classStr: "stderr",
                });
              },
              onDone: function (e) {
                console.log("done");
                var n = $(".console").find("output.cachepath").text(),
                  n = nwPath.join(n, "autosave.json");
                console.log("new cache path : ", n),
                  ui.loadingProgress(t("Loading"), t("Opening file!"), {
                    consoleOnly: !1,
                    mode: "consoleOutput",
                  }),
                  trans.open(n, {
                    onSuccess: function () {
                      (trans.project.cache = trans.project.cache || {}),
                        (trans.project.cache.cachePath = nwPath.dirname(n)),
                        ui.loadingProgress(
                          t("Loading"),
                          t(
                            "Assigning new staging path : " +
                              trans.project.cache.cachePath
                          ),
                          { consoleOnly: !1, mode: "consoleOutput" }
                        ),
                        ui.loadingProgress(t("Loading"), t("Success!"), {
                          consoleOnly: !1,
                          mode: "consoleOutput",
                        }),
                        ui.loadingProgress(
                          t("Finished"),
                          t("All process finished!"),
                          { consoleOnly: !1, mode: "consoleOutput" }
                        ),
                        ui.showCloseButton(),
                        r.onDone.call(trans, e);
                    },
                    onFailed: function () {
                      ui.loadingProgress(t("Loading"), t("Failed!"), {
                        consoleOnly: !1,
                        mode: "consoleOutput",
                      }),
                        ui.loadingProgress(
                          t("Finished"),
                          t("All process finished!"),
                          { consoleOnly: !1, mode: "consoleOutput" }
                        ),
                        ui.showCloseButton(),
                        r.onDone.call(trans, e);
                    },
                  });
              },
            });
        },
      });
  }),
  (Trans.prototype.export = async function (e, t) {
    if (void 0 === e) return !1;
    ((t = t || {}).options = t.options || {}),
      console.log("Exporting with arguments:", arguments),
      (t.mode = t.mode || "dir"),
      (t.onDone = t.onDone || function () {}),
      (t.dataPath = t.dataPath || ""),
      (t.transPath = t.transPath || ""),
      (t.options.filterTag = t.options.filterTag || t.filterTag || []),
      (t.options.filterTagMode =
        t.options.filterTagMode || t.filterTagMode || ""),
      (t.custom = t.custom || t.options.custom),
      delete t.options.custom,
      console.log("exporting project", arguments);
    for (
      var n = [],
        r = $(".fileList .data-selector .fileCheckbox:checked"),
        o = 0;
      o < r.length;
      o++
    )
      n.push(r.eq(o).attr("value"));
    t.files = t.files || n || [];
    var a = trans.project.gameEngine;
    if (
      void 0 !== engines[a] &&
      "function" == typeof engines[a].exportHandler
    ) {
      var i = await engines[a].exportHandler.apply(this, arguments);
      if ((console.log("Is process halt?", i), i))
        return void (await this.projectHook.run("afterExport", t));
    }
    (!["csv", "xlsx", "xls", "ods", "html", "RPGMakerTrans"].includes(t.mode) &&
      "spreadsheet" != a) ||
      this.legacyExport(e, t),
      console.log("Export process is finished");
  }),
  (Trans.prototype.legacyExport = async function (e, n) {
    var r = await trans.autoSave(),
      o =
        (ui.log.show(),
        await ui.log(
          "Exporting project to " + n.mode + " format with legacy mode"
        ),
        (trans.project.options = trans.project.options || {}),
        (trans.project.options.init = trans.project.options.init || {}),
        Object.assign(trans.project.options.init, n.options));
    php.spawn("export.php", {
      args: {
        path: e,
        gameFolder: trans.gameFolder,
        gameTitle: trans.gameTitle,
        projectId: trans.projectId,
        gameEngine: trans.gameEngine,
        files: n.files,
        exportMode: n.mode,
        options: o,
        rpgTransFormat: trans.config.rpgTransFormat,
        dataPath: n.dataPath,
        transPath: nwPath.resolve(n.transPath || r),
      },
      onData: function (e) {
        ui.loadingProgress(t("Loading"), e, {
          consoleOnly: !0,
          mode: "consoleOutput",
        });
      },
      onError: function (e) {
        ui.loadingProgress(t("Loading"), e, {
          consoleOnly: !0,
          mode: "consoleOutput",
          classStr: "stderr",
        });
      },
      onDone: async (e) => {
        console.log("done"),
          ui.loadingProgress(t("Finished"), t("All process finished!"), {
            consoleOnly: !1,
            mode: "consoleOutput",
          }),
          await this.projectHook.run("afterExport", n),
          ui.loadingEnd(),
          n.onDone.call(trans, e);
      },
    });
  }),
  (Trans.prototype.revertToOriginal = async function (e, t = {}) {
    var n = require("better-copy");
    if (
      ((e = e || (await ui.openRevertToOriginalDialog())),
      (t.dataPath = t.dataPath || "data"),
      e)
    ) {
      ui.showLoading(), ui.loadingProgress(0, "Reverting original data");
      var r,
        o = this.project.files,
        a =
          (0 < this.getCheckedFiles().length && (o = this.getCheckedObjects()),
          0),
        i = 0,
        s = Object.keys(o).length || 1;
      for (r in (ui.log(`Processing ${s} file(s)`), o)) {
        i++;
        var l = this.getStagingDataPath(),
          c = this.getStagingFile(o[r]),
          d = common.getRelativePath(c, l);
        await ui.loadingProgress(Math.round((i / s) * 100), "Reverting : " + d),
          (await common.isFileAsync(c))
            ? (await ui.log(i + `/${s} Copying : ` + c),
              await n(c, nwPath.join(e, d), { overwrite: !0 }),
              a++)
            : await ui.log("File not found: " + c);
      }
      await ui.log(`Completed! ${a} file(s) reverted to original!`),
        ui.log.addButtons(
          "Open folder",
          function () {
            nw.Shell.showItemInFolder(nwPath.join(e, d));
          },
          { class: "icon-folder-open" }
        ),
        ui.loadingEnd();
    }
  }),
  (Trans.prototype.importSheet = async function (n, o, a) {
    (o = o || 1),
      ((a = a || {}).sourceColumn = a.sourceColumn || "auto"),
      (a.overwrite = a.overwrite || !1),
      (a.files = a.files || trans.getCheckedFiles() || []),
      (a.sourceKeyColumn = a.sourceKeyColumn || 0),
      (a.keyColumn = a.keyColumn || 0),
      (a.newLine = a.newLine || void 0),
      (a.stripCarriageReturn = a.stripCarriageReturn || !1),
      (a.ignoreNewLine = !0),
      console.log("trans.importSheet"),
      console.log(arguments),
      0 == Array.isArray(n) && (n = [n]),
      ui.showLoading(),
      ui.loadingProgress(0, t("Collecting paths"), {
        consoleOnly: !0,
        mode: "consoleOutput",
      }),
      ui.log("Building indexes"),
      0 == a.files?.length && (a.files = this.getAllFiles()),
      (a.indexes = this.buildIndexes(a.files, !1, { stripCarriageReturn: !0 }));
    var r,
      i = [];
    for (let e = 0; e < n.length; e++) {
      var s,
        l = n[e];
      0 == common.isExist(l)
        ? (ui.loadingProgress(0, t("Path : '") + l + t("' doesn't exist"), {
            consoleOnly: !0,
            mode: "consoleOutput",
          }),
          console.log("Error, path not exist"))
        : common.isDir(l)
        ? ((s = common.dirContentSync(l)), (i = i.concat(s)))
        : i.push(l);
    }
    ui.loadingProgress(0, i.length + t(" file(s) collected!"), {
      consoleOnly: !0,
      mode: "consoleOutput",
    }),
      ui.loadingProgress(0, t("Start importing data!"), {
        consoleOnly: !0,
        mode: "consoleOutput",
      }),
      (r = common.parseSheet
        ? (ui.log("Import using sheet parser add-on"),
          async function (e) {
            var t,
              n = await common.parseSheet(e),
              r = [];
            for (t in n)
              console.log("Merging data", n[t]),
                n[t] && n[t].length && (r = r.concat(n[t]));
            console.log("output data :"),
              console.log(r),
              trans.translateFromArray(r, o, a);
          })
        : (ui.log("Import using legacy sheet importer"),
          function (e) {
            (e = e || l),
              php.spawnSync("import.php", {
                args: {
                  path: e,
                  output: null,
                  mergeSheet: !0,
                  prettyPrint: !0,
                },
                onDone: function (e) {
                  console.log("output data :"),
                    console.log(e),
                    trans.translateFromArray(e, o, a);
                },
              });
          }));
    for (let e = 0; e < i.length; e++) {
      var c = i[e];
      ui.loadingProgress(
        Math.round((e / i.length) * 100),
        t("Importing : ") + c,
        { consoleOnly: !0, mode: "consoleOutput" }
      ),
        await r(c),
        ui.loadingProgress(Math.round(((e + 1) / i.length) * 100), t("Done!"), {
          consoleOnly: !0,
          mode: "consoleOutput",
        });
    }
    trans.refreshGrid(),
      trans.evalTranslationProgress(),
      ui.loadingProgress(t("Done!"), t("All Done!"), {
        consoleOnly: !0,
        mode: "consoleOutput",
      }),
      ui.loadingEnd();
  }),
  (Trans.prototype.importRPGMTrans = function (e, n, r) {
    (n = n || 1),
      ((r = r || {}).sourceColumn = r.sourceColumn || "auto"),
      (r.overwrite = r.overwrite || !1),
      (r.files = r.files || trans.getCheckedFiles() || []),
      (r.sourceKeyColumn = r.sourceKeyColumn || 0),
      (r.keyColumn = r.keyColumn || 0),
      (r.newLine = r.newLine || void 0),
      (r.stripCarriageReturn = r.stripCarriageReturn || !1),
      (r.ignoreNewLine = !0),
      console.log("trans.importRPGMTrans"),
      console.log(arguments),
      0 == Array.isArray(e) && (e = [e]),
      ui.showLoading(),
      ui.loadingProgress(0, t("Collecting paths"), {
        consoleOnly: !0,
        mode: "consoleOutput",
      });
    for (var o = [], a = 0; a < e.length; a++) {
      var i,
        s = e[a];
      0 == common.isExist(s)
        ? (ui.loadingProgress(0, t("Path : '") + s + t("' doesn't exist"), {
            consoleOnly: !0,
            mode: "consoleOutput",
          }),
          console.log("Error, path not exist"))
        : common.isDir(s)
        ? ((i = common.dirContentSync(s)), (o = o.concat(i)))
        : o.push(s);
    }
    ui.loadingProgress(0, o.length + t(" file(s) collected!"), {
      consoleOnly: !0,
      mode: "consoleOutput",
    }),
      ui.loadingProgress(0, t("Start importing data!"), {
        consoleOnly: !0,
        mode: "consoleOutput",
      });
    for (let e = 0; e < o.length; e++) {
      var l = o[e];
      ui.loadingProgress(
        Math.round((e / o.length) * 100),
        t("Importing : ") + l,
        { consoleOnly: !0, mode: "consoleOutput" }
      ),
        (l = (l = l) || s),
        php.spawnSync("parseTrans.php", {
          args: { path: l, prettyPrint: !0 },
          onDone: function (e) {
            console.log("output data :"),
              console.log(e),
              Array.isArray(e.data) && trans.translateFromArray(e.data, n, r);
          },
        }),
        ui.loadingProgress(Math.round(((e + 1) / o.length) * 100), t("Done!"), {
          consoleOnly: !0,
          mode: "consoleOutput",
        });
    }
    trans.refreshGrid(),
      trans.evalTranslationProgress(),
      ui.loadingProgress(t("Done!"), t("All Done!"), {
        consoleOnly: !0,
        mode: "consoleOutput",
      }),
      ui.loadingEnd();
  }),
  (Trans.prototype.clearFooter = function () {
    $(".footer .footer1 span").html(""),
      $(".footer .footer2 span").html(""),
      $(".footer .footer3 span").html(""),
      $(".footer .footer4 span").html(""),
      $(".footer .footer5 span").html("");
  }),
  (Trans.prototype.setStatusBarContext = function (e) {
    void 0 === e &&
      Array.isArray(trans.grid.getSelected()) &&
      (e = trans.grid.getSelected()[0][0]);
    var t = trans.getSelectedId();
    try {
      "> ANTI TES PATCH FILE VERSION 0.2" ==
        trans.project.files[t].originalFormat &&
      "rmrgss" !== this.project.parser
        ? $(".footer .footer1>span").html(
            trans.buildContextFromParameter(
              trans.project.files[t].parameters[e]
            )
          )
        : $(".footer .footer1>span").html(
            trans.project.files[t].context[e].join("; ")
          ),
        $(".footer .footer1>span").addClass("icon-th-2");
    } catch (e) {
      $(".footer .footer1>span").html(""),
        $(".footer .footer1>span").removeClass("icon-th-2");
    }
  }),
  (Trans.prototype.setStatusBarNumData = function () {
    if (void 0 === trans.project) return !1;
    try {
      $(".footer .footer3 span").html(
        "rows : " + trans.project.files[trans.getSelectedId()].data.length
      );
    } catch (e) {
      $(".footer .footer3 span").html("");
    }
  }),
  (Trans.prototype.setStatusBarEngine = function () {
    if (void 0 === trans.project) return !1;
    try {
      var e = "";
      trans.project.parser &&
        (e = `/<span title='parser'>${trans.project.parser}</span>`),
        $(".footer .footer4 span").html(trans.project.gameEngine + e);
    } catch (e) {
      $(".footer .footer4 span").html("");
    }
  }),
  (Trans.prototype.setTrayIcon = function (e) {
    e = e || "translatorPlusPlus";
    var t = $('<i class="icon trayIcon"></i>');
    t.addClass(e), $(".footer .footer5 span").html(t);
  }),
  (Trans.prototype.goToNewKey = function () {
    if (0 == Array.isArray(this.data)) return !1;
    this.grid.scrollViewportTo(this.data.length - 1),
      this.grid.selectCell(this.data.length - 1, 0);
  }),
  (Trans.prototype.clearEditor = function () {
    var e = $("#currentCellText");
    return (
      e.val(""),
      e.prop("readonly", !0),
      e.data("column", null),
      e.data("row", null),
      !0
    );
  }),
  (Trans.prototype.clearCellInfo = function () {
    return $("#currentCoordinate").val(""), !0;
  }),
  (Trans.prototype.setCellInfo = function (e, t) {
    $("#currentCoordinate").val(e + 1 + "," + (t + 1)),
      (trans.lastSelectedCell = [e, t]);
  }),
  (Trans.prototype.drawCellEmblem = function () {
    var e = this.lastSelectedCell[0],
      t = this.lastSelectedCell[1];
    $(".cellEmblems > i").addClass("hidden"),
      t != this.keyColumn &&
        ($(".cellEmblems > .emblemComment").attr("title", ""),
        this.isOrganicCell(e, t) &&
          $(".cellEmblems > .emblemOrganic").removeClass("hidden"),
        (this.isVisitedCell(e, t)
          ? $(".cellEmblems > .emblemFootprint")
          : $(".cellEmblems > .emblemFirstVisit")
        ).removeClass("hidden"),
        (e = this.getCellComment(e, t))) &&
        ($(".cellEmblems > .emblemComment").removeClass("hidden"),
        $(".cellEmblems > .emblemComment").attr(
          "title",
          "<b>Cell comment:</b><br />" + e
        ));
  }),
  (Trans.prototype.connectData = function () {
    return this.getSelectedId() && this.project.files[this.getSelectedId()].data
      ? void (this.project.files[this.getSelectedId()].data = trans.data)
      : console.warn("unable to connect data with selected id");
  }),
  (Trans.prototype.isLastRow = function (e) {
    return (
      0 == Boolean(trans.data) && ((trans.data = []), trans.connectData()),
      (e = e || 0) == trans.data.length - 1
    );
  }),
  (Trans.prototype.getCurrentData = function () {
    return this.data;
  }),
  (Trans.prototype.getTextFromLastSelected = function () {
    var e = this.getCurrentData();
    return empty(this.lastSelectedCell)
      ? ""
      : e[this.lastSelectedCell[0]][this.lastSelectedCell[1]];
  }),
  (Trans.prototype.textEditorSetValue = function (e, t = !1) {
    $("#currentCellText").val(e),
      ui.generateBackgroundNumber(),
      t && $("#currentCellText").trigger("change");
  }),
  (Trans.prototype.doAfterSelection = function (e, t, n, r) {
    var o = $("#currentCellText"),
      a = (o.val(trans.data[e][t]), o.prop("readonly", !1), trans.isLastRow(e));
    if (
      (0 == t && 0 == a && o.prop("readonly", !0),
      o.data("column", t),
      o.data("row", e),
      trans.setCellInfo(e, t),
      trans.setStatusBarContext(e),
      trans.translateSelectedRow(e),
      ui.generateBackgroundNumber(o),
      "undefined" != typeof romaji)
    ) {
      if (0 == trans.config.loadRomaji) return !0;
      romaji.resolve(trans.data[e][0], $("#currentRomaji .text"));
    }
    $("#currentRomaji .header").text(this.getRowInfoText(e, !0) || ""),
      this.drawCellEmblem(),
      this.getOption("gridInfo")?.isRuleActive &&
        this.getOption("gridInfo")?.enableTrail &&
        (this._cellInfoTrack && clearTimeout(this._cellInfoTrack),
        t != this.keyColumn) &&
        this.getText(e, t) &&
        (this._cellInfoTrack = setTimeout(() => {
          clearTimeout(this._cellInfoTrack),
            (this._cellInfoTrack = void 0),
            console.log("Setting cellInfo", "v", 1, this.getSelectedId(), e, t),
            this.cellInfo.set("v", 1, this.getSelectedId(), e, t),
            $(`table tbody td[data-coord="${e}-${t}"]`).addClass("viewed");
        }, 1e3)),
      (this.getSelectedObject().lastSelectedCell = [e, t]),
      this.trigger("onAfterSelectCell", {
        fromRow: e,
        fromCol: t,
        toRow: n,
        toCol: r,
        isLastRow: a,
      });
  }),
  (Trans.prototype.resetCurentCellEditor = function () {
    var e = $("#currentCellText");
    e.val(""),
      e.data("row", 0),
      e.data("column", 0),
      trans.setCellInfo(0, 0),
      trans.setStatusBarContext(0),
      $("#currentRomaji .text").text(""),
      $("#currentRomaji .header").text("");
  }),
  (Trans.prototype.createFile = function (e, n, r) {
    ((r = r || {}).originalFormat = r.originalFormat || ""),
      (r.type = r.type || null);
    var o = require("is-valid-path");
    return (
      (n = n || "/"),
      o(e)
        ? o(n) || "*" === n
          ? ((o = nwPath.join("/", n, e)),
            this.getObjectById(o)
              ? { error: !0, msg: o + t(" is already exist") }
              : ((r =
                  "*" == n
                    ? ((o = e),
                      (r.type = r.type || "reference"),
                      this.createFileData(o, {
                        originalFormat:
                          r.originalFormat || "TRANSLATOR++ GENERATED TABLE",
                        type: r.type,
                        dirname: "*",
                      }))
                    : ((o = o.replace(/\\/g, "/")),
                      this.createFileData(o, {
                        originalFormat: r.originalFormat,
                        type: r.type,
                      }))),
                (trans.project.files[o] = r),
                trans.addFileItem(o, r),
                this.evalTranslationProgress(),
                ui.fileList.reIndex(),
                ui.initFileSelectorDragSelect(),
                {}))
          : { error: !0, msg: n + t(" is not a valid directory name") }
        : { error: !0, msg: e + t(" is not a valid object name") }
    );
  }),
  (Trans.prototype.selectFile = function (e, t) {
    ((t = t || {}).onDone = t.onDone || void 0), this.grid.deselectCell();
    t = (e =
      "string" == typeof e
        ? $(".fileList [data-id=" + common.escapeSelector(e) + "]")
        : e)
      .closest("li")
      .data("id");
    return (
      this.trigger("beforeSelectFile", [trans?.project?.selectedId, t]),
      e.closest(".tree").find("li").removeClass("selected"),
      e.closest("li").addClass("selected"),
      (trans.project.selectedId = t),
      (trans.data = trans.project.files[t].data),
      (trans.selectedData = trans.project.files[t]),
      trans.buildIndex(),
      trans.clearCellInfo(),
      trans.clearEditor(),
      trans.setStatusBarNumData(),
      trans.resetCurentCellEditor(),
      $(".menu-button.addNote").hasClass("checked") && ui.openFileNote(),
      $(".fileId").val(t),
      ui.disableGrid(!1),
      ui.evalFileNoteIcon(),
      this.trigger("objectSelected", t),
      this.grid.loadData(trans.data),
      trans.loadComments(),
      trans.renderGridInfo(),
      trans.grid.setFixedTableHeightByData(trans.data),
      trans.grid.scrollViewportTo(0, 0),
      e
    );
  }),
  (Trans.prototype.renderGridInfo = function () {
    var e = this.getOption("gridInfo") || {};
    e?.isRuleActive && e?.rowHeaderInfo
      ? ((e = e.rowHeaderWidth || 130),
        trans.grid.updateSettings({ rowHeaderWidth: e }),
        $("#table").css("--row-header-width", e + "px"))
      : (trans.grid.updateSettings({ rowHeaderWidth: null }),
        (e = $('#table [data-role="tablecorner"]').outerWidth()),
        $("#table").css("--row-header-width", e + "px"));
  }),
  (Trans.prototype.addFileGroup = function (e, t) {
    return (
      $("#fileList [data-group='" + CSS.escape(e) + "']").length < 1 &&
      ((e = $(
        "<li class='group-header'  data-group='" + e + "'>" + e + "</li>"
      )),
      0 < $("#fileList .fileListUl .group-header[data-group='*']").length
        ? $("#fileList .fileListUl .group-header[data-group='*']").before(e)
        : $("#fileList .fileListUl").append(e),
      !0)
    );
  }),
  (Trans.prototype.fileItemExist = function (e, t) {
    return (
      0 <
      $(
        "#fileList [data-group='" +
          CSS.escape(t.dirname) +
          "'][data-id='" +
          CSS.escape(e) +
          "']"
      ).length
    );
  }),
  (Trans.prototype.drawFileStatus = function (o) {
    "string" == typeof o && (o = [o]);
    for (var a = $("#fileList"), i = 0; i < o.length; i++)
      (() => {
        var e,
          t = o[i],
          n = this.getObjectById(t),
          r = a.find(`[data-id="${CSS.escape(o[i])}"]`);
        0 != r.length &&
          (r.removeClass("isCompleted"),
          r.removeClass("isRequireAttention"),
          n.isCompleted && r.addClass("isCompleted"),
          n.isRequireAttention && r.addClass("isRequireAttention"),
          r.data("noteTooltipIsActive") &&
            (r.tooltip("destroy"), r.data("noteTooltipIsActive", !1)),
          (t = r.find(".markers")).empty(),
          n.note) &&
          (t.append($('<span class="hidden"></span>').text(n.note)),
          (e = $('<i class="icon-commenting"></i>')),
          t.append(e),
          n.noteColor && e.css("color", n.noteColor),
          r.tooltip({
            content: function () {
              var e = $("<div class='fileObjTooltipWindow'></div>");
              return (
                n.noteColor &&
                  (e.css("border-left-color", n.noteColor),
                  e.addClass("hasColor")),
                e.text(n.note),
                e.on("mouseenter", function () {
                  ui.fileObjectTooltip.open(e.clone(), r);
                }),
                e
              );
            },
            tooltipClass: "fileObjTooltipWrapper",
            show: { effect: "fade", duration: 100 },
            hide: { effect: "none", delay: 100 },
            position: { my: "left top", at: "right+6 top-16", of: r },
            open: function (e, t) {},
          }),
          r.data("noteTooltipIsActive", !0));
      })();
  }),
  (Trans.prototype.addFileItem = function (e, t) {
    if (this.fileItemExist(e, t)) return !1;
    this.addFileGroup(t.dirname);
    var n = $("<li></li>");
    n.append(
      "<input type='checkbox' class='fileCheckbox' title='hold shift for bulk selection' /><a href='#' class='filterable'><span class='filename'></span><span class='markers'></span><span class='percent' title='progress'></span><div class='progress' title='progress'></div></a>"
    ),
      n.attr("title", e),
      n.attr("data-group", t.dirname),
      n.find(".fileCheckbox").attr("value", e),
      n.find(".filename").text(t.filename),
      n.addClass("data-selector"),
      n.data("id", e),
      n.attr("data-id", e),
      n.find("a").on("mousedown", function (e) {
        if (2 == e.which) return e.preventDefault(), trans.clearSelection(), !1;
      }),
      n.find("a").on("dblclick", function (e) {
        var t = $(this).closest("li").find(".fileCheckbox");
        t.prop("checked", !t.prop("checked")).trigger("change");
      }),
      n.find("a").on("click", function (e) {
        e.preventDefault(), trans.selectFile($(this).closest("li"));
      }),
      n.find(".fileCheckbox").on("change", function () {
        1 == $(this).prop("checked")
          ? ((trans.$lastCheckedFile = $(this)),
            $(this).closest(".data-selector").addClass("hasCheck"))
          : ((trans.$lastCheckedFile = void 0),
            $(this).closest(".data-selector").removeClass("hasCheck"));
      }),
      n.find(".fileCheckbox").on("mousedown", function (e) {
        if (
          (console.log("mouse down", console.log($(this).closest("li"))),
          (async () => {
            await common.wait(200),
              $(this).closest("li").removeClass("ds-hover");
          })(),
          !trans.$lastCheckedFile)
        )
          return !1;
        if (e.shiftKey) {
          console.log("The SHIFT key was pressed!");
          var t,
            n = $(".fileList .fileCheckbox"),
            e = n.index(trans.$lastCheckedFile),
            r = n.index(this),
            o = e < r ? ((t = e), r) : ((t = r), e);
          console.log("check from index " + t + " to " + o);
          for (var a = t; a < o; a++)
            n.eq(a).prop("checked", !0).trigger("change");
        }
      }),
      $("#fileList [data-group='" + CSS.escape(t.dirname) + "']")
        .last()
        .after(n);
  }),
  (Trans.prototype.drawFileSelector = function () {
    if (void 0 === this.project.files) return !1;
    for (var e in ($("#fileList .fileListUl").empty(),
    this.generateNewDictionaryTable(),
    this.project.files))
      this.addFileItem(e, this.project.files[e]);
    this.drawFileStatus(this.getAllFiles()),
      this.setStatusBarEngine(),
      this.evalTranslationProgress(),
      ui.fileList.reIndex(),
      ui.initFileSelectorDragSelect(),
      ui.enableButtons(),
      this.renderGridInfo();
    var t = require("www/js/TranslationByContext.js");
    (ui.translationByContext = new t()),
      ui.ribbonMenu.select("home"),
      (this.inProject = !0),
      engines.current().triggerHandler("onLoadTrans", this, arguments),
      this.initLocalStorage(),
      this.trigger("onLoadTrans");
  }),
  (Trans.prototype.initLocalStorage = async function () {
    var e = trans?.project?.projectId || "global";
    this.localStorage = new (require("better-localstorage"))("tp" + e);
  }),
  (Trans.prototype.unInitLocalStorage = async function () {
    "function" == typeof this.localStorage?.db?.close &&
      (await this.localStorage.db.close()),
      (this.localStorage = void 0);
  }),
  (Trans.prototype.setMarkAsComplete = function (e, t) {
    (t = t || trans.getCheckedFiles()).length < 1 && (t = trans.getAllFiles());
    for (var n = 0; n < t.length; n++) {
      var r = t[n];
      this.getObjectById(r).isCompleted = e;
    }
    return this.drawFileStatus(t), !0;
  }),
  (Trans.prototype.selectAll = function (t, e) {
    (e = e || !1), "string" == typeof (t = t || []) && (t = [t]);
    var n = $("#fileList .fileCheckbox");
    0 == t.length
      ? n.each(function () {
          $(this).prop("checked", !0).trigger("change");
        })
      : (e || n.prop("checked", !1).trigger("change"),
        n.each(function () {
          var e = $(this);
          t.includes(e.closest("li").data("id")) &&
            e.prop("checked", !0).trigger("change");
        }));
  }),
  (Trans.prototype.selectObjectsByFilter = function (t) {
    var e = $("#fileList .fileCheckbox");
    "function" == typeof t &&
      e.each(function () {
        var e = $(this);
        t(e.closest("li").data("id"), e) &&
          e.prop("checked", !0).trigger("change");
      });
  }),
  (Trans.prototype.invertSelection = function () {
    $("#fileList .fileCheckbox").each(function () {
      $(this).prop("checked", !$(this).prop("checked")).trigger("change");
    });
  }),
  (Trans.prototype.clearSelection = function () {
    $("#fileList .fileCheckbox").each(function () {
      $(this).prop("checked", !1).trigger("change");
    });
  }),
  (Trans.prototype.initFileNav = function () {
    console.log("running trans.initFileNav");
    try {
      void 0 !== trans.project.files
        ? (trans.fileListLoaded = !0)
        : (trans.fileListLoaded = !1);
    } catch (e) {
      trans.fileListLoaded = !1;
    }
    if (0 == trans.fileListLoaded)
      return (
        trans.createProject({
          onAfterLoading: function () {
            trans.drawFileSelector();
          },
        }),
        !1
      );
    this.unInitFileNav(),
      trans.drawFileSelector(),
      this.onFileNavLoaded.call(this),
      this.trigger("transLoaded", this);
  }),
  (Trans.prototype.unInitFileNav = function () {
    $("#fileList .fileListUl").empty(),
      ui.fileList.reIndex(),
      this.onFileNavUnloaded.call(this),
      engines.handler("onUnloadTrans").apply(this, arguments),
      ui.ribbonMenu.clear(),
      ui.disableButtons(),
      this.trigger("onUnloadTrans");
  }),
  (Trans.prototype.evalTranslationProgress = function (e, t) {
    e = e || [];
    var n,
      r = t || trans.countTranslated(e) || {};
    for (n in r) {
      var o = $(".fileList [data-id=" + common.escapeSelector(n) + "]");
      o.find(".percent").text(Math.round(r[n].percent)),
        o
          .find(".progress")
          .css(
            "background",
            "linear-gradient(to right, #3159f9 0%,#3159f9 " +
              r[n].percent +
              "%,#ff0004 " +
              r[n].percent +
              "%,#ff0004 100%)"
          );
    }
  }),
  (Trans.prototype.getStats = function (e) {
    var t = {
        files: 0,
        folders: 0,
        progress: 0,
        words: 0,
        characters: 0,
        rows: 0,
        rowTranslated: 0,
        percent: 0,
        organic: 0,
      },
      n = !1;
    if (this.project && this.project.files) {
      for (var r in (e ||
        (this.project.stats && ((n = !0), (t = this.project.stats))),
      this.project.files)) {
        var o = this.project.files[r];
        if (
          "TRANSLATOR++ GENERATED TABLE" != o.originalFormat &&
          (t.files++,
          o.progress &&
            ((t.rows += o.progress.length),
            (t.rowTranslated += o.progress.translated)),
          !n && !empty(o.data))
        )
          for (var a = 0; a < o.data.length; a++) {
            var i = o.data[a];
            empty(i) ||
              (i[this.keyColumn] &&
                ((t.characters += i[this.keyColumn].length),
                (t.words += i[this.keyColumn].trim().split(/\s+/).length),
                "HU" == this.cellInfo.getBestCellInfo(r, a, "t")) &&
                t.organic++);
          }
      }
      0 < t.rows && (t.percent = (t.rowTranslated / t.rows) * 100),
        (t.folders = $(".fileList  .group-header").length - 1),
        (t.organicPercent = (t.organic / t.rowTranslated) * 100),
        (this.stats = t);
    }
    return t;
  }),
  (Trans.prototype.setFileNoteColor = function (e, t) {
    for (var n in ((t ||= this.getSelectedId()),
    (t = 0 == Array.isArray(t) ? [t] : t))) {
      n = this.getObjectById(t[n]);
      e ? (n.noteColor = e) : n.noteColor && delete n.noteColor;
    }
    this.drawFileStatus(t), ui.evalFileNoteIcon();
  }),
  (Trans.prototype.setFileNote = function (e, t) {
    for (var n in ((t ||= this.getSelectedId()),
    (t = 0 == Array.isArray(t) ? [t] : t)))
      this.getObjectById(t[n]).note = e;
    this.drawFileStatus(t), ui.evalFileNoteIcon(), ui.fileList.reIndex();
  }),
  (Trans.prototype.loadComments = function () {
    trans.grid.comment = trans.grid.comment || trans.grid.getPlugin("comments");
    var e,
      t = trans.getSelectedObject();
    if (!t) return !1;
    if (void 0 === t.comments) return !1;
    for (e in t.comments)
      for (var n in t.comments[e])
        trans.grid.comment.setCommentAtCell(
          parseInt(e),
          parseInt(n),
          t.comments[e][n]
        );
  }),
  (Trans.prototype.runCustomScript = async function (e, n, r) {
    console.log("Running custom script with arguments:", arguments),
      (r = r || {});
    var o = new (require("www/js/CodeRunner.js"))(),
      a = await common.fileGetContents(n);
    if (!a) return alert(t("Error opening file :" + n));
    await ui.showBusyOverlay(), await common.wait(200);
    try {
      var i = await o.run(a, e, r);
      i && alert(i);
    } catch (e) {
      alert(t("Error executing :") + nwPath.basename(n) + "\n" + e.toString());
    }
    await ui.hideBusyOverlay();
  }),
  (Trans.prototype.updateRunScriptMenu = function () {
    console.log("Updating run script menu"),
      (this.fileSelectorMenu = this.fileSelectorMenu || {}),
      (this.fileSelectorMenu.withSelected.items.runScript.items.forEachRowRun.items =
        {});
    var a =
        this.fileSelectorMenu.withSelected.items.runScript.items.forEachRowRun
          .items,
      i = sys.getConfig("codeEditor/rowIterator");
    i || sys.setConfig("codeEditor/rowIterator", { quickLaunch: [] }),
      ((i ||= {}).quickLaunch ||= []);
    for (let n = 0; n < i.quickLaunch.length; n++)
      (() => {
        var r = i.quickLaunch[n],
          o = common.getFilename(r),
          e = common.generateId();
        a[e] = {
          name: o,
          callback: (e, n) => {
            confirm(
              t("Are you sure want to execute the following script?") + "\n" + o
            ) && this.runCustomScript("rowIterator", r);
          },
        };
      })();
    0 < Object.keys(a).length
      ? ((a.sep0 = "---------"),
        (a.clearQuickLaunch = {
          name: t("Clear quick launch"),
          icon: "context-menu-icon icon-trash",
          callback: (e, n) => {
            confirm(t("Are you sure want to clear quick launch?")) &&
              (sys.setConfig("codeEditor/rowIterator", { quickLaunch: [] }),
              sys.saveConfig(),
              this.updateRunScriptMenu());
          },
        }))
      : (a.howToAdd = {
          name: t("How to add Automation here"),
          icon: "context-menu-icon icon-help",
          callback: (e, t) => {
            nw.Shell.openExternal(
              "https://dreamsavior.net/docs/translator/execute-script/pin-your-automation-to-quickly-launch-from-translator/"
            );
          },
        }),
      (this.fileSelectorMenu.withSelected.items.runScript.items.forEachObjectRun.items =
        {});
    var s =
        this.fileSelectorMenu.withSelected.items.runScript.items
          .forEachObjectRun.items,
      l = sys.getConfig("codeEditor/objectIterator");
    l ||
      (sys.setConfig("codeEditor/objectIterator", { quickLaunch: [] }),
      (l = sys.getConfig("codeEditor/objectIterator"))),
      (l.quickLaunch = l.quickLaunch || []);
    for (let n = 0; n < l.quickLaunch.length; n++)
      (() => {
        var r = l.quickLaunch[n],
          o = common.getFilename(r),
          e = common.generateId();
        s[e] = {
          name: o,
          callback: (e, n) => {
            confirm(
              t("Are you sure want to execute the following script?") + "\n" + o
            ) && this.runCustomScript("objectIterator", r);
          },
        };
      })();
    0 < Object.keys(s).length
      ? ((s.sep0 = "---------"),
        (s.clearQuickLaunch = {
          name: t("Clear quick launch"),
          icon: "context-menu-icon icon-trash",
          callback: (e, n) => {
            confirm(t("Are you sure want to clear quick launch?")) &&
              (sys.setConfig("codeEditor/objectIterator", { quickLaunch: [] }),
              sys.saveConfig(),
              this.updateRunScriptMenu());
          },
        }))
      : (s.howToAdd = {
          name: t("How to add Automation here"),
          icon: "context-menu-icon icon-help",
          callback: (e, t) => {
            nw.Shell.openExternal(
              "https://dreamsavior.net/docs/translator/execute-script/pin-your-automation-to-quickly-launch-from-translator/"
            );
          },
        });
  }),
  (Trans.prototype.updateRunScriptGridMenu = function () {
    this.gridContextMenu.runAutomation.submenu = { items: [] };
    var n = this.gridContextMenu.runAutomation.submenu.items,
      a = sys.getConfig("codeEditor/gridSelection");
    a ||
      (sys.setConfig("codeEditor/gridSelection", { quickLaunch: [] }),
      (a = sys.getConfig("codeEditor/gridSelection"))),
      (a.quickLaunch = a.quickLaunch || []);
    for (var i = 0; i < a.quickLaunch.length; i++)
      (() => {
        var r = a.quickLaunch[i],
          o = (console.log("Adding context menu", r), common.getFilename(r)),
          e = common.generateId();
        n.push({
          name: o,
          key: "runAutomation:" + e,
          callback: (e, n) => {
            confirm(
              t("Are you sure want to execute the following script?") + "\n" + o
            ) && this.runCustomScript("gridSelection", r);
          },
        });
      })();
  }),
  (Trans.prototype.fileSelectorContextMenuInit = function () {
    console.log("trans.fileSelectorContextMenuInit");
    var a = this;
    if (
      ((this.fileSelectorMenu = {
        selectAll: {
          name: t("Select all"),
          icon: "context-menu-icon icon-check2-all",
        },
        clearSelection: { name: t("Clear selection") },
        selectCompleted: { name: t("Select 100%") },
        selectIncompleted: { name: t("Select <100%") },
        selectProgressGT: { name: t("Select progress ≥ ...") },
        selectMarkedAsCompleted: { name: t("Select completed") },
        invertSelection: { name: t("Invert selection") },
        sep0: "---------",
        markCompleteCurrent: {
          name: t("Toggle mark as complete"),
          icon: function () {
            return "context-menu-icon icon-ok";
          },
        },
        sep1: "---------",
        withSelected: {
          name: () => {
            var e = $(".fileCheckbox:checked").length;
            return 0 == e
              ? ((a.fileSelectorMenu.withSelected.icon =
                  "context-menu-icon icon-docs-1"),
                (a.fileSelectorMenu.withSelected.items.deleteFiles.visible =
                  !1),
                t("With all"))
              : t("With ") + e + t(" selected");
          },
          icon: function () {
            return "context-menu-icon icon-check";
          },
          items: {
            markComplete: {
              name: t("Mark as complete"),
              icon: "context-menu-icon icon-ok",
            },
            unsetMarkComplete: { name: t("Un-mark as complete") },
            "sep0-0": "---------",
            batchTranslation: {
              name: t("Batch translation"),
              icon: "context-menu-icon icon-language",
            },
            sendTo: {
              name: t("Send to..."),
              icon: "context-menu-icon icon-share-ios-line",
              items: {},
            },
            "sep0-1": "---------",
            wrapText: {
              name: t("Wrap texts"),
              icon: "context-menu-icon icon-wordwrap",
            },
            trim: { name: t("Trim"), icon: "context-menu-icon icon-article" },
            padding: {
              name: t("Auto padding"),
              icon: "context-menu-icon icon-list-nested",
            },
            createScript: {
              name: t("Create Automation"),
              icon: "context-menu-icon icon-code",
              items: {
                forEachObject: {
                  name: t("For each object"),
                  icon: "context-menu-icon icon-doc",
                },
                forEachRow: {
                  name: t("For each row"),
                  icon: "context-menu-icon icon-menu-1",
                },
              },
            },
            runScript: {
              name: t("Run Automation"),
              icon: "context-menu-icon icon-play",
              items: {
                forEachObjectRun: {
                  name: t("For each object"),
                  icon: "context-menu-icon icon-doc",
                  items: {},
                },
                forEachRowRun: {
                  name: () => (
                    console.log("rendering for each row"), t("For each row")
                  ),
                  icon: "context-menu-icon icon-menu-1",
                  items: {},
                },
              },
            },
            "sep0-2": "---------",
            import: {
              name: t("Import from..."),
              icon: "context-menu-icon icon-login",
              items: {
                importFromTrans: {
                  name: t("Trans File"),
                  icon: "context-menu-icon icon-tpp",
                },
                importFromSheet: {
                  name: t("Spreadsheets"),
                  icon: "context-menu-icon icon-file-excel",
                },
                importFromRPGMTransPatch: {
                  name: t("RPGMTransPatch Files"),
                  icon: "context-menu-icon icon-doc-text",
                },
              },
            },
            export: {
              name: t("Export into..."),
              icon: "context-menu-icon icon-export",
              items: {
                exportToGamePatch: {
                  name: t("A folder"),
                  icon: () => "context-menu-icon icon-folder-add",
                },
                exportToGamePatchZip: {
                  name: t("Zipped Game Patch"),
                  icon: () => "context-menu-icon icon-file-archive",
                },
                exportToCsv: {
                  name: t("Comma Separated Value (csv)"),
                  icon: () => "context-menu-icon icon-file-excel",
                },
                exportToXlsx: {
                  name: t("Excel 2007 Spreadsheets (xlsx)"),
                  icon: () => "context-menu-icon icon-file-excel",
                },
                exportToXls: {
                  name: t("Excel Spreadsheets (xls)"),
                  icon: () => "context-menu-icon icon-file-excel",
                },
                exportToOds: {
                  name: t("ODS Spreadsheets"),
                  icon: () => "context-menu-icon icon-file-excel",
                },
                exportToHtml: {
                  name: t("Html Spreadsheets"),
                  icon: () => "context-menu-icon icon-file-code",
                },
                exportToTransPatch: {
                  name: t("RMTrans Patch"),
                  icon: () => "context-menu-icon icon-doc-text",
                },
              },
            },
            inject: {
              name: t("Inject Translation"),
              icon: "context-menu-icon icon-download",
            },
            revert: {
              name: t("Revert to original"),
              icon: "context-menu-icon icon-ccw",
            },
            "sep0-3": "---------",
            clearTranslationSel: {
              name: t("Clear translation"),
              icon: "context-menu-icon icon-eraser",
            },
            deleteFiles: {
              name: t("Delete files"),
              icon: "context-menu-icon icon-trash-empty",
            },
          },
        },
        sep2: "---------",
        properties: {
          name: t("Properties"),
          icon: "context-menu-icon icon-cog",
        },
      }),
      a.fileSelectorContextMenuIsInitialized)
    )
      return !1;
    $.contextMenu({
      selector: ".fileList .data-selector",
      events: { preShow: function (e, t) {}, hide: function (e, t) {} },
      build: function (e, n) {
        return (
          a.updateRunScriptMenu(),
          {
            zIndex: 1e3,
            callback: function (e, n) {
              switch (e) {
                case "selectAll":
                  a.selectAll();
                  break;
                case "clearSelection":
                  a.clearSelection();
                  break;
                case "invertSelection":
                  a.invertSelection();
                  break;
                case "selectCompleted":
                  a.selectAll(a.getAllCompletedFiles());
                  break;
                case "selectIncompleted":
                  a.selectAll(a.getAllIncompletedFiles());
                  break;
                case "selectProgressGT":
                  let n = prompt(t("Select progress greater than"), "0");
                  isNaN(n)
                    ? alert(t("Please input a number"))
                    : a.selectObjectsByFilter((e, t) => {
                        e = a.getObjectById(e);
                        return (
                          !!e.progress &&
                          (e.progress.translated / e.progress.length) * 100 >=
                            parseInt(n)
                        );
                      });
                  break;
                case "selectMarkedAsCompleted":
                  a.selectAll(a.getAllMarkedAsCompleted());
                  break;
                case "markCompleteCurrent":
                  var r = $("#fileList .context-menu-active"),
                    o = !r.hasClass("isCompleted"),
                    r = r.data("id");
                  a.setMarkAsComplete(o, [r]);
                  break;
                case "markComplete":
                  a.setMarkAsComplete(!0);
                  break;
                case "unsetMarkComplete":
                  a.setMarkAsComplete(!1);
                  break;
                case "batchTranslation":
                  ui.translateAllDialog();
                  break;
                case "forEachObject":
                  ui.openAutomationEditor("codeEditor_objectIterator", {
                    workspace: "objectIterator",
                  });
                  break;
                case "forEachRow":
                  ui.openAutomationEditor("codeEditor_rowIterator", {
                    workspace: "rowIterator",
                  });
                  break;
                case "clearTranslationSel":
                  (o = confirm(t("Do you want to clear translation?"))),
                    (r = a.getCheckedFiles());
                  o &&
                    a.removeAllTranslation(a.getCheckedFiles(), {
                      refreshGrid: !0,
                    }),
                    a.evalTranslationProgress(r);
                  break;
                case "clearTranslationAll":
                  (o = confirm(t("Do you want to clear translation?"))),
                    (r = a.getAllFiles());
                  o &&
                    a.removeAllTranslation(a.getAllFiles(), {
                      refreshGrid: !0,
                    }),
                    a.evalTranslationProgress(r);
                  break;
                case "deleteFiles":
                  ui.deleteFiles();
                  break;
                case "wrapText":
                  ui.batchWrapingDialog();
                  break;
                case "trim":
                  ui.openTrimWindow();
                  break;
                case "padding":
                  ui.openPaddingWindow();
                  break;
                case "properties":
                  ui.openFileProperties();
                  break;
                case "importFromSheet":
                  ui.openImportSpreadsheetDialog();
                  break;
                case "importFromTrans":
                  $("#importTrans").trigger("click");
                  break;
                case "importFromRPGMTransPatch":
                  ui.openImportRPGMTransDialog();
                  break;
                case "exportToGamePatch":
                  $("#dialogExport").data("options", {
                    files: a.getCheckedFiles(),
                  }),
                    $("#exportDir").trigger("click");
                  break;
                case "exportToGamePatchZip":
                  $("#dialogExport").data("options", {
                    files: a.getCheckedFiles(),
                  }),
                    $("#export").trigger("click");
                  break;
                case "exportToCsv":
                  $("#exportCSV").trigger("click");
                  break;
                case "exportToXlsx":
                  $("#dialogExport").data("options", {
                    files: a.getCheckedFiles(),
                  }),
                    $("#exportXLSX").trigger("click");
                  break;
                case "exportToXls":
                  $("#dialogExport").data("options", {
                    files: a.getCheckedFiles(),
                  }),
                    $("#exportXLS").trigger("click");
                  break;
                case "exportToOds":
                  $("#dialogExport").data("options", {
                    files: a.getCheckedFiles(),
                  }),
                    $("#exportODS").trigger("click");
                  break;
                case "exportToHtml":
                  $("#dialogExport").data("options", {
                    files: a.getCheckedFiles(),
                  }),
                    $("#exportHTML").trigger("click");
                  break;
                case "exportToTransPatch":
                  $("#dialogExport").data("options", {
                    files: a.getCheckedFiles(),
                  }),
                    $("#exportTrans").trigger("click");
                  break;
                case "inject":
                  ui.openInjectDialog();
                  break;
                case "revert":
                  a.revertToOriginal();
              }
            },
            items: a.fileSelectorMenu,
          }
        );
      },
    }),
      (a.fileSelectorContextMenuIsInitialized = !0);
  }),
  (Trans.prototype.gridBodyContextMenu = function () {
    $.contextMenu({
      selector: ".ht_master .htCore tbody, .ht_clone_left .htCore tbody",
      events: {
        preShow: function (e, t) {
          t = $(t.target);
          console.log(t),
            t.hasClass("highlight") && console.log("previously hightlighted"),
            console.log(arguments);
        },
        show: function (e, t) {
          console.log("selection on show : "),
            (trans.grid.lastContextMenuCellRange =
              trans.grid.getSelectedRange());
        },
        hide: function (e, t) {
          if (
            (console.log("reload selection : "),
            void 0 === trans.grid.lastContextMenuCellRange)
          )
            return !1;
          trans.grid.selectCells(trans.grid.lastContextMenuCellRange),
            console.log(trans.grid.getSelectedRange());
        },
      },
      build: function (e, n) {
        return {
          zIndex: 1e3,
          callback: function (e, t) {
            switch (e) {
              case "addComment":
                var n = void 0;
                try {
                  n = trans.grid.lastContextMenuCellRange[0].highlight;
                } catch (e) {}
                trans.editNoteAtCell(n);
                break;
              case "removeComment":
                trans.removeNoteAtSelected(trans.grid.lastContextMenuCellRange);
            }
          },
          items: {
            addComment: {
              name: t("Add comment"),
              icon: function () {
                return "context-menu-icon icon-commenting-o";
              },
            },
            removeComment: {
              name: t("Remove comment"),
              icon: function () {
                return "context-menu-icon icon-comment-empty";
              },
            },
            selectAll: { name: t("Select all") },
            invertSelection: { name: t("Invert selection") },
            sep0: "---------",
            withSelected: {
              name: "With all",
              items: {
                batchTranslation: { name: t("Batch translation") },
                wordWrap: { name: t("Wrap texts") },
              },
            },
          },
        };
      },
    });
  }),
  (Trans.prototype.evalContextsQuery = function () {
    if (0 == arguments.length) return !1;
    for (var e, t = [], n = 0; n < arguments.length; n++)
      "string" == typeof arguments[n]
        ? 0 != arguments[n].length &&
          ((e = arguments[n].split("\n").map(function (e) {
            return common.stripCarriageReturn(e);
          })),
          (t = t.concat(e)))
        : Array.isArray(arguments[n]) &&
          0 != arguments[n].length &&
          (t = t.concat(arguments[n]));
    return t;
  }),
  (Trans.prototype.isInContext = function (e, t, n) {
    if (0 == (n = n || []).length) return !0;
    if (
      ("string" == typeof n && (n = [n]),
      void 0 !== trans.project.files[e] &&
        void 0 !== trans.project.files[e].context[t])
    )
      for (
        var r = trans.project.files[e].context[t],
          o = (r =
            (r = 0 == Array.isArray(r) ? [r] : r).length < 1 &&
            void 0 !== trans.project.files[e].parameters[t]
              ? [
                  trans.buildContextFromParameter(
                    trans.project.files[e].parameters[t]
                  ),
                ]
              : r).join("\n"),
          a = 0;
        a < n.length;
        a++
      )
        if (-1 != (o = o.toLowerCase()).indexOf(n[a].toLowerCase())) return !0;
    return !1;
  }),
  (Trans.prototype.removeRowByContext = function (e, t, n, r) {
    (n = n || {}).matchAll = n.matchAll || !1;
    var o,
      a = trans.travelContext(e, t, {
        onMatch: function (e, t) {},
        matchAll: n.matchAll,
      });
    for (o in a)
      for (var i = a[o].length - 1; 0 <= i; i--)
        ((1 == a[o][i] && !0 !== r) || (1 != a[o][i] && !0 === r)) &&
          (console.log(
            "removing " +
              o +
              " row " +
              i +
              (!0 === r ? " (Not on whitelist)" : "")
          ),
          trans.removeRow(o, i));
    trans.refreshGrid();
  }),
  (Trans.prototype.collectContextKeyword = function (t, n, e) {
    if (void 0 === (t = t || trans.project)) return !1;
    if ((n = "string" == typeof (n = n || []) ? [n] : n).length < 1)
      for (var r in trans.project.files) n.push(r);
    var o = {};
    for (let e = 0; e < n.length; e++)
      for (var a = n[e], i = t.files[a].context, s = 0; s < i.length; s++)
        if (0 != Array.isArray(i[s]))
          for (var l = 0; l < i[s].length; l++)
            for (var c = (i[s][l] || "").split("/"), d = 0; d < c.length; d++)
              isNaN(c[d]) && ((o[c[d]] = o[c[d]] || 0), (o[c[d]] += 1));
    return o;
  }),
  (Trans.prototype.travelContext = function (t, n, r) {
    if (
      ((t = t || []),
      (n = n || []),
      ((r = r || {}).onMatch = r.onMatch || function () {}),
      (r.onNotMatch = r.onNotMatch || function () {}),
      (r.matchAll = r.matchAll || !1),
      "string" == typeof t && (t = [t]),
      0 == Array.isArray(n) && (n = [n]),
      t.length < 1)
    )
      for (var e in trans.project.files) t.push(e);
    var o = {};
    for (let e = 0; e < t.length; e++) {
      var a = t[e];
      o[a] = [];
      for (let e = 0; e < trans.project.files[a].context.length; e++) {
        var i = trans.project.files[a].context[e];
        if (
          (0 == Array.isArray(i) && (i = [i]), (o[a][e] = !1), i.length < 1)
        ) {
          if (!trans.project.files[a].parameters[e]) continue;
          i = [
            trans.buildContextFromParameter(
              trans.project.files[a].parameters[e]
            ),
          ];
        }
        for (var s = 0; s < i.length; s++)
          for (var l = i[s], c = 0; c < n.length; c++)
            r.matchAll
              ? common.matchAllWords(l, n[c]) && (o[a][e] = !0)
              : 0 <= l.toLowerCase().indexOf(n[c].toLowerCase()) &&
                (o[a][e] = !0);
      }
      for (let e = 0; e < o[a].length; e++)
        (1 == o[a][e] ? r.onMatch : r.onNotMatch).call(
          trans.project.files[a],
          a,
          e
        );
    }
    return o;
  }),
  (Trans.prototype.isOrganicCell = function (e, t, n) {
    return (
      !!this.project &&
      ((n ||= this.getSelectedId()), "HU" == this.cellInfo.getCell(n, e, t)?.t)
    );
  }),
  (Trans.prototype.isVisitedCell = function (e, t, n) {
    return (
      !!this.project &&
      ((n ||= this.getSelectedId()), Boolean(this.cellInfo.get("v", n, e, t)))
    );
  }),
  (Trans.prototype.getData = function (e) {
    return void 0 === e
      ? this.getCurrentData()
      : "string" == typeof e
      ? this.getObjectById(e).data
      : "object" == typeof e && Array.isArray(e.data)
      ? e.data
      : (console.warn("invalid id or object ", e), []);
  }),
  (Trans.prototype.addRow = function (e, t, n) {
    var r,
      o,
      e =
        "object" == typeof e
          ? e
          : ((e = e || this.getSelectedId()), this.getObjectById(e));
    return (
      (e.indexIds ||= {}),
      "string" == typeof t && t
        ? ((r = this.getIndexByKey(e, t)),
          console.log("Existing index is", r),
          void 0 !== r
            ? r
            : (((r = Array(trans.colHeaders.length).fill(null))[
                this.keyColumn
              ] = t),
              n && (r[1] = n),
              console.log("inserting row:", r),
              (n = trans.getData(e)),
              console.log("theData", n),
              empty(n[n.length - 1][0])
                ? ((n[(o = n.length - 1)] = r), (e.indexIds[t] = o))
                : ((o = n.push(r)), (e.indexIds[t] = o - 1), o)))
        : -1
    );
  }),
  (Trans.prototype.appendRow = function (e, t = []) {
    e =
      "object" == typeof e
        ? e
        : ((e = e || this.getSelectedId()), this.getObjectById(e));
    if (((e.indexIds ||= {}), 0 == Array.isArray(t))) return -1;
    if (t.length < 1) return -1;
    var n = t[this.keyColumn];
    if ("string" != typeof n) return -1;
    if (!n) return -1;
    var r = this.getIndexByKey(e, n);
    if ((console.log("Existing index is", r), void 0 !== r)) return r;
    t.length = trans.colHeaders.length;
    var o,
      r = common.clone(t),
      t = trans.getData(e);
    return (
      console.log("theData", t),
      empty(t[t.length - 1][0])
        ? ((t[(o = t.length - 1)] = r), (e.indexIds[n] = o))
        : ((o = t.push(r)), (e.indexIds[n] = o - 1), o)
    );
  }),
  (Trans.prototype.getIndexIds = function (e) {
    var t;
    return "string" == typeof (e = void 0 === e ? this.getSelectedId() : e)
      ? (t = this.getObjectById(e))
        ? (t.indexIsBuilt || this.buildIndex(e), t.indexIds)
        : {}
      : "object" == typeof e
      ? (t = (t = e).indexIsBuilt ? t : this.buildIndexFromData(t)).indexIds
      : (console.warn("Error getting Index ID for file:", e), {});
  }),
  (Trans.prototype.getIndexByKey = function (e, t) {
    return this.getIndexIds(e)[t];
  }),
  (Trans.prototype.isAllSelected = function () {
    return (
      trans.getCheckedFiles().length == Object.keys(trans.project.files).length
    );
  }),
  (Trans.prototype.getActiveTranslator = function () {
    return trans.project
      ? ((trans.project.options = trans?.project.options || {}),
        trans.project?.options?.translator || sys.config.translator)
      : sys.config?.translator;
  }),
  (Trans.prototype.appendTextToReference = function (e) {
    var n, r;
    return (
      !!this.isInProject() &&
      "string" == typeof e &&
      (e.trim()
        ? trans.isKeyExistOn(e, "Common Reference")
          ? trans.alert(
              "Unable to add <b>" +
                e +
                "</b>. That value already exist on Common Reference!"
            )
          : ((r =
              (n = trans.project.files["Common Reference"]).data.length - 1),
            0 == Boolean(n.data[r][0])
              ? (console.log("inserting to ref.data[lastKey][0]"),
                (n.data[r][0] = e),
                (n.indexIds[e] = r))
              : (console.log("append new data"),
                ((r = (r = new Array(trans.colHeaders.length)).fill(null))[0] =
                  e),
                n.data.push(r),
                (n.indexIds[e] = n.data.length - 1)),
            trans.alert("<b>" + e + "</b> " + t("added to reference table!")),
            !0)
        : trans.alert(
            "Cannot add empty text to reference. Please try again with a text selected, or use <b>CTRL+SHIFT+D</b> to add the selected row into reference."
          ))
    );
  }),
  (Trans.prototype.appendSelectedRowToReference = function () {
    var n = common.gridSelectedRows();
    if (this.isInProject()) {
      if (!n?.length) return this.alert("No row selected.");
      if (!this.getObjectById("Common Reference"))
        return this.alert(
          "This project don't have <b>Common Reference</b> file. Please create one first."
        );
      let t = 0;
      for (let e = 0; e < n.length; e++)
        -1 < this.appendRow("Common Reference", this.getData()[e]) && t++;
      return this.alert(t + " row(s) added to Common Reference."), !0;
    }
  }),
  (Trans.prototype.wordWrapFiles = function (e, n, r, o) {
    if (
      (0 == (e = "string" == typeof (e = e || []) ? [e] : e).length &&
        (e = this.getAllFiles()),
      (n = n || 1),
      0 == (r = r || n + 1))
    )
      return trans.alert(t("Can not modify Column 0"));
    ((o = o || {}).maxLength = o.maxLength || 41),
      (o.onDone = o.onDone || function () {}),
      (o.context = o.context || []);
    for (var a = 0; a < e.length; a++) {
      var i = e[a];
      if (
        (console.log("Wordwrapping file : " + i),
        void 0 !== trans.project.files[i])
      ) {
        o.lineBreak = o.lineBreak || trans.project.files[i].lineBreak || "\n";
        for (var s = trans.project.files[i].data, l = 0; l < s.length; l++)
          trans.isInContext(i, l, o.context) &&
            ("string" != typeof s[l][n] && (s[l][r] = s[l][n]),
            (s[l][r] = common.wordwrapLocale(
              s[l][n],
              o.maxLength,
              this.getTl(),
              o.lineBreak
            )));
      }
    }
    o.onDone.call(trans);
  }),
  (Trans.prototype.fillEmptyLine = function (e, t, n, r, o) {
    "string" == typeof (e = e || []) && (e = [e]),
      ((o = o || {}).project = o.project || trans.project),
      (o.keyColumn = o.keyColumn || 0),
      (o.lineFilter =
        o.lineFilter ||
        function () {
          return !0;
        }),
      (o.fromKeyOnly = o.fromKeyOnly || !1),
      (o.filterTag = o.filterTag || []),
      (o.overwrite = o.overwrite || !1),
      o.fromKeyOnly &&
        (console.warn("collecting data from key only"),
        (o.sourceCol = r || o.keyColumn)),
      "number" == typeof (t = t || []) && (t = [t]),
      0 == e.length && (e = trans.getAllFiles()),
      console.log(e);
    for (var a = 0; a < e.length; a++) {
      var i = e[a];
      if (!(0 < t.length))
        for (var s = o.project.files[i].data, l = 0; l < s.length; l++) {
          if ("blacklist" == o.filterTagMode) {
            if (this.hasTags(o.filterTag, l, i)) continue;
          } else if (
            "whitelist" == o.filterTagMode &&
            !this.hasTags(o.filterTag, l, i)
          )
            continue;
          (void 0 === n &&
            null == (n = trans.getTranslationColFromRow(s[l]))) ||
            (0 == o.overwrite && s[l][n]) ||
            (o.project.files[i].data[l][n] = trans.getTranslationByLine(
              s[l],
              o.keyColumn,
              {
                includeIndex: !0,
                priorityCol: n,
                onBeforeLineAdd: o.lineFilter,
                sourceCol: o.sourceCol,
              }
            ));
        }
    }
  }),
  (Trans.prototype.trimTranslation = function (e, t, n) {
    if (!trans.project) return !1;
    (e = e || trans.getSelectedId()),
      ((n = n || {}).refreshGrid = n.refreshGrid || !1),
      0 == Array.isArray(e) && (e = [e]),
      0 == Array.isArray(t) && (t = [t]);
    for (var r = 0; r < e.length; r++)
      for (
        var o = e[r],
          a = trans.project.files[o].data,
          i = trans.project.files[o].lineBreak || "\n",
          s = 0;
        s < a.length;
        s++
      )
        for (var l in t) {
          var c,
            l = t[l];
          l < 1 ||
            ("string" == typeof trans.project.files[o].data[s][l] &&
              ((c = trans.project.files[o].data[s][l]
                .split("\n")
                .map(function (e) {
                  return e.trim();
                })),
              (trans.project.files[o].data[s][l] = c.join(i))));
        }
    trans.refreshGrid();
  }),
  (Trans.prototype.paddingTranslation = function (e, t, n) {
    if (!trans.project) return !1;
    (e = e || trans.getSelectedId()),
      ((n = n || {}).keyId = n.keyId || 0),
      (n.includeInitialWhitespace = n.includeInitialWhitespace || !1),
      (n.refreshGrid = n.refreshGrid || !1),
      0 == Array.isArray(e) && (e = [e]),
      0 == Array.isArray(t) && (t = [t]);
    for (var r = /^[\s\u0009\u200b\u180e\u2060]+/g, o = 0; o < e.length; o++)
      for (
        var a = e[o],
          i = trans.project.files[a].data,
          s = trans.project.files[a].lineBreak || "\n",
          l = 0;
        l < i.length;
        l++
      )
        if ("string" == typeof trans.project.files[a].data[l][n.keyId]) {
          for (
            var c,
              d = trans.project.files[a].data[l][n.keyId].split(s),
              g = [],
              f = 0;
            f < d.length;
            f++
          ) {
            var u = d[f].match(r);
            0 == Boolean(u) && (u = ""), g.push(u);
          }
          for (c in t) {
            var p = t[c];
            if (
              !(p < 1) &&
              "string" == typeof trans.project.files[a].data[l][p]
            ) {
              for (
                var h = trans.project.files[a].data[l][p].split(s),
                  m = [],
                  y = 0;
                y < h.length;
                y++
              ) {
                var v = g[y] || "";
                n.includeInitialWhitespace
                  ? m.push(v + h[y])
                  : m.push(v + h[y].trim());
              }
              trans.project.files[a].data[l][p] = m.join(s);
            }
          }
        }
    trans.refreshGrid();
  }),
  (Trans.prototype.removeAllTranslation = function (e, t) {
    if (!trans.project) return !1;
    (e = e || trans.getSelectedId()),
      ((t = t || {}).refreshGrid = t.refreshGrid || !1),
      0 == Array.isArray(e) && (e = [e]);
    for (var n = 0; n < e.length; n++)
      for (
        var r = e[n], o = trans.project.files[r].data, a = 0;
        a < o.length;
        a++
      )
        for (var i = 1; i < o[a].length; i++)
          trans.project.files[r].data[a][i] = null;
    this.trigger("removeAllTranslation", { files: e, options: t }),
      t.refreshGrid && trans.refreshGrid();
  }),
  (Trans.prototype.deleteFile = function (e, n) {
    if (!trans.project) return !1;
    if (
      ((e = e || trans.getSelectedId()),
      (e = 0 == Array.isArray(e) ? [e] : e).length < 1)
    )
      return !0;
    for (var r = 0; r < e.length; r++) {
      var o,
        a = e[r];
      "reference" == trans.project.files[a].type
        ? alert(t("Unable to delete table : ") + a)
        : (a == trans.getSelectedId() && ui.disableGrid(!0),
          (o = JSON.parse(JSON.stringify(trans.project.files[a]))),
          (trans.project.trash = trans.project.trash || {}),
          (trans.project.trash[a] = o),
          $(
            ".panel-left .fileList [data-id=" + common.escapeSelector(a) + "]"
          ).remove(),
          delete trans.project.files[a]);
    }
    ui.fileList.reIndex(), this.trigger("afterDeleteFile", [e]);
  }),
  (Trans.prototype.stagingFilesRemove = async function (e) {
    Array.isArray(e) || (e = [e]);
    var t = this.getStagingPath();
    if (!t) return [];
    var n,
      r = [];
    for (n in e) {
      var o = nwPath.join(t, "data", e[n]);
      console.log("Removing", o),
        (await common.isFileAsync(o)) || console.log("Not found:", o),
        r.push(await common.unlink(e[n]));
    }
    return r;
  }),
  (Trans.prototype.removeRow = function (e, t, n) {
    if ((console.log("removing row : ", arguments), void 0 === e)) return !1;
    if (void 0 === t) return !1;
    (t = (t = 0 === t ? [0] : t) || []),
      (n = n || {}),
      0 == Array.isArray(t) && (t = [t]),
      (n.permanent = n.permanent || !1),
      (n.refreshGrid = n.refreshGrid || !1),
      (t = common.arrayUnique(t)).sort(function (e, t) {
        return t - e;
      }),
      console.log("Removing rows > should be ordered descendingly:", t);
    for (var r = 0; r < t.length; r++) {
      var o,
        a = t[r];
      void 0 === trans.project.files[e].data[a] ||
        (trans.project.files[e].data.splice(a, 1),
        trans.project.files[e].parameters &&
          trans.project.files[e].parameters.splice(a, 1),
        trans.project.files[e].context &&
          trans.project.files[e].context.splice(a, 1),
        trans.project.files[e].tags && trans.project.files[e].tags.splice(a, 1),
        this.cellInfo.deleteRow(e, a),
        (o = this.getObjectById(e).comments),
        empty(o)) ||
        (Array.isArray(o) ? o.splice(a, 1) : delete o[a]);
    }
    0 < t.length && (trans.project.files[e].indexIsBuilt = !1),
      this.trigger("afterRemoveRow", { file: e, rows: t, options: n }),
      n.refreshGrid && trans.refreshGrid();
  }),
  (Trans.prototype.clearRow = function (e, t, n = {}) {
    if ((e = "string" == typeof e ? trans.getObjectById(e) : e)) {
      if ("object" != typeof e || !Array.isArray(e.data))
        return console.warn("Invalid argument 1");
      Array.isArray(t) || (t = [t]), (n ||= {});
      for (var r = 0, o = 0; o < t.length; o++)
        for (var a = e.data[t[o]], i = 0; i < a.length; i++)
          i != this.keyColumn && ((a[i] = ""), r++);
      return r;
    }
  }),
  (Trans.prototype.removeColumn = function (e, n) {
    if (0 === e) return trans.alert(t("Can not remove key column!"));
    if (
      (((n = n || {}).permanent = n.permanent || !1),
      (n.refreshGrid = n.refreshGrid || !1),
      void 0 === trans.project)
    )
      return trans.alert(t("Please open or create a project first"));
    for (var r in trans.project.files)
      if (
        0 != Array.isArray(trans.project.files[r].data) &&
        0 != trans.project.files[r].data.length
      )
        for (var o = 0; o < trans.project.files[r].data.length; o++)
          trans.project.files[r].data[o].splice(e, 1),
            this.cellInfo.deleteCell(r, o, e);
    trans.colHeaders.splice(e, 1),
      trans.columns.splice(e, 1),
      n.refreshGrid && trans.refreshGrid();
  }),
  (Trans.prototype.renameColumn = function (e, n, r) {
    return 0 === e
      ? trans.alert(t("Can not set column name to blank!"))
      : (((r = r || {}).refreshGrid = r.refreshGrid || !1),
        void 0 !== trans.colHeaders[e] &&
          ((trans.colHeaders[e] = n),
          void (r.refreshGrid && trans.refreshGrid())));
  }),
  (Trans.prototype.rowHasMultipleContext = function (e, t) {
    return (
      !!(t = t || this.getSelectedObject()).context &&
      !(!t.context[e] || t.context[e].length <= 1)
    );
  }),
  (Trans.prototype.isTranslatedRow = function (e, t) {
    t = t || trans.data;
    for (var n = 1; n < t[e].length; n++)
      if (0 < (t[e][n] || "").length) return !0;
    return !1;
  }),
  (Trans.prototype.countFilledCol = function (e, t) {
    t = t || trans.data;
    for (var n = 0, r = 1; r < t[e].length; r++)
      0 < (t[e][r] || "").length && n++;
    return n;
  }),
  (Trans.prototype.getTranslationFromRow = function (t, n, r = []) {
    if (((r ||= []), 0 == Array.isArray(t))) return !1;
    if (0 == (n = n || 0)) {
      for (let e = t.length; 0 < e; e--)
        if (!r.includes(e) && t[e]) return t[e];
    } else
      for (let e = t.length; 0 <= e; e--)
        if (e != n && !r.includes(e) && t[e]) return t[e];
    return null;
  }),
  (Trans.prototype.getTranslationColFromRow = function (t, n) {
    if (0 == Array.isArray(t)) return !1;
    if (0 == (n = n || 0)) {
      for (let e = t.length; e > n; e--) if (t[e]) return e;
    } else for (let e = t.length; 0 <= e; e--) if (e != n && t[e]) return e;
    return null;
  }),
  (Trans.prototype.getTranslationByLine = function (t, e, n) {
    if (0 == Array.isArray(t)) return !1;
    ((n = n || {}).includeIndex = n.includeIndex || !1),
      (n.lineBreak = n.lineBreak || "\n"),
      (n.onBeforeLineAdd =
        n.onBeforeLineAdd ||
        function () {
          return !0;
        });
    var r = [];
    if (void 0 !== n.sourceCol) {
      var o = (t[n.sourceCol] || "").split("\n").map(function (e) {
        return common.stripCarriageReturn(e);
      });
      for (let e = 0; e < o.length; e++)
        0 != Boolean(o[e]) && n.onBeforeLineAdd(o[e]) && (r[e] = o[e]);
    } else
      for (let e = 0; e < t.length; e++)
        if (0 != e && (void 0 === n.priorityCol || e != n.priorityCol)) {
          var a = (t[e] || "").split("\n").map(function (e) {
            return common.stripCarriageReturn(e);
          });
          for (let e = 0; e < a.length; e++)
            0 != Boolean(a[e]) && n.onBeforeLineAdd(a[e]) && (r[e] = a[e]);
        }
    if (n.includeIndex) {
      var i = (t[0] || "").split("\n").map(function (e) {
        return common.stripCarriageReturn(e);
      });
      for (let e = 0; e < i.length; e++)
        0 != Boolean(i[e]) && n.onBeforeLineAdd(i[e]) && (r[e] = i[e]);
    }
    if (void 0 !== n.priorityCol)
      for (
        var s = (t[n.priorityCol] || "").split("\n").map(function (e) {
            return common.stripCarriageReturn(e);
          }),
          l = 0;
        l < s.length;
        l++
      )
        0 != Boolean(s[l]) && (r[l] = s[l]);
    return r.join(n.lineBreak);
  }),
  (Trans.prototype.generateTranslationPair = function (e, t) {
    if (((t = t || 0), 0 == Array.isArray(e))) return {};
    for (var n, r = {}, o = 0; o < e.length; o++)
      0 != Boolean(e[o][0]) &&
        null != (n = trans.getTranslationFromRow(e[o], t)) &&
        (r[e[o][0]] = n);
    return r;
  }),
  (Trans.prototype.getProgressColumnIndices = function () {
    var t = sys.getConfig("progressColumnIndices");
    if (t) {
      let e = t.replaceAll(" ", "").split(",");
      return (
        (e = e.map(function (e) {
          return parseInt(e);
        })),
        common.arrayUnique(e)
      );
    }
  }),
  (Trans.prototype.countTranslated = function (e) {
    0 == (e = "string" == typeof (e = e || []) ? [e] : e).length &&
      (e = this.getAllFiles());
    for (
      var t = this.getProgressColumnIndices(),
        n = (console.log("Progress column indices", t), {}),
        r = 0;
      r < e.length;
      r++
    ) {
      var o = this.project.files[e[r]].data;
      n[e[r]] = { translated: 0, length: 0, percent: 100 };
      for (var a = 0; a < o.length; a++)
        if (0 != Boolean(o[a][this.keyColumn])) {
          if (
            ((o[a][this.keyColumn] = o[a][this.keyColumn] || ""),
            (o[a][this.keyColumn] = o[a][this.keyColumn] + ""),
            this.lineByLineMode)
          ) {
            try {
              var i = o[a][0].split("\n").length;
            } catch (e) {
              throw (
                (console.error(
                  "Error when trying to split key string ",
                  o[a][0]
                ),
                e)
              );
            }
            for (var s = 1; s < o[a].length; s++)
              if (0 != Boolean(o[a][s]))
                if (
                  ("string" != typeof o[a][s] && (o[a][s] = o[a][s] + ""),
                  (o[a][s] = o[a][s] || ""),
                  i <= o[a][s].split("\n").length)
                ) {
                  n[e[r]].translated++;
                  break;
                }
          } else
            this.rowHasTranslation(o[a], this.keyColumn, t) &&
              n[e[r]].translated++;
          n[e[r]].length++;
        }
      0 < n[e[r]].length &&
        (n[e[r]].percent = (n[e[r]].translated / n[e[r]].length) * 100),
        100 < n[e[r]].percent && (n[e[r]].percent = 100),
        n[e[r]].percent < 0 && (n[e[r]].percent = 0),
        (this.project.files[e[r]].progress = n[e[r]]);
    }
    return n;
  }),
  (Trans.prototype.resetIndex = function (e) {
    for (var t in this.project.files) this.project.files[t].indexIsBuilt = !1;
  }),
  (Trans.prototype.buildIndex = function (e, t, n) {
    if (
      ((e = e || trans.getSelectedId()), (n = n || trans.keyColumn || 0), e)
    ) {
      var r = trans.project.files[e];
      if (r.indexIsBuilt && !0 !== t) return r.indexIds;
      var o = {};
      for (let e = 0; e < r.data.length; e++)
        void 0 !== r.data[e] &&
          null != r.data[e][n] &&
          "" != r.data[e][n] &&
          void 0 !== r.data[e][n] &&
          (o[r.data[e][n]] = e);
      return (
        (r.indexIds = o),
        (r.indexIsBuilt = !0),
        e == trans.getSelectedId() &&
          ((trans.indexIds = r.indexIds),
          (trans.indexIsBuilt = r.indexIsBuilt)),
        o
      );
    }
    if (!trans.indexIsBuilt || !0 === t) {
      for (let e = 0; e < trans.data.length; e++)
        void 0 !== trans.data[e] &&
          null != trans.data[e][n] &&
          "" != trans.data[e][n] &&
          void 0 !== trans.data[e][n] &&
          (trans.indexIds[trans.data[e][n]] = e);
      trans.indexIsBuilt = !0;
    }
    return trans.indexIds;
  }),
  (Trans.prototype.buildIndexes = function (n, e = !1, r = {}) {
    if (
      ((r ||= {}).customFilter,
      (r.indexId ||= ""),
      (this.customIndexes ||= {}),
      "function" == typeof r.customFilter)
    ) {
      console.log("Generating custom index mode");
      try {
        if ("string" != typeof r.customFilter("test"))
          return console.error(
            "Invalid customFilter. Custom filter should return string"
          );
      } catch (e) {
        return console.error(
          "Invalid customFilter. Custom filter should return string"
        );
      }
      r.indexId = "#auto.fn." + common.crc32String(r.customFilter.toString());
    }
    r.indexId && (this.customIndexes[r.indexId] = {}),
      0 == (n = (n = "string" == typeof n ? [n] : n) || []).length &&
        (n = this.getAllFiles());
    var o = {};
    if (e) {
      for (let t = 0; t < n.length; t++) {
        var a = this.getObjectById(n[t]);
        if (a) {
          a.indexIsBuilt || this.buildIndex(n[t]);
          var i,
            s = this.getObjectById(n[t]).indexIds;
          for (i in s)
            for (
              var l = i.replaceAll("\r", "").split("\n"), c = 0;
              c < l.length;
              c++
            ) {
              let e = l[c];
              (o[
                (e =
                  "function" == typeof r.customFilter ? r.customFilter(e) : e)
              ] = o[e] || []),
                o[e].push({ file: n[t], row: s[i], line: c });
            }
        }
      }
      r.indexId ? (this.customIndexes[r.indexId] = o) : (this._tempIndexes = o);
    } else {
      console.log("Files is", n);
      for (let e = 0; e < n.length; e++) {
        console.log("handling file:", n[e]);
        var t = this.getObjectById(n[e]);
        if ((console.log("ThisObject:", t), t)) {
          t.indexIsBuilt || this.buildIndex(n[e]);
          var d,
            g = this.getObjectById(n[e]).indexIds;
          for (d in g) {
            o[
              (d = "function" == typeof r.customFilter ? r.customFilter(d) : d)
            ] = o[d] || [];
            var f,
              u = { file: n[e], row: g[d] };
            o[d].push(u),
              d.includes("\r") &&
                r.stripCarriageReturn &&
                ((o[(f = d.replaceAll("\r", ""))] = o[f] || []), o[f].push(u));
          }
        }
      }
      r.indexId ? (this.customIndexes[r.indexId] = o) : (this._tempIndexes = o),
        console.log("Indexes is", o);
    }
    return o;
  }),
  (Trans.prototype.getFromIndexes = function (e, t, n) {
    return (
      "function" == typeof n &&
        ((n = "#auto.fn." + common.crc32String(n.toString())),
        this.customIndexes[n]) &&
        this.customIndexes[n][e],
      (t = t || this._tempIndexes || {})[e]
    );
  }),
  (Trans.prototype.clearTemporaryIndexes = function (e) {
    e
      ? "string" == typeof e
        ? this.customIndexes[e] && delete this.customIndexes[e]
        : "function" == typeof e &&
          ((e = "#auto.fn." + common.crc32String(e.toString())),
          this.customIndexes[e]) &&
          delete this.customIndexes[e]
      : delete this.customIndexes,
      (this._tempIndexes = void 0);
  }),
  (Trans.prototype.findIdByIndex = function (e, t) {
    return (
      null != trans.data &&
      "" != trans.data &&
      void 0 !== trans.data &&
      (void 0 === t
        ? (void 0 === trans.indexIds && trans.buildIndex(),
          void 0 !== trans.indexIds[e] && trans.indexIds[e])
        : (0 == trans.project.files[t].indexIsBuilt && trans.buildIndex(t),
          void 0 === trans.project.files[t].indexIds && trans.buildIndex(t),
          void 0 !== trans.project.files[t].indexIds[e] &&
            trans.project.files[t].indexIds[e]))
    );
  }),
  (Trans.prototype.getClearOnNextHumanInteract = function (e) {
    return (
      (this._clearOnNextHumanInteract = this._clearOnNextHumanInteract || {}),
      e
        ? ((this._clearOnNextHumanInteract[e] =
            this._clearOnNextHumanInteract[e] || {}),
          this._clearOnNextHumanInteract[e])
        : this._clearOnNextHumanInteract
    );
  }),
  (Trans.prototype.getRowIdByTextInsensitive = function (e, t) {
    if (null == this.data || "" == this.data || void 0 === this.data) return !1;
    if (!t) throw "second argument fileId is required!";
    var n = this.getClearOnNextHumanInteract("insensitiveIndex_" + t),
      r = this.getData(t),
      o = (e) => (e ? common.trimRightParagraph(e).toLowerCase() : "");
    if (empty(n))
      for (var a = 0; a < r.length; a++) n[o(r[a][this.keyColumn])] = a;
    return n[o(e)];
  }),
  (Trans.prototype.copyTranslationToRow = function (e, t, n) {
    if ((console.log("copyTranslationToRow", arguments), void 0 === e))
      return !1;
    if (
      (void 0 !== e.files && (e = e.files),
      (t = t || n.targetColumn || 1),
      ((n = n || {}).files = n.files || []),
      (n.mode = n.mode || ""),
      (n.fetch = n.fetch || ""),
      (n.filterTag = n.filterTag || []),
      (n.filterTagMode = n.filterTagMode || ""),
      (n.overwrite = n.overwrite || !1),
      0 == Array.isArray(n.files) && (n.files = [n.files]),
      0 == n.files.length)
    )
      for (var r in e) n.files.push(r);
    for (var o = 0; o < n.files.length; o++) {
      var a = n.files[o];
      if ((console.log("Handling", a), 0 != Boolean(e[a])))
        for (var i = trans.getObjectById(a), s = 0; s < e[a].data.length; s++) {
          var l,
            c = e[a].data[s];
          0 == Boolean(c[0]) ||
            empty(i.data[s]) ||
            (0 == n.overwrite && Boolean(i.data[s][t])) ||
            ((l = trans.getTranslationFromRow(c)),
            0 == Boolean(l) && (l = c[0]),
            (i.data[s][t] = l));
        }
    }
  }),
  (Trans.prototype.generateContextTranslationPair = function (t, n) {
    if ((console.log("Entering trans.generateTranslationTable"), void 0 === t))
      return !1;
    void 0 !== t.files && (t = t.files),
      console.log("obj files inside trans.generateTranslationTable :"),
      console.log(t);
    var r = {};
    if (
      (((n = n || {}).files = n.files || []),
      (n.mode = n.mode || ""),
      (n.fetch = n.fetch || ""),
      (n.filterTag = n.filterTag || []),
      (n.filterTagMode = n.filterTagMode || ""),
      0 == Array.isArray(n.files) && (n.files = [n.files]),
      0 == n.files.length)
    )
      for (var e in t) n.files.push(e);
    console.log("Worked option files : "), console.log(n.files);
    for (let e = 0; e < n.files.length; e++) {
      var o = n.files[e];
      if (0 != Boolean(t[o]))
        for (var a = 0; a < t[o].context.length; a++)
          if (0 != Boolean(t[o].context[a]) && 0 != Boolean(t[o].data[a])) {
            var i = trans.getTranslationFromRow(t[o].data[a]);
            if (
              (0 == Boolean(i) && (i = t[o].data[a][trans.keyColumn]),
              0 != Boolean(i))
            )
              for (var s = 0; s < t[o].context[a].length; s++)
                r[t[o].context[a][s]] = i;
          }
    }
    return console.log("translation table collection is : "), console.log(r), r;
  }),
  (Trans.prototype.generateTranslationTable = function (t, n) {
    if ((console.log("Entering trans.generateTranslationTable"), void 0 === t))
      return !1;
    void 0 !== t.files && (t = t.files),
      console.log("obj files inside trans.generateTranslationTable :"),
      console.log(t);
    var r = {};
    if (
      (((n = n || {}).files = n.files || []),
      (n.caseSensitive = n.caseSensitive || !1),
      (n.mode = n.mode || ""),
      (n.fetch = n.fetch || ""),
      (n.filterTag = n.filterTag || []),
      (n.filterTagMode = n.filterTagMode || ""),
      0 == Array.isArray(n.files) && (n.files = [n.files]),
      0 == n.files.length)
    )
      for (var e in t) n.files.push(e);
    if (
      (console.log("Worked option files : "),
      console.log(n.files),
      "linebyline" == n.mode.toLowerCase())
    )
      for (let e = 0; e < n.files.length; e++) {
        var o = n.files[e];
        console.log(o);
        for (var a = 0; a < t[o].data.length; a++)
          if (0 != Boolean(t[o].data[a][0])) {
            if ("blacklist" == n.filterTagMode) {
              if (this.hasTags(n.filterTag, a, o)) continue;
            } else if (
              "whitelist" == n.filterTagMode &&
              !this.hasTags(n.filterTag, a, o)
            )
              continue;
            var i = trans.getTranslationFromRow(t[o].data[a]);
            if ("untranslated" == n.fetch) {
              if (1 == Boolean(i)) continue;
            } else if ("both" != n.fetch && 0 == Boolean(i)) continue;
            for (
              var s = t[o].data[a][0].split("\n"),
                l = (i = i || "").split("\n").map(function (e) {
                  return (e = e || "").replaceAll(/\r/g, "");
                }),
                c = 0;
              c < s.length;
              c++
            ) {
              if ("untranslated" == n.fetch) {
                if (1 == Boolean(l[c])) continue;
              } else if ("both" != n.fetch && 0 == Boolean(l[c])) continue;
              r[s[c]] = l[c] || "";
            }
          }
      }
    else
      for (let e = 0; e < n.files.length; e++) {
        var d,
          g = n.files[e];
        if (0 != Boolean(t[g]))
          for (let e = 0; e < t[g].data.length; e++)
            0 != Boolean(t[g].data[e][0]) &&
              ((d = trans.getTranslationFromRow(t[g].data[e])),
              0 != Boolean(d)) &&
              (r[t[g].data[e][0]] = d);
      }
    return console.log("translation table collection is : "), console.log(r), r;
  }),
  (Trans.prototype.generateTranslationTableLine = function (t, n) {
    if (
      (console.log("Entering trans.generateTranslationTableLine", t, n),
      void 0 === t)
    )
      return !1;
    void 0 !== t.files && (t = t.files),
      console.log("obj files inside trans.generateTranslationTable :"),
      console.log(t);
    var r = {};
    ((n = n || {}).files = n.files || []),
      (n.caseSensitive = n.caseSensitive || !1),
      (n.mode = n.mode || ""),
      (n.fetch = n.fetch || ""),
      (n.keyColumn = n.keyColumn || 0),
      (n.filterTag = n.filterTag || []),
      (n.filterTagMode = n.filterTagMode || ""),
      (n.ignoreTranslated = n.ignoreTranslated || !1),
      (n.overwrite = n.overwrite || !1),
      (n.collectAddress = n.collectAddress || !1);
    try {
      n.filterLanguage = n.filterLanguage || this.getSl() || "ja";
    } catch (e) {
      n.filterLanguage = "ja";
    }
    if (
      ((n.ignoreLangCheck = n.ignoreLangCheck || !1),
      console.log("ignore language check?"),
      console.log(n.ignoreLangCheck),
      0 == Array.isArray(n.files) && (n.files = [n.files]),
      0 == n.files.length)
    )
      for (var e in t) n.files.push(e);
    console.log("Worked option files : "), console.log(n.files);
    var o = {};
    for (let e = 0; e < n.files.length; e++) {
      var a = n.files[e];
      console.log("fetching translatable data from:", a);
      for (let e = 0; e < t[a].data.length; e++)
        if (0 != Boolean(t[a].data[e][n.keyColumn])) {
          if ("blacklist" == n.filterTagMode) {
            if (this.hasTags(n.filterTag, e, a)) continue;
          } else if (
            "whitelist" == n.filterTagMode &&
            !this.hasTags(n.filterTag, e, a)
          )
            continue;
          if (
            !(
              (n.ignoreTranslated &&
                this.rowHasTranslation(t[a].data[e], n.keyColumn)) ||
              (0 == n.overwrite &&
                n.targetColumn &&
                t[a].data[e][n.targetColumn])
            )
          ) {
            console.log("Reached here!");
            for (
              var i = trans.getTranslationFromRow(t[a].data[e], n.keyColumn, [
                  0,
                ]),
                s =
                  (console.log("current translation", i),
                  t[a].data[e][n.keyColumn].split("\n")),
                l = (i = i || "").split("\n").map(function (e) {
                  return (e = e || "").replaceAll(/\r/g, "");
                }),
                c = 0;
              c < s.length;
              c++
            ) {
              if ("untranslated" == n.fetch) {
                if (1 == Boolean(l[c])) continue;
              } else if ("both" != n.fetch && 0 == Boolean(l[c])) continue;
              (0 == n.ignoreLangCheck &&
                0 == common.isInLanguage(s[c], n.filterLanguage)) ||
                ((r[s[c]] = l[c] || ""),
                n.collectAddress &&
                  ((o[s[c]] ||= []),
                  o[s[c]].push({
                    line: c,
                    file: a,
                    row: e,
                    rowObj: t[a].data[e],
                  })));
            }
          }
        }
    }
    return (
      console.log("result is : "),
      console.log(r),
      console.log("addresses:", o),
      n.collectAddress ? { pairs: r, addresses: o } : r
    );
  }),
  (Trans.prototype.generateTranslationTableFromStrings = function (t, e, n) {
    n = n || {};
    try {
      n.filterLanguage = n.filterLanguage || this.getSl() || "ja";
    } catch (e) {
      n.filterLanguage = "ja";
    }
    var r;
    n.ignoreLangCheck = n.ignoreLangCheck || !1;
    try {
      r = n.ignoreLangCheck || e.getOptions("ignoreLangCheck");
    } catch (e) {
      r = !1;
    }
    "string" == typeof t && (t = [t]);
    var o = { include: {}, exclude: {} };
    if ("rowByRow" == n.mode)
      for (let e = 0; e < t.length; e++)
        "string" != typeof t[e] ||
          t[e].length < 1 ||
          (r || 0 != common.isInLanguage(t[e], n.filterLanguage)
            ? (o.include[t[e]] = "")
            : (o.exclude[t[e]] = t[e]));
    else
      for (let e = 0; e < t.length; e++)
        if ("string" == typeof t[e] && !(t[e].length < 1))
          for (
            var a = t[e].replaceAll("\r", "").split("\n"), i = 0;
            i < a.length;
            i++
          ) {
            if (n.ignoreWhitespace) {
              if (!a[i]) continue;
              if (!a[i].trim()) continue;
            }
            r && 0 == common.isInLanguage(a[i], n.filterLanguage)
              ? (o.exclude[a[i]] = a[i])
              : (o.include[a[i]] = "");
          }
    return o;
  }),
  (Trans.prototype.generateTranslationTableFromResult = function (e, t, n) {
    for (var r = n || {}, o = 0; o < e.length; o++)
      void 0 !== t[o] && (r[e[o]] = t[o]);
    return r;
  }),
  (Trans.prototype.generateSelectedTranslationTable = function (e, t, n) {
    (e = e || this.grid.getSelectedRange() || [[]]),
      (t = t || this.getSelectedId());
    for (
      var r = common.gridSelectedCells(e), o = this.getData(t), a = {}, i = 0;
      i < r.length;
      i++
    ) {
      var s = r[i].row,
        l = r[i].col,
        c = o[s][this.keyColumn];
      (a[c] = a[c] || []),
        a[c].push({ col: l, row: s, value: o[s][l], file: t });
    }
    return a;
  }),
  (Trans.prototype.wordWrapText = function (t, n = [], r = [], o = "\n") {
    if (!empty(r) && !empty(n)) {
      if (window.langTools?.isCJK(this.getTl()))
        for (let e = 0; e < r.length; e++)
          if (0 < common.arrayIntersect(n, r[e].tags).length)
            return common.wordwrapLocale(t, r[e].maxLength, this.getTl(), o);
      for (let e = 0; e < r.length; e++)
        if (0 < common.arrayIntersect(n, r[e].tags).length)
          return common.wordwrap(t, r[e].maxLength, o);
    }
    return t;
  }),
  (Trans.prototype.getTranslationData = function (e, t) {
    ((t = t || {}).keyCol = t.keyCol || 0),
      (t.groupIndex = t.groupIndex || void 0),
      (t.groupBy = t.groupBy || "path"),
      (t.objectGrouping = t.objectGrouping || !1),
      (t.includeTagsInfo = t.includeTagsInfo || !1),
      (e = e || trans.getSaveData()),
      ((e = JSON.parse(JSON.stringify(e))).project = e.project || {}),
      (e.project.files = e.project.files || {}),
      (t.options = t.options || {}),
      (t.filterTag = t.filterTag || t.options.filterTag || []),
      (t.filterTagMode = t.filterTagMode || t.options.filterTagMode || ""),
      (t.wordWrapByTags =
        t.wordWrapByTags ||
        t.options.wordWrapByTags ||
        e.project.options.wordWrapByTags),
      (t.useSelectedFiles ??= !0),
      (t.disableEvent ||= !1),
      (t.collectUntranslated ||= !1);
    var n = t.contextSeparator || "\n",
      r = [];
    if (t.useSelectedFiles)
      for (
        var o = $(".fileList .data-selector .fileCheckbox:checked"), a = 0;
        a < o.length;
        a++
      )
        r.push(o.eq(a).attr("value"));
    if (((t.files = t.files || r || []), "id" == t.groupBy))
      for (var i in e.project.files)
        e.project.files[i] && (e.project.files[i].id = i);
    var s,
      l = {},
      c = { filterTag: t.filterTag, filterTagMode: t.filterTagMode };
    for (s in (empty(t.wordWrapByTags) || (c.wordWrapByTags = t.wordWrapByTags),
    e.project.files)) {
      var d = e.project.files[s];
      if (
        ((d.data = d.data || [[]]),
        (d.tags = d.tags || []),
        !(0 < t.files.length && 0 == t.files.includes(s)))
      ) {
        l[d[t.groupBy]] = l[d[t.groupBy]] || {
          info: { groupLevel: d.groupLevel },
          translationPair: {},
        };
        for (var g = 0; g < d.data.length; g++)
          if (0 != Boolean(d.data[g]) && 0 != Boolean(d.data[g][t.keyCol])) {
            var f = d.tags[g] || [];
            if ("" !== t.filterTagMode) {
              var u = t.filterTag.filter((e) => f.includes(e));
              if ("whitelist" == t.filterTagMode) {
                if (0 == u.length) continue;
              } else if (0 < u.length) continue;
            }
            try {
              var p,
                h,
                m = (d.data[g][t.keyCol] = d.data[g][t.keyCol] || ""),
                y = trans.getTranslationFromRow(d.data[g], t.keyCol),
                v = ui.translationByContext.generateContextTranslation(g, s, m);
              t.collectUntranslated
                ? (0 < v.length &&
                    (l[d[t.groupBy]].translationPair = Object.assign(
                      l[d[t.groupBy]].translationPair,
                      v.translation
                    )),
                  t.objectGrouping
                    ? d[t.groupIndex]
                      ? ((l[d[t.groupBy]].translationPair[d[t.groupIndex]] =
                          l[d[t.groupBy]].translationPair[d[t.groupIndex]] ||
                          {}),
                        (l[d[t.groupBy]].translationPair[d[t.groupIndex]][m] =
                          trans.wordWrapText(y, f, t.wordWrapByTags) || ""))
                      : (l[d[t.groupBy]].translationPair[m] =
                          trans.wordWrapText(y, f, t.wordWrapByTags) || "")
                    : ((p = d[t.groupIndex] ? d[t.groupIndex] + n + m : m),
                      (l[d[t.groupBy]].translationPair[p] =
                        trans.wordWrapText(y, f, t.wordWrapByTags) || "")))
                : (0 == Boolean(y) && 0 == v.length) ||
                  (0 < v.length &&
                    (l[d[t.groupBy]].translationPair = Object.assign(
                      l[d[t.groupBy]].translationPair,
                      v.translation
                    )),
                  t.objectGrouping
                    ? d[t.groupIndex]
                      ? ((l[d[t.groupBy]].translationPair[d[t.groupIndex]] =
                          l[d[t.groupBy]].translationPair[d[t.groupIndex]] ||
                          {}),
                        !1 !== Boolean(y) &&
                          (l[d[t.groupBy]].translationPair[d[t.groupIndex]][m] =
                            trans.wordWrapText(y, f, t.wordWrapByTags)))
                      : !1 !== Boolean(y) &&
                        (l[d[t.groupBy]].translationPair[m] =
                          trans.wordWrapText(y, f, t.wordWrapByTags))
                    : ((h = d[t.groupIndex] ? d[t.groupIndex] + n + m : m),
                      !1 !== Boolean(y) &&
                        (l[d[t.groupBy]].translationPair[h] =
                          trans.wordWrapText(y, f, t.wordWrapByTags))));
            } catch (e) {
              throw (
                (console.log(
                  "Error when processing",
                  s,
                  "row",
                  g,
                  d.data[g][t.keyCol]
                ),
                e)
              );
            }
          }
      }
    }
    return (
      t.disableEvent ||
        this.trigger("onGenerateTranslationData", {
          info: c,
          translationData: l,
        }),
      { info: c, translationData: l }
    );
  }),
  (Trans.prototype.buildContextFromParameter = function (e) {
    return (
      e["VALUE ID"] + "/" + consts.eventCode[trans.gameEngine][e["EVENT CODE"]]
    );
  }),
  (Trans.prototype.getStagingPath = function (e) {
    try {
      return (e ||= this), nwPath.resolve(e?.project?.cache?.cachePath);
    } catch (e) {}
  }),
  (Trans.prototype.getStagingDataPath = function (e) {
    var t = engines.current().getProperty("stagingDataPath") || "data";
    return nwPath.join(this.getStagingPath(e), t);
  }),
  (Trans.prototype.updateStagingInfo = async function (e) {
    e ||= this;
    var t = nwPath.join(this.getStagingPath(e) || "", "gameInfo.json"),
      n = (console.log("Staging info:", t), {});
    return (
      ((n = (await common.isFileAsync(t))
        ? JSON.parse(await common.fileGetContents(t))
        : n).title = e.project.gameTitle),
      (n.engine = e.project.gameEngine),
      await common.filePutContents(t, JSON.stringify(n, void 0, 2), "UTF8", !1),
      n
    );
  }),
  (Trans.prototype.getStagingFile = function (e) {
    if (
      (e = "string" == typeof e ? this.getObjectById(e) : e) &&
      "object" == typeof e &&
      e.path
    )
      return nwPath.join(this.getStagingDataPath(), e.path);
  }),
  (Trans.prototype.insertCell = function (e, n) {
    if (
      ((n = n || null),
      common.batchArrayInsert(trans.data, e, n),
      void 0 === trans.project)
    )
      return trans.alert(t("Please open or create a new project first!"));
    for (var r in trans.project.files)
      r != trans.getSelectedId() &&
        common.batchArrayInsert(trans.project.files[r].data, e, n);
  }),
  (Trans.prototype.copyCol = function (e, t, n, r) {
    if (
      (console.log("Copying column"),
      console.log(arguments),
      void 0 === (n = n || trans.project))
    )
      return console.log("project is undefined");
    if (void 0 === n.files) return console.log("project.files are undefined");
    for (var o in n.files)
      if (0 == Array.isArray(n.files[o].data))
        console.log("no data for files " + o);
      else
        for (var a in n.files[o].data)
          n.files[o].data[a][t] = n.files[o].data[a][e];
  }),
  (Trans.prototype.gridIsModified = function (e) {
    return void 0 === e
      ? this.unsavedChange
      : this.project
      ? (this.unsavedChange !== e &&
          this.trigger("documentModifiedStateChange", e),
        (this.unsavedChange = e),
        (e = this.getSelectedId()),
        0 != Boolean(this.project.files) &&
          !!this.project.files[e] &&
          ((this.project.files[e].cacheResetOnChange = {}), this.unsavedChange))
      : void (this.unsavedChange = !1);
  }),
  (Trans.prototype.walkToAllFile = function () {
    console.log($(".fileList .selected"));
    for (
      var e = $(".fileList li").index($(".fileList .selected")), t = 0;
      t < $(".fileList li").length;
      t++
    )
      $(".fileList li").eq(t).trigger("click");
    $(".fileList li").eq(e).trigger("click");
  }),
  (Trans.prototype.moveColumn = async function (e, t) {
    if (
      (console.log("trans.moveColumn"),
      console.log(arguments),
      void 0 === trans.project)
    )
      return !1;
    if (
      (t > Math.min.apply(null, e) && (console.log("move to rigth"), (t -= 1)),
      e[0] == t)
    )
      return !1;
    for (var n in (t < Math.max.apply(null, e) && console.log("move to left"),
    ui.showBusyOverlay(),
    trans.project.files))
      for (var r = 0; r < trans.project.files[n].data.length; r++)
        (trans.project.files[n].data[r] = common.arrayMoveBatch(
          trans.project.files[n].data[r],
          e,
          t
        )),
          this.cellInfo.moveCell(n, r, e, t);
    return (
      (trans.colHeaders = common.arrayMoveBatch(trans.colHeaders, e, t)),
      (trans.column = common.arrayMoveBatch(trans.column, e, t)),
      await common.wait(250),
      trans.grid.destroy(),
      trans.initTable(),
      ui.hideBusyOverlay(),
      trans.renderGridInfo(),
      trans.gridIsModified(!0),
      trans
    );
  }),
  (Trans.prototype.dataPadding = function () {
    if (void 0 === trans.data) return !1;
    for (var e in (console.log("Trans data : ", trans.data), trans.data)) {
      var t;
      0 == Array.isArray(trans.data[e]) && (trans.data[e] = []),
        trans.data[e].length >= trans.colHeaders.length ||
          (t = trans.colHeaders.length - trans.data[e].length) < 0 ||
          (console.log("trans.data[i] : ", trans.data[e]),
          console.log("trans.data : ", trans.data[e].length),
          console.log("dif length : ", t),
          (t = Array(t).fill(null)),
          (trans.data[e] = trans.data[e].concat(t)));
    }
    if (void 0 === trans.project) return !1;
    for (var n in trans.project.files)
      for (var r in trans.project.files[n].data) {
        var o;
        trans.project.files[n].data[r].length >= trans.colHeaders.length ||
          ((o =
            trans.colHeaders.length - trans.project.files[n].data[r].length),
          (o = Array(o).fill(null)),
          (trans.project.files[n].data[r] =
            trans.project.files[n].data[r].concat(o)));
      }
    return trans.refreshGrid(), trans;
  }),
  (Trans.prototype.generateHeader = function (t, n) {
    n = n || "";
    var e,
      r = 0;
    for (e in (t = t || this).project.files) {
      var o = t.project.files[e].data || [];
      for (let e = 0; e < o.length; e++)
        0 != Array.isArray(o[e]) && o[e].length > r && (r = o[e].length);
    }
    for (let e = t.colHeaders.length - 1; e < r; e++)
      t.colHeaders.push(n + String.fromCharCode(65 + e)), t.columns.push({});
    return t.colHeaders;
  }),
  (Trans.prototype.sanitize = function (e) {
    if (
      ((e = e || this),
      console.log("running trans.sanitize"),
      void 0 === e.project)
    )
      return !1;
    if (void 0 === e.project.files) return !1;
    for (var t in e.project.files) {
      var n = e.project.files[t].data,
        r = e.project.files[t].context || [],
        o = e.project.files[t].tags || [],
        a = e.project.files[t].parameters || [],
        i = {},
        s = [],
        l = [],
        c = [],
        d = [];
      if (((this.colHeaders = this.colHeaders || []), 0 == Array.isArray(n)))
        e.project.files[t].data = [
          JSON.parse(JSON.stringify(this.colHeaders)).fill(null),
        ];
      else if (0 == n.length)
        e.project.files[t].data = [
          JSON.parse(JSON.stringify(this.colHeaders)).fill(null),
        ];
      else {
        for (var g, n = n || [], f = 0; f < n.length; f++)
          "string" != typeof n[f][0] ||
            n[f][0].length < 1 ||
            (void 0 === i[n[f][0]] &&
              (s.push(n[f]),
              (g = s.length - 1),
              r[f] && (l[g] = r[f]),
              o[f] && (c[g] = o[f]),
              a[f] && (d[g] = a[f]),
              (i[n[f][0]] = !0)));
        (e.project.files[t].data = s),
          (e.project.files[t].context = l),
          (e.project.files[t].tags = c),
          (e.project.files[t].parameters = d);
      }
    }
    return (e.project.isDuplicatesRemoved = !0), e;
  }),
  (Trans.prototype.removeDuplicates = function () {
    console.log("running trans.removeDuplicates");
    for (var e = {}, t = [], n = 0; n < trans.data.length; n++)
      void 0 === e[trans.data[n][0]] &&
        (t.push(trans.data[n]), (e[trans.data[n]] = !0));
    return (trans.data = t), trans.data;
  }),
  (Trans.prototype.isKeyExistOn = function (e, t) {
    return (
      void 0 === t && (t = trans.getSelectedId()),
      "number" == typeof trans.findIdByIndex(e, t)
    );
  }),
  (Trans.prototype.isKeyExist = function (e) {
    return "number" == typeof trans.findIdByIndex(e);
  }),
  (Trans.prototype.setTags = function (e, t, n, r) {
    return (
      (r = r || {}),
      0 == Array.isArray(n) && (n = [n]),
      void 0 !== this.project &&
        void 0 !== this.project.files[e] &&
        "number" == typeof t &&
        (void 0 === this.project.files[e].tags &&
          (this.project.files[e].tags = []),
        1 == Boolean(r.append)
          ? ((this.project.files[e].tags[t] =
              this.project.files[e].tags[t] || []),
            this.project.files[e].tags[t].push.apply(
              this.project.files[e].tags[t],
              n
            ),
            (this.project.files[e].tags[t] = this.project.files[e].tags[
              t
            ].filter((e, t, n) => n.indexOf(e) === t)))
          : (this.project.files[e].tags[t] = n),
        this.project.files[e].tags[t])
    );
  }),
  (Trans.prototype.removeTags = function (e, t, n, r) {
    if (
      (console.log("removeTags", arguments),
      (e = e || this.getSelectedId()),
      0 == Array.isArray(n) && (n = [n]),
      void 0 === this.project)
    )
      return !1;
    if (void 0 === this.project.files[e]) return !1;
    if ("number" != typeof t) return !1;
    void 0 === this.project.files[e].tags && (this.project.files[e].tags = []);
    let o = this.project.files[e].tags?.[t];
    return (
      console.log("Current tags", o),
      0 == Array.isArray(o)
        ? []
        : ((o = o.filter((e) => !n.includes(e))),
          (this.project.files[e].tags[t] = o),
          this.project.files[e].tags[t])
    );
  }),
  (Trans.prototype.clearTags = function (t, n, e) {
    if (((t = t || this.getSelectedId()), void 0 === this.project)) return !1;
    if (void 0 === this.project.files[t]) return !1;
    if ("number" == typeof n)
      return (
        (this.project.files[t].tags[n] = []), this.project.files[t].tags[n]
      );
    for (let e = 0; e < n.length; e++) {
      var r = n[e].start || n[e].from,
        o = n[e].end || n[e].to;
      if (void 0 !== r.row && void 0 !== o.row) {
        this.project.files[t].tags = this.project.files[t].tags || [];
        for (var a = r.row; a <= o.row; a++) this.project.files[t].tags[a] = [];
      }
    }
    return this.project.files[t].tags[a];
  }),
  (Trans.prototype.resetTags = function (e, t) {
    return (
      (e = e || this.getSelectedId()),
      void 0 !== this.project &&
        void 0 !== this.project.files[e] &&
        (this.project.files[e].tags = [])
    );
  }),
  (Trans.prototype.appendTags = function (e, t, n, r) {
    return this.setTags(e, t, n, { append: !0, noRefresh: !0 });
  }),
  (Trans.prototype.setTagForSelectedRow = function (t, n, r, o) {
    if (
      (void 0 === (o = o || {}).append && (o.append = !0),
      (r = r || this.getSelectedId()),
      0 == Boolean(n))
    )
      return !1;
    if (0 == Array.isArray(n)) return !1;
    for (let e = 0; e < n.length; e++) {
      var a = n[e].start || n[e].from,
        i = n[e].end || n[e].to;
      if (void 0 !== a.row && void 0 !== i.row)
        for (var s = a.row; s <= i.row; s++) this.setTags(r, s, t, o);
    }
    return this.grid.render(), !0;
  }),
  (Trans.prototype.removeTagForSelectedRow = function (t, n, r, o) {
    if (
      (console.log("removeTagForSelectedRow", arguments),
      ((o = o || {}).append = o.append || !0),
      (r = r || this.getSelectedId()),
      0 == Boolean(n))
    )
      return !1;
    if (0 == Array.isArray(n)) return !1;
    for (let e = 0; e < n.length; e++) {
      var a = n[e].start || n[e].from,
        i = n[e].end || n[e].to;
      if (void 0 !== a.row && void 0 !== i.row)
        for (var s = a.row; s <= i.row; s++) this.removeTags(r, s, t, o);
    }
    return this.grid.render(), !0;
  }),
  (Trans.prototype.hasTags = function (e, t, n) {
    if (!e) return !1;
    if (void 0 === t) return !1;
    n = n || this.getSelectedId();
    var r = this.getObjectById(n);
    if (!r) return !1;
    if (!r.tags) return !1;
    if (!Array.isArray(r.tags[t])) return !1;
    Array.isArray(e) || (e = [e]);
    try {
      for (var o in e) if (r.tags[t].includes(e[o])) return !0;
      return !1;
    } catch (e) {
      return !1;
    }
  }),
  (Trans.prototype.alert = async function (t, r) {
    return (
      (r = r || 3e3),
      $("#appInfo").attr("title", t),
      new Promise((n, e) => {
        $("#appInfo").tooltip({
          content: function () {
            return t;
          },
          show: { effect: "slideDown", duration: 200 },
          hide: { effect: "fade", delay: 250 },
          position: { my: "left top", at: "left bottom", of: "#table" },
          open: function (e, t) {
            setTimeout(function () {
              $("#appInfo").tooltip("close"),
                $("#appInfo").attr("title", ""),
                n();
            }, r);
          },
        }),
          $("#appInfo").tooltip("open");
      })
    );
  }),
  (Trans.prototype.refreshGrid = function (e) {
    if (
      (((e = e || {}).rebuild = e.rebuild || !1),
      trans.getSelectedId() &&
        (trans.data = trans?.project?.files[trans.getSelectedId()].data),
      trans.data || (trans.data = [[null]]),
      1 == trans.data.length &&
        (0 == Array.isArray(trans.data[0]) && (trans.data = [[null]]),
        0 == Boolean(trans.data[0][0])) &&
        (trans.data = [[null]]),
      0 == trans.data.length && (trans.data = [[null]]),
      trans.getSelectedId() &&
        (trans.project.files[trans.getSelectedId()].data = trans.data),
      "function" == typeof e.onDone &&
        trans.grid.addHookOnce("afterRender", function () {
          e.onDone.call(trans.grid);
        }),
      e.rebuild)
    )
      return trans.grid.destroy(), trans.initTable(), !0;
    trans.grid.updateSettings({
      data: trans.data,
      colHeaders: trans.colHeaders,
      columns: trans.columns,
    }),
      trans.loadComments();
  }),
  (Trans.prototype.editNoteAtCell = function (e) {
    if (void 0 === e)
      try {
        e = trans.grid.getSelectedRange()[0].highlight;
      } catch (e) {
        return console.log(e), !1;
      }
    trans.grid.getPlugin("comments").showAtCell(e.row, e.col),
      $(".htCommentTextArea").trigger("click"),
      $(".htCommentTextArea").focus();
  }),
  (Trans.prototype.removeNoteAtSelected = function (e) {
    if (
      (console.log("trans.removeNoteAtSelected"),
      void 0 === e && (e = trans.grid.getSelectedRange()),
      0 == Boolean(e))
    )
      return console.log("no selection were made"), !1;
    console.log(e);
    for (
      var t = Math.min(e[0].from.row, e[0].to.row),
        n = Math.max(e[0].from.row, e[0].to.row),
        r = Math.min(e[0].from.col, e[0].to.col),
        o = Math.max(e[0].from.col, e[0].to.col),
        a = trans.grid.getPlugin("comments"),
        i = t;
      i <= n;
      i++
    )
      for (var s = r; s <= o; s++) a.removeCommentAtCell(i, s);
  }),
  (Trans.prototype.drawGridTranslatorMenu = function () {
    if (!this.translatorContextMenuIsInitialized) {
      if (
        (console.log("Initializing translator context menu"),
        (TranslatorEngine.translators = TranslatorEngine.translators || {}),
        empty(TranslatorEngine.translators))
      )
        return;
      for (var n in ((this.gridContextMenu.translateUsing.submenu.items = []),
      TranslatorEngine.translators))
        (() => {
          var e = n,
            t = TranslatorEngine.translators[n];
          this.gridContextMenu.translateUsing.submenu.items.push({
            key: "translateUsing:" + e,
            name: t.name,
            callback: () => {
              this.translateSelection(void 0, { translatorEngine: t });
            },
            hidden: () =>
              !!this.grid.isColumnHeaderSelected() ||
              !!this.grid.isRowHeaderSelected() ||
              void 0,
          });
        })();
      this.translatorContextMenuIsInitialized = !0;
    }
    return this.gridContextMenu;
  }),
  (Trans.prototype.getGridContextMenu = function () {
    return this.drawGridTranslatorMenu(), this.gridContextMenu;
  }),
  (Trans.prototype.updateGridContextMenu = function (e) {
    console.log("updateGridContextMenu", e), this.gridContextMenuIsModified;
  }),
  (Trans.prototype.modifyGridContextMenu = function (e) {
    this.gridContextMenuIsModified = !0;
  }),
  (Trans.prototype.calculateTableHeights = async function (e = this.data) {
    console.log("Calculating table height");
    return e?.length
      ? e.length < 1e3
        ? 23 * t(e) + 46
        : (e = await new (require("www/js/CommonWorker.js").Handler)(
            "./www/js/trans.worker.js",
            {
              command: "calculateHeights",
              data: e,
              options: { logTarget: "ui" },
            }
          ).getResult())?.result
        ? 23 * e.result + 46
        : 23
      : 23;
    function t(r) {
      let e = 0;
      for (let n = 0; n < r.length; n++)
        if (r[n]?.length) {
          let t = 1;
          for (let e = 0; e < r[n].length; e++) {
            var o;
            r[n][e] && (o = r[n][e].split("\n").length) > t && (t = o);
          }
          e += t;
        }
      return e < r.length ? r.length : e;
    }
  }),
  (Trans.prototype.initTable = function (e) {
    var n = document.getElementById("table");
    if (0 == Boolean(n)) return !1;
    Handsontable.dom.addEvent(n, "blur", function (e) {
      console.log("event", e);
    }),
      (Handsontable.debugLevel = common.debugLevel()),
      (this.grid = new Handsontable(n, {
        data: trans.data,
        comments: !0,
        rowHeaders: !0,
        colHeaders: trans.colHeaders,
        columns: trans.columns,
        formulas: !1,
        search: !0,
        outsideClickDeselects: !1,
        viewportColumnRenderingOffset: 15,
        maxCols: Trans.maxCols,
        autoRowSize: !1,
        minSpareRows: 1,
        filters: !1,
        dropdownMenu: !1,
        autoWrapRow: !0,
        manualColumnMove: !0,
        manualColumnResize: !0,
        copyPaste: { columnsLimit: 15, rowsLimit: 1e5 },
        beforeChange: function (e, n) {
          if (
            (console.log("beforeChange", arguments),
            console.log(e),
            console.log(n),
            void 0 === trans.selectedData)
          )
            return console.warn("unknown selected data");
          for (var r = 0; r < e.length; r++) {
            if (0 == e[r][1] && e[r][0] < trans.grid.getData().length - 1)
              return (
                console.log(JSON.stringify(e, void 0, 2)),
                trans.alert(t("You should not edit key value")),
                !1
              );
            if (0 == e[r][1]) {
              if (0 == Boolean(e[r][3])) return !1;
              if (trans.isKeyExistOn(e[r][3]))
                return (
                  trans.alert(
                    t("Ilegal value") +
                      " <b>'" +
                      e[r][3] +
                      "'</b> " +
                      t("That value already exist!")
                  ),
                  !1
                );
              "number" == typeof trans.findIdByIndex(e[r][2]) &&
                delete trans.indexIds[e[r][2]],
                (trans.selectedData.indexIds[e[r][3]] = e[r][0]);
            }
          }
        },
        afterChange: function (e, t) {
          if ((trans.gridIsModified(!0), null == e)) return !0;
          if (!trans.getSelectedId()) return !0;
          var n,
            r,
            o = !1,
            a = trans.project.files[trans.getSelectedId()].progress;
          for (n in e)
            0 != Array.isArray(e[n]) &&
              trans.data[e[n][0]][0] &&
              ((e[n][2] = e[n][2] || ""),
              (e[n][3] = e[n][3] || ""),
              e[n][0] == trans.lastSelectedCell[0] &&
                e[n][1] == trans.lastSelectedCell[1] &&
                trans.textEditorSetValue(e[n][3]),
              0 < e[n][2].length && 0 == e[n][3].length
                ? 0 != trans.countFilledCol(e[n][0]) ||
                  a.translated <= 0 ||
                  (a.translated--,
                  0 < a.length
                    ? (a.percent = (a.translated / a.length) * 100)
                    : (a.percent = 0),
                  (o = !0))
                : 0 == e[n][2].length &&
                  0 < e[n][3].length &&
                  (1 != trans.countFilledCol(e[n][0]) ||
                    a.translated >= a.length ||
                    (a.translated++,
                    0 < a.length
                      ? (a.percent = (a.translated / a.length) * 100)
                      : (a.percent = 0),
                    (o = !0))));
          o &&
            (((r = {})[trans.getSelectedId()] = a),
            trans.evalTranslationProgress(trans.getSelectedId(), r)),
            trans.trigger("afterCellChange", [e, t]);
        },
        beforeContextMenuShow: (e) => {
          trans.updateGridContextMenu(e);
        },
        contextMenu: { items: trans.getGridContextMenu() },
        cells: function (e, t, n) {
          var r = {};
          if (0 == t) {
            if (void 0 === trans.data[e]) return r;
            null !== trans.data[e][t] &&
              "" !== trans.data[e][t] &&
              (r.readOnly = !0);
          }
          return r;
        },
        afterSelection: function (e, t, n, r, o, a) {
          console.log("do after selection", arguments),
            trans.trigger("beforeProcessSelection", arguments),
            trans.doAfterSelection(e, t, n, r);
        },
        beforeInit: function () {
          console.log("running before init");
        },
        afterInit: function () {
          trans.buildIndex();
        },
        beforeColumnMove: function (e, t) {
          return (
            console.log("beforeColumnMove"),
            0 != t && 1 != e.includes(0) && (trans.moveColumn(e, t), !0)
          );
        },
        afterColumnMove: function (e, t) {
          return console.log("afterColumnMove"), 0 != t && 1 != e.includes(0);
        },
        afterSetCellMeta: function (t, n, e, r) {
          if ("comment" == e) {
            e = trans.getSelectedObject();
            if (e)
              if (null == r)
                try {
                  delete e.comments[t][n];
                } catch (e) {
                  console.log(
                    "unable to delete comment.\nData row:" +
                      t +
                      ", col:" +
                      n +
                      " is not exist on trans.project.files[trans.getCurrentID].comments!"
                  );
                }
              else
                (e.comments = e.comments || []),
                  (e.comments[t] = e.comments[t] || []),
                  (e.comments[t][n] = r.value);
            return !0;
          }
        },
        afterRender: function (e) {
          if (1 == e) return !0;
          $("#currentCellText").is(":focus") &&
            !1 !== (e = ui.getCurrentEditedCellElm()) &&
            ($("#table .currentCell").removeClass("currentCell"),
            e.addClass("currentCell"));
        },
        afterRenderer: function (e, t, n, r, o, a) {
          e.setAttribute("data-coord", t + "-" + n),
            0 < n &&
              trans.getOption("gridInfo")?.isRuleActive &&
              (trans.getOption("gridInfo")?.viewOrganicCellMarker &&
              trans.isOrganicCell(t, n)
                ? $(e).addClass("organic")
                : trans.getOption("gridInfo")?.viewTrail &&
                  trans.isVisitedCell(t, n) &&
                  $(e).addClass("viewed")),
            0 < n ||
              (t >= trans.data.length - 1 && $(e).addClass("newKeyField"));
        },
        afterGetColHeader: function (e, t) {
          -1 == e && $(t).attr("data-role", "tablecorner");
        },
        afterGetRowHeader: function (t, n) {
          var e,
            r = $(n),
            n = $(n).closest("tr"),
            o = r.find(".rowInfo");
          if (
            (o.length ||
              ((e = r.find(">div")),
              (o = $('<span class="rowInfo"></span>').appendTo(e))),
            void 0 !== trans.selectedData &&
              0 != Array.isArray(trans.selectedData.tags) &&
              0 != Array.isArray(trans.selectedData.tags[t]) &&
              1 != n.hasClass("tagRendered"))
          ) {
            var a = [];
            let e = 0;
            for (var i = 0; i < trans.selectedData.tags[t].length; i++) {
              var s = trans.selectedData.tags[t][i];
              void 0 !== consts.tagColor[s] &&
                ((e += consts.tagStripThickness),
                a.push("inset " + e + "px 0px 0px 0px " + consts.tagColor[s])),
                r.addClass("tag-" + trans.selectedData.tags[t][i]);
            }
            0 != a.length && r.css("box-shadow", a.join(",")),
              n.addClass("hasTag"),
              n.addClass("tagRendered");
          }
          ui.translationByContext &&
            trans.rowHasMultipleContext(t, trans.selectedData) &&
            (r.addClass("hasMC"),
            ui.translationByContext.rowHasContextTranslation(
              t,
              trans.selectedData
            )) &&
            r.addClass("hasTC"),
            (e = trans.getRowInfoText(t)) ? o.text(e) : o.text("");
        },
        afterCreateRow: function (e, t, n) {
          var r = trans.getSelectedId();
          if (0 == Boolean(r)) return !1;
          trans.evalTranslationProgress([r]);
        },
        beforePaste: function (e, t) {},
        afterScrollVertically() {
          this.skipScrollEvent ||
            (this._scrollTimer && clearTimeout(this._scrollTimer),
            (this._scrollTimer = setTimeout(async () => {
              $("#table .wtHolder>*:eq(0)").height() -
                $("#table .wtHolder").scrollTop() -
                $("#table .wtHolder").height() <=
                0 &&
                ($(".newKeyField").visible() ||
                  (this.render(),
                  (this.skipScrollEvent = !0),
                  trans.grid.scrollViewportTo(ui.getFirstFullyVisibleRow()),
                  await common.wait(50),
                  (this.skipScrollEvent = !1)));
            }, 200)));
        },
      })),
      Handsontable.dom.addEvent($("#quickFind")[0], "input", function (e) {
        var t = trans.grid.getPlugin("search").query(this.value);
        console.log(t), trans.grid.render();
      }),
      (trans.grid.autoRowSize = trans.grid.getPlugin("autoRowSize")),
      (trans.grid.isFixedHeight = !0),
      (trans.grid.view.wt.ignoreAdjustElementSize = !1);
    async function r(e = trans.getSelectedId()) {
      !trans.grid.getSettings().autoRowSize ||
        trans.grid.isFixedHeight ||
        trans.data?.length < 1e3 ||
        (console.log("Saving cache rowheights for ", e),
        trans?.localStorage &&
          (console.log(
            "Calculated row heights length ",
            trans.grid.autoRowSize.heights.length,
            "Current row length",
            trans.data.length
          ),
          trans.grid &&
            trans.localStorage.set(
              trans.getSelectedId() + "?rowHeights",
              trans.grid.autoRowSize.heights
            ),
          trans.localStorage.set(trans.getSelectedId() + "?hiderDimension", {
            width: trans.grid.view.wt.wtTable.hider.style.width,
            height: trans.grid.view.wt.wtTable.hider.style.height,
          })));
    }
    (trans.grid.loadRowHeightsCache = async function (e) {
      if (
        trans.grid.getSettings().autoRowSize &&
        !trans.grid.isFixedHeight &&
        !(trans.data?.length < 1e3) &&
        (console.log("start counting rows height on colRange", e),
        trans?.localStorage)
      ) {
        e = await trans.localStorage.get(trans.getSelectedId() + "?rowHeights");
        if ((console.log("Cache row height is", e), e?.length))
          return (
            (trans.grid.autoRowSize.heights = await trans.localStorage.get(
              trans.getSelectedId() + "?rowHeights"
            )),
            (trans.grid.autoRowSize.inProgress = !1),
            (trans.grid.cachedDimension = await trans.localStorage.get(
              trans.getSelectedId() + "?hiderDimension"
            )),
            !0
          );
      }
    }),
      (trans.grid.onCalculateAllRowsHeightStart = async function () {
        ui.tableCornerShowLoading(
          "Counting total rows height. The grid may jumpy while in counting process."
        );
      }),
      (trans.grid.onCalculateAllRowsHeightEnd = async function () {
        trans.data?.length < 1e3 || (ui.tableCornerHideLoading(), r());
      }),
      trans.off("beforeSelectFile"),
      trans.on("beforeSelectFile", function (e, t) {
        console.log("%cbeforeSelectFile", "color:pink", t),
          t?.[0] && t[0] != t[1] && r(t[0]);
      }),
      (trans.grid.setFixedTableHeightByData = async function (e = []) {
        var t, n;
        trans.grid.isFixedHeight &&
          e?.length &&
          ((n = 22 * e.length * 10),
          (t = trans.getSelectedId()),
          trans.grid.setFixedTableHeight(n),
          (n = await trans.calculateTableHeights(e)),
          trans.getSelectedId() === t) &&
          (console.log("Setting actual height", n),
          trans.grid.setFixedTableHeight(n));
      }),
      (trans.grid.setFixedTableHeight = function (e) {
        if (trans.grid.isFixedHeight)
          return (
            "string" == typeof e && e.includes("px")
              ? ((trans.grid.view.wt.wtTable.hider.style.height = e),
                (trans.grid.view.wt.ignoreAdjustElementSize = !0))
              : "number" == typeof e
              ? ((trans.grid.view.wt.wtTable.hider.style.height = e + "px"),
                (trans.grid.view.wt.ignoreAdjustElementSize = !0))
              : "boolean" == typeof e &&
                !1 === e &&
                (trans.grid.view.wt.ignoreAdjustElementSize = !1),
            trans.grid.view.wt.wtTable.hider.style.height
          );
      }),
      (trans.grid.addHeight = function (e = 0) {
        var t = parseInt(trans.grid.view.wt.wtTable.hider.style.height);
        return (
          (trans.grid.view.wt.wtTable.hider.style.height = t + e + "px"),
          trans.grid.view.wt.wtTable.hider.style.height
        );
      }),
      (trans.grid.getTableHeight = function () {
        return trans.grid.view.wt.wtTable.hider.style.height;
      }),
      (trans.grid.isColumnHeaderSelected = function () {
        return Boolean($(".htCore thead th.ht__active_highlight").length);
      }),
      (trans.grid.isRowHeaderSelected = function () {
        return Boolean($(".htCore tr th.ht__active_highlight").length);
      }),
      (trans.grid.insertColumnRight = function (e, n) {
        var r;
        trans.columns.length >= Trans.maxCols
          ? alert(
              t(
                "The maximum number of columns for this project has been reached, so you cannot add any more."
              )
            )
          : ((e = e || "New Col"),
            (n = n || trans.grid.getSelected()[0][1]),
            (r = trans.columns.length),
            trans.columns.push({}),
            common.arrayExchange(trans.columns, r, n + 1),
            common.arrayInsert(trans.colHeaders, n + 1, e),
            console.log(trans.columns),
            trans.insertCell(n + 1, null),
            trans.grid.updateSettings({ colHeaders: trans.colHeaders }));
      }),
      (trans.grid.setColWidth = function (e, t) {
        trans.columns[e] && ((trans.columns[e].width = t), trans.refreshGrid());
      });
  }),
  (Trans.prototype.findAndInsertWithIndexes = function (t = "", n, r, e, o) {
    (r = r || 1),
      (t ||= ""),
      ((o = o || {}).overwrite = o.overwrite || !1),
      (o.files = o.files || []),
      (o.keyColumn = o.keyColumn || this.keyColumn || 0),
      (o.insensitive = o.insensitive || !1),
      (o.lineByLine = o.lineByLine || !1),
      (e = e || this._tempIndexes),
      void 0 === o.ignoreNewLine && (o.ignoreNewLine = !0),
      0 == o.files.length && (o.files = this.getAllFiles());
    var a = { keyword: t, count: 0, executionTime: 0, files: {} },
      i = this.getFromIndexes(t, e, o.customFilter);
    if (
      (!i &&
        t.includes("\r") &&
        ((t = t.replaceAll("\r", "")),
        (a.find = t),
        (i = this.getFromIndexes(t, e, o.customFilter))),
      i)
    )
      for (let e = 0; e < i.length; e++) {
        var s = i[e],
          l = s.file,
          c = s.row;
        if (
          (o.ignoreNewLine &&
            !1 !== Boolean(this.project.files[l].lineBreak) &&
            (t = common.replaceNewLine(t, this.project.files[l].lineBreak)),
          "number" == typeof c)
        ) {
          var d = this.getData(l)[c];
          if (d) {
            if ("blacklist" == o.filterTagMode) {
              if (this.hasTags(o.filterTag, c, l)) continue;
            } else if (
              "whitelist" == o.filterTagMode &&
              !this.hasTags(o.filterTag, c, l)
            )
              continue;
            if (o.lineByLine) {
              var g = (d[r] || "").replaceAll("\r", "").split("\n");
              if (0 == o.overwrite && 1 == Boolean(g[s.line])) continue;
              (g[s.line] = n), (d[r] = g.join("\n"));
            } else {
              if (0 == o.overwrite && 1 == Boolean(d[r])) continue;
              d[r] = n;
            }
            (a.files[l] = a.files[l] || []),
              a.files[l].push({
                fullString: d[r],
                row: c,
                col: r,
                type: "cell",
                lineIndex: null,
              }),
              a.count++;
          }
        }
      }
    return a;
  }),
  (Trans.prototype.findAndInsert = function (t, n, r, o) {
    (r = r || 1),
      ((o = o || {}).overwrite = o.overwrite || !1),
      (o.files = o.files || []),
      (o.keyColumn = o.keyColumn || this.keyColumn || 0),
      (o.insensitive = o.insensitive || !1),
      void 0 === o.ignoreNewLine && (o.ignoreNewLine = !0),
      0 == o.files.length && (o.files = this.getAllFiles());
    var a = { keyword: t, count: 0, executionTime: 0, files: {} };
    for (let e = 0; e < o.files.length; e++) {
      var i,
        s = o.files[e];
      if (
        (o.ignoreNewLine &&
          !1 !== Boolean(this.project.files[s].lineBreak) &&
          (t = common.replaceNewLine(t, this.project.files[s].lineBreak)),
        "number" ==
          typeof (i = o.insensitive
            ? this.getRowIdByTextInsensitive(t, s)
            : this.findIdByIndex(t, s)))
      ) {
        var l = this.getData(s)[i];
        if (l) {
          if ("blacklist" == o.filterTagMode) {
            if (this.hasTags(o.filterTag, i, s)) continue;
          } else if (
            "whitelist" == o.filterTagMode &&
            !this.hasTags(o.filterTag, i, s)
          )
            continue;
          (0 == o.overwrite && 1 == Boolean(l[r])) ||
            ((l[r] = n),
            (a.files[s] = a.files[s] || []),
            a.files[s].push({
              fullString: l[r],
              row: i,
              col: r,
              type: "cell",
              lineIndex: null,
            }),
            a.count++);
        }
      }
    }
    return a;
  }),
  (Trans.prototype.findAndInsertLine = function (t, n, r, o) {
    if (
      ((r = r || 1),
      ((o = o || {}).overwrite = o.overwrite || !1),
      (o.files = o.files || []),
      (o.keyColumn = o.keyColumn || 0),
      (o.newLine = o.newLine || void 0),
      (o.stripCarriageReturn = o.stripCarriageReturn || !1),
      o.stripCarriageReturn && (t = common.stripCarriageReturn(t)),
      0 == o.files.length)
    )
      if (void 0 !== trans.allFiles) o.files = trans.allFiles;
      else {
        for (var a in trans.project.files) o.files.push(a);
        trans.allFiles = o.files;
      }
    for (var e = 0; e < o.files.length; e++)
      for (
        var i,
          a = o.files[e],
          s = trans.project.files[a].data,
          l = o.newLine || trans.project.files[a].lineBreak || "\n",
          c = 0;
        c < s.length;
        c++
      ) {
        let e;
        if (s[c][o.keyColumn]) {
          if ("blacklist" == o.filterTagMode) {
            if (this.hasTags(o.filterTag, c, a)) continue;
          } else if (
            "whitelist" == o.filterTagMode &&
            !this.hasTags(o.filterTag, c, a)
          )
            continue;
          (s[c][o.keyColumn] = s[c][o.keyColumn] || ""),
            0 !=
              (e = (
                o.stripCarriageReturn
                  ? s[c][o.keyColumn].replaceAll("\r", "")
                  : s[c][o.keyColumn]
              ).split("\n")).includes(t) &&
              ((s[c][r] = s[c][r] || ""),
              (i = s[c][r].replaceAll("\r", "").split("\n")),
              (i = common.searchReplaceArray(e, i, t, n, {
                overwrite: o.overwrite,
              })),
              (s[c][r] = i.join(l)));
        }
      }
  }),
  (Trans.prototype.findAndInsertByContext = function (t, n, r, o) {
    (r = r || 1),
      ((o = o || {}).overwrite = o.overwrite || !1),
      (o.files = o.files || []),
      (o.ignoreNewLine = o.ignoreNewLine || !1),
      0 == o.files.length && (o.files = this.getAllFiles());
    for (let e = 0; e < o.files.length; e++) {
      var a = o.files[e],
        i = this.getObjectById(a);
      if (0 != Boolean(i) && 0 != Boolean(i.context))
        for (var s = 0; s < i.context.length; s++) {
          var l = i.context[s];
          if (
            0 != Array.isArray(l) &&
            !(l.length < 1) &&
            0 != Array.isArray(i.data[s])
          )
            for (var c = 0; c < l.length; c++)
              t !== l[c] ||
                (0 == o.overwrite && 1 == Boolean(i.data[s][r])) ||
                (i.data[s][r] = n);
        }
    }
  }),
  (Trans.prototype.translateTextByLine = function (e, t, n) {
    if ("string" != typeof e) return e;
    if (e.length < 1) return e;
    for (
      var r = [], o = e.replace(/(\r\n)/gm, "\n").split("\n"), a = 0;
      a < o.length;
      a++
    ) {
      var i = o[a];
      t[i] ? r.push(t[i]) : r.push("");
    }
    return r.join("\n");
  }),
  (Trans.prototype.translateFromArray = function (e, t, n) {
    if (
      (console.log("insert trans.translateFromArray", arguments),
      (t = t || 1),
      ((n = n || {}).sourceColumn = n.sourceColumn || "auto"),
      (n.overwrite = n.overwrite || !1),
      (n.files = n.files || []),
      (n.sourceKeyColumn = n.sourceKeyColumn || 0),
      (n.keyColumn = n.keyColumn || 0),
      (n.newLine = n.newLine || void 0),
      (n.stripCarriageReturn = n.stripCarriageReturn || !1),
      (n.ignoreNewLine = !0),
      0 == (e = e || []).length)
    )
      return !1;
    n.indexes ||
      (console.log("%cbuilding index", "color:salmon;"),
      0 == n.files?.length && (n.files = this.getAllFiles()),
      (n.indexes = this.buildIndexes(n.files, !1))),
      console.log("options.indexes", n.indexes);
    for (var r = 0; r < e.length; r++) {
      var o,
        a = e[r];
      0 != Boolean(a[n.sourceKeyColumn]) &&
        ((o = a[n.sourceKeyColumn]),
        (a =
          "auto" == n.sourceColumn
            ? trans.getTranslationFromRow(a, n.sourceKeyColumn)
            : a[n.sourceColumn]),
        trans.findAndInsertWithIndexes(o, a, t, n.indexes, {
          overwrite: n.overwrite,
          files: n.files,
        }));
    }
  }),
  (Trans.prototype.abortTranslation = function () {
    (trans.translator = trans.translator || []),
      void 0 !== trans.translationTimer && clearTimeout(trans.translationTimer);
    for (var e = 0; e < trans.translator.length; e++) {
      var t = trans.translator[e],
        t = trans.getTranslatorEngine(t);
      if (t) {
        if ("function" == typeof t.abort)
          try {
            t.abort();
          } catch (e) {
            ui.log("Failed to abort with message", e.toString());
          }
        (t.job = t.job || {}), (t.job.wordcache = {}), (t.job.batch = []);
      }
    }
    ui.hideLoading(), trans.refreshGrid(), trans.evalTranslationProgress();
  }),
  (Trans.prototype.translateStringByPair = function (e, t, n) {
    if (((n = n || !1), "string" == typeof e && "object" == typeof t))
      for (var r in t) e = e.replaces(r, t[r], n);
    return e;
  }),
  (Trans.prototype.translateFromTrans = function (e, r = [], t = this) {
    if (!e) return "";
    "string" == typeof r && (r = [r]);
    var t = t?.project?.files || {},
      n =
        (r?.length || (r = this.getAllFiles(t)),
        (e) => {
          for (var t in r) {
            var t = r[t],
              n = this.getIndexByKey(t, e);
            if (void 0 !== n) {
              t = this.getData(t);
              if (empty(t[n])) return "";
              t = this.getTranslationFromRow(t[n]);
              if (t) return t;
            }
          }
        });
    if (Array.isArray(e)) {
      var o,
        a = [];
      for (o in e) a[o] = n(e[o]) || "";
      return a;
    }
    return n(e);
  }),
  (Trans.prototype.getReference = function (e, t = "Common Reference") {
    return (
      (e &&
        void 0 !== (e = this.getIndexByKey(t, e)) &&
        ((t = this.getData(t)), !empty(t[e])) &&
        this.getTranslationFromRow(t[e])) ||
      ""
    );
  }),
  (Trans.prototype.translateByReference = function (
    e,
    t,
    n = "Common Reference"
  ) {
    if (((t = t || !1), trans.project.files[n])) {
      var r;
      if (
        ((trans.project.files[n].cacheResetOnChange =
          trans.project.files[n].cacheResetOnChange || {}),
        !1 !== Boolean(trans.project.files[n].cacheResetOnChange.transPair)
          ? (r = trans.project.files[n].cacheResetOnChange.transPair)
          : ((r = trans.generateTranslationPair(trans.project.files[n].data)),
            (trans.project.files[n].cacheResetOnChange.transPair = r)),
        "string" == typeof e)
      )
        return (o = trans.translateStringByPair(e, r, t));
      if (Array.isArray(e)) {
        for (var o = [], a = 0; a < e.length; a++)
          o[a] = trans.translateStringByPair(e[a], r, t);
        return o;
      }
    }
    return e;
  }),
  (Trans.prototype.rowHasTranslation = function (
    t = [],
    n = this.keyColumn,
    r
  ) {
    if (t && t.length)
      if (((n = this.keyColumn || 0), null == r)) {
        for (let e = 0; e < t.length; e++) if (e != n && t[e]) return !0;
      } else {
        Array.isArray(r) || (r = [r]);
        for (let e = 0; e < r.length; e++) if (r[e] != n && t[r[e]]) return !0;
      }
    return !1;
  }),
  (Trans.prototype.translateAll = async function (e, t) {
    var n = this.getTranslatorEngine(e);
    return (
      this.buildIndex("Common Reference", !0),
      "function" == n.translateAll
        ? n.translateAll(t)
        : "v2" == n.translatorType
        ? this.batchTranslate(n, t)
        : void ("rowByRow" == n.mode
            ? trans.translateAllByRows(e, t)
            : trans.translateAllByLines(e, t))
    );
  }),
  (Trans.prototype.batchTranslate = async function (e, n) {
    let r = new BatchTranslate(e, n);
    await ui.log.start({
      buttons: [
        {
          text: "Abort",
          onClick: function (e) {
            confirm(t("Are you sure want to abort this process?")) && r.abort();
          },
        },
        {
          text: "Pause",
          onClick: function (e) {
            alert(t("Process paused!\nPress OK to continue!"));
          },
        },
      ],
    }),
      await r.translateAll(),
      await ui.log.end(),
      await this.onBatchTranslationDone(n);
  }),
  (Trans.prototype.translateAllByRows = async function (e, i) {
    console.log("Running trans.translateAll", i),
      ui.loadingProgress(0, "Running trans.translateAll");
    var s = this.getTranslatorEngine(e);
    if (void 0 === trans.project)
      return trans.alert(t("Unable to process, project not found"));
    if (void 0 === trans.project.files)
      return trans.alert(t("Unable to process, data not found"));
    if (void 0 === s) return trans.alert(t("Translation engine not found"));
    if (s.isDisabled)
      return trans.alert(t("Translation engine ") + e + t(" is disabled!"));
    trans.getSelectedId() ||
      trans.selectFile($(".fileList .data-selector").eq(0)),
      ((i = i || {}).onFinished = i.onFinished || function () {}),
      (i.keyColumn = i.keyColumn || 0),
      (i.translateOther = i.translateOther || !1),
      (i.ignoreTranslated = i.ignoreTranslated || !1),
      (i.overwrite = i.overwrite || !1),
      (i.saveOnEachBatch = i.saveOnEachBatch || !1),
      (s.job = s.job || {}),
      (s.job.wordcache = {}),
      (s.job.batch = []),
      (s.batchDelay = s.batchDelay || trans.config.batchDelay);
    var n,
      r = trans.config.maxRequestLength,
      o =
        (s.maxRequestLength < r && (r = s.maxRequestLength),
        ui.showLoading({
          buttons: [
            {
              text: "Abort",
              onClick: function (e) {
                confirm(t("Are you sure want to abort this process?")) &&
                  trans.abortTranslation();
              },
            },
            {
              text: "Pause",
              onClick: function (e) {
                alert(t("Process paused!\nPress OK to continue!"));
              },
            },
          ],
        }),
        ui.log("Start batch translation in Row by Row mode, with options:", i),
        ui.log("Translator is: " + e),
        console.log("Current maximum request length : " + r),
        console.log("Start collecting data!"),
        ui.loadingProgress(0, "Start collecting data!"),
        0),
      a = 0,
      l = {},
      c = trans.getCheckedFiles();
    for (n in (ui.loadingProgress(void 0, t("Selected files :") + c.join(", ")),
    (c = 0 == c.length ? this.getAllFiles() : c))) {
      var d = c[n];
      ui.loadingProgress(void 0, t("Collecting data from :") + d);
      try {
        var g = trans.project.files[d].data;
      } catch (e) {
        console.warn("Can not access", d, "in trans.project.files");
        continue;
      }
      void 0 === s.job.batch[o] && (s.job.batch[o] = []);
      for (var f = 0; f < g.length; f++)
        if (g[f][0]) {
          var u = g[f][i.keyColumn],
            p = str_ireplace(
              $DV.config.lineSeparator,
              s.lineSubstitute,
              s.escapeCharacter(u)
            );
          if (u) {
            if ("blacklist" == i.filterTagMode) {
              if (this.hasTags(i.filterTag, f, d)) continue;
            } else if (
              "whitelist" == i.filterTagMode &&
              !this.hasTags(i.filterTag, f, d)
            )
              continue;
            (i.ignoreTranslated && this.rowHasTranslation(g[f], i.keyColumn)) ||
              (0 == i.overwrite && g[f][s.targetColumn]
                ? console.log(
                    "Ignored because overwite options",
                    i.overwrite,
                    g[f][s.targetColumn]
                  )
                : 0 != u.trim().length &&
                  ((l[u] = g[f][0]),
                  p.length > r
                    ? (console.log(
                        "current sentence is bigger than maxRequestLength!"
                      ),
                      o++,
                      (s.job.batch[o] = s.job.batch[o] || []),
                      s.job.batch[o].push(u),
                      o++,
                      (a = 0))
                    : p.length + a > r
                    ? (o++,
                      (s.job.batch[o] = s.job.batch[o] || []),
                      s.job.batch[o].push(u),
                      (a = 0))
                    : void 0 === s.job.wordcache[u] &&
                      ((s.job.wordcache[u] = !0),
                      (s.job.batch[o] = s.job.batch[o] || []),
                      s.job.batch[o].push(u),
                      (a += p.length))));
          }
        }
    }
    await ui.log("Generating indexes");
    var h = this.buildIndexes(c),
      m =
        ((s.job.batchLength = s.job.batch.length),
        console.log("current batch:", s.job.batch),
        ui.loadingProgress(0, "Data collection is done!"),
        console.log("Data collection is done!"),
        console.log("We have " + s.job.batch.length + " batch totals!"),
        console.log("=========================================="),
        console.log("Begin translating using " + e + "!"),
        async function () {
          if (void 0 === s.job.batch) return "batch job undefined, quiting!";
          if (s.job.batch.length < 1)
            return (
              console.log("Batch job is finished"),
              trans.refreshGrid(),
              trans.evalTranslationProgress(),
              "function" == typeof i.onFinished && i.onFinished.call(this),
              ui.loadingProgress(100, t("Translation finished")),
              ui.loadingClearButton(),
              ui.loadingEnd(),
              trans.onBatchTranslationDone(i),
              (trans.translationTimer = void 0),
              "batch job is finished!"
            );
          console.log("running processPart");
          var e,
            a = s.job.batch.pop();
          console.log("current data : "),
            console.log(a),
            (e = s.skipReferencePair ? a : trans.translateByReference(a)),
            s.translate(e, {
              mode: "rowByRow",
              onAfterLoading: async function (e) {
                if ((console.log(e), void 0 !== e.translation)) {
                  console.log("applying translation to table !"),
                    console.log("calculating progress");
                  var n,
                    r = 100 - (s.job.batch.length / s.job.batchLength) * 100,
                    o =
                      (ui.loadingProgress(
                        r,
                        t("applying translation to table!")
                      ),
                      c);
                  for (n in (i.translateOther && (o = trans.getAllFiles()),
                  trans.trigger("batchTranslationResult", {
                    original: a,
                    translation: e.translation,
                    translator: s,
                  }),
                  e.translation))
                    trans.findAndInsertWithIndexes(
                      l[a[n]],
                      e.translation[n],
                      s.targetColumn,
                      h,
                      {
                        filterTag: i.filterTag || [],
                        filterTagMode: i.filterTagMode,
                        keyColumn: i.keyColumn,
                        overwrite: i.overwrite,
                        files: o,
                      }
                    );
                  i.saveOnEachBatch &&
                    (ui.log("Saving your project"), await trans.save()),
                    ui.loadingProgress(
                      void 0,
                      s.job.batchLength -
                        s.job.batch.length +
                        "/" +
                        s.job.batchLength +
                        " batch done, waiting " +
                        s.batchDelay +
                        " ms..."
                    ),
                    (trans.translationTimer = setTimeout(function () {
                      m();
                    }, s.batchDelay));
                }
              },
              onError: function (e, n, r) {
                console.log("ERROR on transling data");
                var o = 100 - (s.job.batch.length / s.job.batchLength) * 100;
                ui.loadingProgress(
                  o,
                  t("Error when translating data!") +
                    "\r\n" +
                    t("\tHTTP Status : ") +
                    e.status +
                    "\r\n" +
                    t("\tError Type : ") +
                    r +
                    "\r\n" +
                    t(
                      "You are probably temporarily banned by your translation service!\r\nPlease use online translation service in moderation\r\nThis usualy fixed by itself within a day or two.\r\n"
                    )
                ),
                  ui.loadingProgress(
                    void 0,
                    s.job.batchLength -
                      s.job.batch.length +
                      "/" +
                      s.job.batchLength +
                      t(" batch done, ") +
                      t("waiting ") +
                      s.batchDelay +
                      t(" ms...")
                  ),
                  (trans.translationTimer = setTimeout(function () {
                    m();
                  }, s.batchDelay));
              },
            });
        });
    m();
  }),
  (Trans.prototype.translateAllByLines = async function (e, i) {
    console.log("Running trans.translateAllByLines", arguments),
      ui.loadingProgress(0, t("Running trans.translateAll"));
    var s = this.getTranslatorEngine(e);
    if (void 0 === trans.project)
      return trans.alert(t("Unable to process, project not found"));
    if (void 0 === trans.project.files)
      return trans.alert(t("Unable to process, data not found"));
    if (void 0 === s) return trans.alert(t("Translation engine not found"));
    if (s.isDisabled)
      return trans.alert(t("Translation engine ") + e + t(" is disabled!"));
    trans.getSelectedId() ||
      trans.selectFile($(".fileList .data-selector").eq(0)),
      ((i = i || {}).onFinished = i.onFinished || function () {}),
      (i.keyColumn = i.keyColumn || 0),
      (i.translateOther = i.translateOther || !1),
      (i.ignoreTranslated = i.ignoreTranslated || !1),
      (i.overwrite = i.overwrite || !1),
      (i.saveOnEachBatch = i.saveOnEachBatch || !1);
    var n,
      r = i.ignoreTranslated ? "untranslated" : "both",
      o =
        ((s.job = s.job || {}),
        (s.job.wordcache = {}),
        (s.job.batch = []),
        (s.batchDelay = s.batchDelay || trans.config.batchDelay),
        trans.config.maxRequestLength),
      a =
        (s.maxRequestLength < o && (o = s.maxRequestLength),
        ui.showLoading({
          buttons: [
            {
              text: "Abort",
              onClick: function (e) {
                confirm(t("Are you sure want to abort this process?")) &&
                  trans.abortTranslation();
              },
            },
            {
              text: "Pause",
              onClick: function (e) {
                alert(t("Process paused!\nPress OK to continue!"));
              },
            },
          ],
        }),
        ui.log(
          "Start batch translation in Line by Line mode, with options:",
          i
        ),
        ui.log("Translator is: " + e),
        console.log("Current maximum request length : " + o),
        console.log("Start collecting data!"),
        ui.loadingProgress(0, t("Start collecting data!")),
        0),
      l = 0,
      c = trans.getCheckedFiles(),
      d =
        (ui.loadingProgress(void 0, t("Selected files :") + c.join(", ")),
        trans.generateTranslationTableLine(trans.project, {
          files: c,
          mode: "lineByLine",
          fetch: r,
          keyColumn: i.keyColumn,
          filterLanguage: this.getSl(),
          filterTag: i.filterTag || [],
          filterTagMode: i.filterTagMode,
          ignoreTranslated: i.ignoreTranslated,
          targetColumn: s.targetColumn,
          overwrite: i.overwrite,
          ignoreWhitespace: s.ignoreWhitespace,
          collectAddress: !0,
        })),
      g = d.pairs;
    for (n in (console.log("Fetch mode : ", r),
    console.log("Translatable : ", g),
    (l = a = 0),
    g)) {
      s.job.batch[a] = s.job.batch[a] || [];
      var f = n,
        u = str_ireplace(
          $DV.config.lineSeparator,
          s.lineSubstitute,
          s.escapeCharacter(f)
        );
      0 != Boolean(f) &&
        "string" == typeof f &&
        0 != f.trim().length &&
        (u.length > o
          ? (console.log("current sentence is bigger than maxRequestLength!"),
            a++,
            (s.job.batch[a] = s.job.batch[a] || []),
            s.job.batch[a].push(f),
            a++,
            (l = 0))
          : u.length + l > o
          ? (a++,
            (s.job.batch[a] = s.job.batch[a] || []),
            s.job.batch[a].push(f),
            (l = 0))
          : ((s.job.batch[a] = s.job.batch[a] || []),
            s.job.batch[a].push(f),
            (l += u.length)));
    }
    (s.job.batchLength = s.job.batch.length),
      ui.loadingProgress(0, t("Data collection is done!")),
      console.log("Data collection is done!"),
      console.log("We have " + s.job.batch.length + " batch totals!"),
      console.log("=========================================="),
      console.log("Begin translating using " + e + "!"),
      await ui.log("Generating indexes");
    var r = this.buildIndexes(c, !0),
      p =
        (console.log("indexes:", r),
        async function () {
          var e, n;
          return void 0 === s.job.batch
            ? "batch job undefined, quiting!"
            : s.job.batch.length < 1
            ? (console.log("Batch job is finished"),
              (e = []),
              0 == i.translateOther && (e = trans.getCheckedFiles()),
              trans.fillEmptyLine(e, [], s.targetColumn, i.keyColumn, {
                lineFilter: function (e) {
                  return !common.isInLanguage(e, trans.getSl());
                },
                fromKeyOnly: i.ignoreTranslated,
                filterTag: i.filterTag || [],
                filterTagMode: i.filterTagMode,
                overwrite: i.overwrite,
              }),
              trans.refreshGrid(),
              trans.evalTranslationProgress(),
              "function" == typeof i.onFinished && i.onFinished.call(this),
              ui.loadingProgress(100, t("Translation finished")),
              ui.loadingClearButton(),
              ui.loadingEnd(),
              trans.onBatchTranslationDone(i),
              (trans.translationTimer = void 0),
              "batch job is finished!")
            : ((n = async function () {
                console.log("running processPart");
                var e,
                  o = [],
                  a =
                    (0 == i.translateOther && (o = trans.getCheckedFiles()),
                    trans.fillEmptyLine(o, [], s.targetColumn, i.keyColumn, {
                      lineFilter: function (e) {
                        return !common.isInLanguage(e, trans.getSl());
                      },
                      fromKeyOnly: i.ignoreTranslated,
                      filterTag: i.filterTag || [],
                      filterTagMode: i.filterTagMode,
                      overwrite: i.overwrite,
                    }),
                    s.job.batch.pop());
                console.log("current data : "),
                  console.log(a),
                  (e = s.skipReferencePair ? a : trans.translateByReference(a)),
                  s.translate(e, {
                    onAfterLoading: async function (e) {
                      if (
                        (console.log("onAfterLoading translation result:", e),
                        void 0 !== e.translation)
                      ) {
                        console.log("applying translation to table !");
                        var n,
                          r =
                            100 -
                            (s.job.batch.length / s.job.batchLength) * 100;
                        for (n in (ui.loadingProgress(
                          r,
                          t("applying translation to table!")
                        ),
                        trans.trigger("batchTranslationResult", {
                          original: a,
                          translation: e.translation,
                          translator: s,
                        }),
                        e.translation))
                          trans.findAndInsertWithIndexes(
                            a[n],
                            e.translation[n],
                            s.targetColumn,
                            d.addresses,
                            {
                              files: o,
                              keyColumn: i.keyColumn,
                              stripCarriageReturn: !0,
                              filterTag: i.filterTag || [],
                              filterTagMode: i.filterTagMode,
                              overwrite: i.overwrite,
                              lineByLine: !0,
                            }
                          );
                        i.saveOnEachBatch &&
                          (ui.log("Saving your project"), await trans.save()),
                          ui.loadingProgress(
                            void 0,
                            s.job.batchLength -
                              s.job.batch.length +
                              "/" +
                              s.job.batchLength +
                              " batch done!"
                          ),
                          p();
                      }
                    },
                    onError: function (e, n, r) {
                      console.log("ERROR on transling data");
                      var o =
                        100 - (s.job.batch.length / s.job.batchLength) * 100;
                      ui.loadingProgress(
                        o,
                        t("Error when translating data!") +
                          "\r\n" +
                          t("\tHTTP Status : ") +
                          e.status +
                          "\r\n" +
                          t("\tError Type : ") +
                          r +
                          "\r\n" +
                          t(
                            "You are probably temporarily banned by your translation service!\r\nPlease use online translation service in moderation\r\nThis usualy fixed by itself within a day or two.\r\n"
                          )
                      ),
                        ui.loadingProgress(
                          void 0,
                          s.job.batchLength -
                            s.job.batch.length +
                            "/" +
                            s.job.batchLength +
                            " batch done!"
                        ),
                        p();
                    },
                  });
              }),
              void (s.job.batchLength == s.job.batch.length
                ? n()
                : (ui.loadingProgress(
                    void 0,
                    "Waiting " + s.batchDelay + " ms..."
                  ),
                  (trans.translationTimer = setTimeout(function () {
                    n();
                  }, s.batchDelay)))));
        });
    p();
  }),
  (Trans.prototype.onBatchTranslationDone = function (e) {
    var t;
    e.playSoundOnComplete &&
      (t = new Audio("/www/audio/done.mp3")).addEventListener(
        "canplay",
        (e) => {
          t.play();
        }
      );
  }),
  (Trans.prototype.getTranslatorEngine = function (e) {
    return (
      TranslatorEngine.translators[e] ||
      (this[e] instanceof TranslatorEngine
        ? this[e]
        : e instanceof TranslatorEngine
        ? e
        : void console.warn(e, " is not a translator engine"))
    );
  }),
  (Trans.prototype.getActiveTranslatorEngine = function () {
    return this.getTranslatorEngine(this.getActiveTranslator());
  }),
  (Trans.prototype.setActiveTranslator = function (e) {
    (e = "string" == typeof e ? this.getTranslatorEngine(e) : e)?.id &&
      this.setOption("translator", e.id);
  }),
  (Trans.prototype.translateSelection = async function (n, r = {}) {
    this.buildIndex("Common Reference", !0);
    var o = this;
    if (void 0 === (n = n || o.grid.getSelectedRange() || [[]]))
      return alert(t("nothing is selected")), !1;
    if (void 0 === o.translator || o.translator.length < 1)
      return alert(t("no translator loaded")), !1;
    var a = r.translatorEngine || this.getActiveTranslatorEngine();
    if (
      ((r.mode ||= a.mode),
      (r.ignoreWhitespace ||= a.ignoreWhitespace),
      console.log("translating selection ", r.mode),
      1 == a.isDisabled)
    )
      return alert(a.id + " is disabled!");
    ui.tableCornerShowLoading();
    for (
      var i = [],
        e = o.grid.getData(),
        s = common.gridSelectedCells() || [],
        l = [],
        c = 0;
      c < s.length;
      c++
    )
      s[c].col != this.keyColumn && l.push(e[s[c].row][this.keyColumn]);
    if (l) {
      console.log("Text pool", l);
      var d,
        g,
        f = o.generateTranslationTableFromStrings(l, a, r);
      for (d in (console.log(
        "Translation table:",
        JSON.stringify(f, void 0, 2)
      ),
      (f = (await this.processWith("translationTableFilter", f, a)) || f),
      console.warn("Filtered translationTable", JSON.stringify(f, void 0, 2)),
      f.include))
        i.push(d);
      console.log(i),
        console.log(s),
        s.length < 1
          ? ui.tableCornerHideLoading()
          : ((g = a.skipReferencePair ? i : o.translateByReference(i)),
            console.log("Translate using : ", a.id),
            a.translate(g, {
              onAfterLoading: async function (e) {
                console.log("Translation result:"),
                  console.log(e),
                  console.log("text pool :"),
                  console.log(i),
                  console.log("rowpool:"),
                  console.log(s),
                  console.log("translation result : "),
                  o.trigger("batchTranslationResult", {
                    original: i,
                    translation: e.translation,
                    translator: a,
                  });
                e = o.generateTranslationTableFromResult(
                  i,
                  e.translation,
                  f.exclude
                );
                console.log("translation table : "),
                  console.log(e),
                  o.applyTransTableToSelectedCell(e, n, void 0, r),
                  ui.tableCornerHideLoading(),
                  o.grid.render(),
                  o.evalTranslationProgress(),
                  o.textEditorSetValue(o.getTextFromLastSelected());
              },
            }));
    }
  }),
  (Trans.prototype.translateSelectionByRow = async function (e, t = {}) {
    return (t.mode = "rowByRow"), this.translateSelection(e, (t = {}));
  }),
  (Trans.prototype.translateSelectionByLine = async function (e, t = {}) {
    return (t.mode = "lineByLine"), this.translateSelection(e, (t = {}));
  }),
  (Trans.prototype.translateSelectionAsOneLine = async function (o, e = {}) {
    if (
      (console.log("Merge to one line then translate"),
      void 0 === (o = o || trans.grid.getSelectedRange() || [[]]))
    )
      return alert(t("nothing is selected")), !1;
    if (void 0 === trans.translator || trans.translator.length < 1)
      return alert(t("no translator loaded")), !1;
    for (
      var e = e.translatorEngine || this.getActiveTranslatorEngine(),
        a = this.getSelectedOriginalTexts(o),
        n = this.getSelectedOriginalTextsAsOneLine(o),
        r = common.gridSelectedRows(o),
        i = {},
        s = 0;
      s < r.length;
      s++
    )
      i[r[s]] = s;
    console.log("Row index:", i);
    var l = this.getData();
    console.log("Original text:", a),
      ui.tableCornerShowLoading(),
      (n = e.skipReferencePair ? n : trans.translateByReference(n)),
      console.log("Translating", n),
      e.translate(n, {
        mode: "rowByRow",
        onAfterLoading: (e) => {
          if (void 0 !== e.translation) {
            console.log("result translation:", e.translation);
            for (
              var t = common.cloneFormatting(a, e.translation.join(" ")),
                n =
                  (console.log("Formatted result:", t),
                  console.log(
                    "Write back the translated result according to the row"
                  ),
                  common.gridSelectedCells(o)),
                r = 0;
              r < n.length;
              r++
            )
              n[r].col != this.keyColumn &&
                (l[n[r].row][n[r].col] = t[i[n[r].row]]);
          }
          ui.tableCornerHideLoading(),
            trans.grid.render(),
            trans.evalTranslationProgress(),
            trans.textEditorSetValue(trans.getTextFromLastSelected());
        },
      });
  }),
  (Trans.prototype.translateSelectionIntoDef = function (e) {
    if (
      (console.log("translating selection into default coloumn"),
      void 0 === (e = e || trans.grid.getSelected() || [[]]))
    )
      return alert(t("nothing is selected")), !1;
    if (void 0 === trans.translator || trans.translator.length < 1)
      return alert(t("no translator loaded")), !1;
    for (var n = [], r = trans.grid.getData(), o = [], a = 0; a < e.length; a++)
      for (var i = e[a][0]; i <= e[a][2]; i++) o.push(i), n.push(r[i][0]);
    var s = n;
    console.log(s), console.log(o);
    for (var l = 0; l < trans.translator.length; l++) {
      console.log(l);
      var c = trans.translator[l],
        d = this.getTranslatorEngine(c);
      1 != d.isDisabled &&
        (void 0 === d.targetColumn
          ? console.warn(
              "Skipping. Reason : TargetColumn property is not set for engine ",
              c
            )
          : ((c = trans.translateByReference(s)),
            d.translate(c, {
              onAfterLoading: function (e) {
                if (void 0 !== e.translation)
                  for (var t in e.translation)
                    trans.data[o[t]][d.targetColumn] = e.translation[t];
                trans.grid.render(), trans.evalTranslationProgress();
              },
            })));
    }
  }),
  (Trans.prototype.applyTransTableToSelectedCell = function (n, e, r, o) {
    if (
      ((r = r || trans.data),
      (e = e || trans.grid.getSelected() || [[]]),
      ((o = o || {}).indexKey = o.indexKey || 0),
      void 0 === e)
    )
      return alert(t("nothing is selected")), !1;
    var a = common.gridSelectedCells(e) || [];
    if ("rowByRow" == o.mode)
      for (let e = 0; e < a.length; e++) {
        var i = a[e].col,
          s = a[e].row;
        i != this.keyColumn &&
          0 != Array.isArray(r[s]) &&
          (r[s][i] = n[r[s][o.indexKey]]);
      }
    else
      for (let e = 0; e < a.length; e++) {
        var l = a[e].col,
          c = a[e].row;
        l != this.keyColumn &&
          0 != Array.isArray(r[c]) &&
          (r[c][l] = this.translateTextByLine(r[c][o.indexKey], n));
      }
  }),
  (Trans.prototype.translateSelectedRow = function (e, n) {
    return (
      void 0 !== e &&
      0 != trans.config.autoTranslate &&
      !!(e = trans.data[e][(n = n || 0)]) &&
      ((n = $("#translationPane")[0].contentWindow),
      (n = ui.windows.translator ? ui.windows.translator : n).translator
        ? (n.translator.translateAll(e), !0)
        : t("unable to load translator window"))
    );
  }),
  (Trans.prototype.getTranslationByIndex = function (e) {
    var t;
    return (
      void 0 !== e &&
      ((t = $("#translationPane")[0].contentWindow),
      (t = ui.windows.translator ? ui.windows.translator : t)
        .$(".mainPane .portlet")
        .eq(e)
        .find(".portlet-content")
        .text())
    );
  }),
  (Trans.prototype.importTranslation = async function (r, f) {
    if ((console.log("importTranslation", arguments), void 0 === r))
      return trans.alert(t("Reference path cannot empty!"));
    ((f = f || {}).targetColumn = f.targetColumn || 1),
      (f.overwrite = f.overwrite || !1),
      (f.files = f.files || []),
      (f.destination = f.destination || []),
      (f.compareMode = f.compareMode || 0),
      (f.ignoreLangCheck = !0),
      (f.destinationMode = f.destinationMode || "selected"),
      (f.caseInsensitive ||= !1),
      console.log("refPath & options : "),
      console.log(arguments),
      trans.getSelectedId() ||
        trans.selectFile($(".panel-left .fileList .data-selector").eq(0));
    var u = void 0,
      o =
        (f.caseInsensitive &&
          (u = function (e) {
            return e.toLowerCase().replaceAll("\r", "");
          }),
        async (n) => {
          console.log("Applying translation"),
            ui.loadingProgress(30, t("Collecting translation refference")),
            await ui.log("Collecting translation refference");
          var r,
            o = {};
          if ("lineByLine" == f.compareMode) {
            o = trans.generateTranslationTableLine(n.project.files, f);
            let e;
            "selected" == f.destinationMode && (e = this.getCheckedFiles()),
              (r = this.buildIndexes(e, !0, { customFilter: u }));
          } else if ("rowByRow" == f.compareMode) {
            o = trans.generateTranslationTable(n.project.files, f);
            let e;
            "selected" == f.destinationMode && (e = this.getCheckedFiles()),
              (r = this.buildIndexes(e, !1, { customFilter: u }));
          } else
            "contextTrans" == f.compareMode &&
              (o = trans.generateContextTranslationPair(n.project.files, f));
          n = trans.mergeReference(n);
          var e = Object.keys(o).length,
            a =
              (await ui.log(`Processing ${e} reference(s)`),
              ui.loadingProgress(50, t("Applying translation!")),
              0),
            i = 50;
          if ("lineByLine" == f.compareMode)
            for (var s in o) {
              var l = s;
              f.caseInsensitive && (s = u(s)),
                trans.findAndInsertWithIndexes(s, o[l], f.targetColumn, r, {
                  overwrite: f.overwrite,
                  files: f.destination,
                  lineByLine: !0,
                  customFilter: u,
                }),
                ui.loadingProgress(50 + (a / e) * 50),
                a++;
            }
          else if ("rowByRow" == f.compareMode)
            for (var c in (console.log("Row by Row translation"), o)) {
              var d = c,
                c =
                  (f.caseInsensitive && (c = u(c)),
                  trans.findAndInsertWithIndexes(c, o[d], f.targetColumn, r, {
                    overwrite: f.overwrite,
                    files: f.destination,
                    insensitive: !0,
                    customFilter: u,
                  }),
                  Math.round(50 + (a / e) * 50));
              i < c &&
                (ui.loadingProgress(50 + (a / e) * 50),
                await ui.log(`Handled: ${a}/` + e),
                (i = c)),
                a++;
            }
          else if ("contextTrans" == f.compareMode)
            for (var g in (console.log("Translation by context"), o))
              trans.findAndInsertByContext(g, o[g], f.targetColumn, {
                overwrite: f.overwrite,
                files: f.destination,
              }),
                ui.loadingProgress(50 + (a / e) * 50),
                a++;
          else
            "copyByRow" == f.compareMode &&
              this.copyTranslationToRow(n.project.files, f.targetColumn, f);
          trans.trigger("onAfterImportTranslations", {
            options: f,
            loadedData: n,
            refTranslation: o,
          }),
            await common.wait(20),
            trans.evalTranslationProgress(),
            trans.refreshGrid(),
            ui.loadingProgress(100, "Done!"),
            ui.loadingEnd();
        });
    if (
      (ui.showLoading(),
      ui.loadingProgress(0, t("Importing translation")),
      await common.wait(200),
      "object" == typeof r && void 0 !== r.project)
    )
      return console.log("refPath is an object : "), await o(r), !0;
    console.log("Opening " + r),
      fs.readFile(r, async function (e, n) {
        if (e)
          throw (
            (console.log("error opening file : " + r),
            (n = n.toString()),
            "function" == typeof f.onFailed && f.onFailed.call(trans, n),
            e)
          );
        ui.loadingProgress(20, t("Parsing data")),
          await ui.log("Parsing data"),
          await common.wait(200),
          (n = n.toString());
        e = JSON.parse(n);
        console.log("Result data : "),
          console.log(e),
          o(e),
          console.log("Done!"),
          "function" == typeof f.onSuccess && f.onSuccess.call(trans, e),
          (trans.isOpeningFile = !1);
      });
  }),
  (Trans.prototype.translateAllBySelectedCells = async function (e, t, n) {
    (e = e || this.grid.getSelectedRange() || [[]]),
      (t = t || this.getSelectedId()),
      (n = n || {}),
      ui.showBusyOverlay(),
      await common.wait(100);
    var r,
      o = this.getAllFilesExcept([t]),
      a = this.generateSelectedTranslationTable(e, t, n),
      i = (console.log("Selected transtable", a), this.buildIndexes(o)),
      s = [];
    for (r in a) {
      var l = this.getFromIndexes(r, i);
      if (l)
        for (var c = 0; c < l.length; c++)
          for (
            var d = l[c], g = this.getData(d.file), f = 0;
            f < a[r].length;
            f++
          ) {
            var u = a[r][f],
              p = g[d.row][u.col];
            u.col != this.keyColumn &&
              ((g[d.row][u.col] = u.value),
              s.push({
                file: d.file,
                row: d.row,
                col: u.col,
                oldValue: p,
                newValue: u.value,
              }));
          }
    }
    return ui.hideBusyOverlay(), s;
  }),
  (Trans.prototype.getSelectedTexts = function (e, t) {
    (e = e || this.grid.getSelectedRange() || [[]]),
      (t = t || this.getSelectedId());
    for (
      var n = this.getData(t), r = common.gridSelectedCells(e), o = [], a = 0;
      a < r.length;
      a++
    )
      o.push(n[r[a].row][r[a].col] || "");
    return o;
  }),
  (Trans.prototype.getText = function (e, t, n) {
    return (n ? trans.getObjectById(n) : this.data)?.[e]?.[t];
  }),
  (Trans.prototype.getCellComment = function (e, t, n) {
    let r;
    if ((r = n ? this.getObjectById(n) : this.getSelectedObject()).comments)
      return r.comments?.[e]?.[t];
  }),
  (Trans.prototype.getSelectedOriginalTexts = function (e, t) {
    (e = e || this.grid.getSelectedRange() || [[]]),
      (t = t || this.getSelectedId());
    for (
      var n = this.getData(t), r = common.gridSelectedCells(e), o = [], a = 0;
      a < r.length;
      a++
    )
      o.push(n[r[a].row][this.keyColumn] || "");
    return o;
  }),
  (Trans.prototype.getSelectedTextsAsOneLine = function (e, t) {
    return (this.getSelectedTexts(e, t) || [])
      .join(" ")
      .replaceAll("\r", "")
      .replaceAll("\n", " ");
  }),
  (Trans.prototype.getSelectedOriginalTextsAsOneLine = function (e, t) {
    (e = e || this.grid.getSelectedRange() || [[]]),
      (t = t || this.getSelectedId());
    for (
      var n = this.getData(t), r = common.gridSelectedRows(), o = [], a = 0;
      a < r.length;
      a++
    )
      o.push(n[r[a]][this.keyColumn] || "");
    return o.join(" ");
  }),
  (Trans.prototype.getSelectedId = function () {
    return !!trans.project && trans.project?.selectedId;
  }),
  (Trans.prototype.getSelectedContext = function (t) {
    t = t || trans.lastSelectedCell[0];
    var n = trans.getSelectedObject().context;
    try {
      return n[t];
    } catch (e) {
      return (n[t] = []), n[t];
    }
  }),
  (Trans.prototype.getSelectedParameters = function () {
    var e, t;
    if (trans.lastSelectedCell)
      return (
        (e = trans.lastSelectedCell[0]),
        ((t = trans.getSelectedObject()).parameters = t.parameters || []),
        (t.parameters[e] = t.parameters[e] || []),
        t.parameters[e]
      );
  }),
  (Trans.prototype.getParamatersByRow = function (e, t) {
    return (
      (t = t || this.getSelectedId()),
      "number" == typeof e &&
        !!(t = trans.getObjectById(t))?.parameters &&
        t.parameters[e]
    );
  }),
  (Trans.prototype.setParametersByRow = function (e, t, n) {
    n = n || this.getSelectedId();
    n = this.getObjectById(n);
    (n.parameters = n.parameters || []), (n.parameters[e] = t);
  }),
  (Trans.prototype.getRowInfoText = function (e, t = !1, n = "", r = !1) {
    n = n || this.getSelectedId();
    var o = this.getParamatersByRow(e, n);
    if (!o) return "";
    var a,
      i,
      s = (this.getOption("gridInfo") || {}).referenceName || "Actor Reference";
    if (t) {
      for (var l in ((a = []), o))
        o[l] &&
          "object" == typeof o[l] &&
          (r
            ? o[l].rowInfoText && a.push(o[l].rowInfoText)
            : o[l].rowInfoText &&
              a.push(this.translateByReference(o[l].rowInfoText, !1, s)));
      return [...new Set(a)].join(", ");
    }
    for (i in ((a = ""), o))
      if (o[i] && "object" == typeof o[i]) {
        if (a) return a + "++";
        r
          ? o[i].rowInfoText && (a = o[i].rowInfoText)
          : o[i].rowInfoText &&
            (a = this.translateByReference(o[i].rowInfoText, !1, s));
      }
    return a;
  }),
  (Trans.prototype.setRowInfoText = function (e, t, n) {
    n = n || this.getSelectedId();
    e = this.getParamatersByRow(e, n);
    return !!e && ((e[0] ||= {}), (e[0].rowInfoText = t), !0);
  }),
  (Trans.prototype.getSelectedKeyText = function (e) {
    e = e || trans.lastSelectedCell[0];
    try {
      return trans.getSelectedObject().data[e][trans.keyColumn];
    } catch (e) {}
  }),
  (Trans.prototype.getSelectedObject = function () {
    var e;
    return (
      0 != $(".fileList .selected").length &&
      ((e = trans.getSelectedId()), trans.project.files[e])
    );
  }),
  (Trans.prototype.getObjectById = function (e) {
    if (e)
      try {
        return trans.project?.files?.[e];
      } catch (e) {
        console.warn(e);
      }
  }),
  (Trans.prototype.getCheckedFiles = function () {
    for (
      var e = [],
        t = $(".fileList .data-selector .fileCheckbox:checked"),
        n = 0;
      n < t.length;
      n++
    )
      e.push(t.eq(n).attr("value"));
    return e;
  }),
  (Trans.prototype.getCheckedObjects = function () {
    for (
      var e = {},
        t = $(".fileList .data-selector .fileCheckbox:checked"),
        n = 0;
      n < t.length;
      n++
    ) {
      var r = t.eq(n).attr("value");
      e[r] = this.getObjectById(r);
    }
    return e;
  }),
  (Trans.prototype.getAllFiles = function (e, t) {
    var n = [];
    if (void 0 !== (e = e || trans?.project?.files))
      if ((e?.project?.files && (e = e?.project?.files), t))
        for (var r in e) "*" != e[r]?.dirname && n.push(r);
      else for (var o in e) n.push(o);
    return n;
  }),
  (Trans.prototype.getAllFilesExcept = function (e, t) {
    e = (e = "string" == typeof e ? [e] : e) || [];
    var n,
      r = [];
    for (n in (t = t || trans.project.files)) e.includes(n) || r.push(n);
    return r;
  }),
  (Trans.prototype.getAllCompletedFiles = function (e) {
    var t = [];
    if (void 0 !== (e = e || this.project.files))
      for (var n in e)
        "object" == typeof e[n] &&
          "object" == typeof e[n].progress &&
          100 == e[n].progress.percent &&
          t.push(n);
    return t;
  }),
  (Trans.prototype.getAllIncompletedFiles = function (e) {
    var t = [];
    if (void 0 !== (e = e || this.project.files))
      for (var n in e)
        "object" == typeof e[n] &&
          "object" == typeof e[n].progress &&
          e[n].progress.percent < 100 &&
          t.push(n);
    return t;
  }),
  (Trans.prototype.getAllMarkedAsCompleted = function (e) {
    var t = [];
    if (void 0 !== (e = e || this.project.files))
      for (var n in e)
        "object" == typeof e[n] &&
          "object" == typeof e[n].progress &&
          e[n].isCompleted &&
          t.push(n);
    return t;
  }),
  (Trans.prototype.getAttachmentContent = function (e) {
    if (e && trans.project?.attachments?.[e])
      return trans.project.attachments[e].data;
  }),
  (Trans.prototype.scrollHToCol = function (e) {
    var t = $("#table .ht_master .wtHolder");
    if (!e) return (t[0].scrollLeft = 0);
    for (
      var n = $("#table .ht_master .wtHolder colgroup col"), r = 0, o = 1;
      o < e;
      o++
    )
      r += n.eq(o + 1).outerWidth();
    console.log(r), (t[0].scrollLeft = r);
  }),
  (Trans.prototype.goTo = function (e, t, n) {
    console.log(arguments),
      (n = n || this.getSelectedId()),
      this.grid.deselectCell(),
      n !== this.getSelectedId() &&
        ((n = this.selectFile(n)), $(n)[0].scrollIntoView({ block: "center" })),
      this.grid.selectCell(e, t, e, t),
      this.grid.scrollViewportTo(e, t),
      this.scrollHToCol(t);
  }),
  (Trans.prototype.getLastSelectedCell = function () {
    return this.lastSelectedCell;
  }),
  (Trans.prototype.goToNextUntranslated = function () {
    for (
      var e = this.getLastSelectedCell(),
        t = this.getCurrentData(),
        n = e[0] + 1,
        r = (n = n >= t.length ? 0 : n);
      r < t.length && this.rowHasTranslation(t[r]);
      r++
    );
    return t.length <= r && (r = t.length - 1), this.goTo(r, e[1]);
  }),
  (Trans.prototype.goToPreviousUntranslated = function () {
    var e = this.getLastSelectedCell(),
      t = this.getCurrentData(),
      n = e[0] - 1;
    n <= 0 && (n = t.length - 1), console.log("starting", n);
    for (var r = n; 0 <= r && this.rowHasTranslation(t[r]); r--);
    return console.log("Move to row", r), this.goTo((r = r < 0 ? 0 : r), e[1]);
  }),
  (Trans.prototype.search = function (n, r) {
    var e = require("glob-to-regexp");
    if ((console.log("entering trans.search", arguments), void 0 === n))
      return null;
    if (typeof n.length <= 1) return "Keyword too short!";
    if (void 0 === trans.project) return null;
    if (void 0 === trans.project.files) return null;
    if (
      (((r = r || {}).caseSensitive = r.caseSensitive || !1),
      (r.lineMatch = r.lineMatch || !1),
      (r.isRegexp = r.isRegexp || !1),
      (r.searchLocations = r.searchLocations || []),
      0 == r.searchLocations.length && (r.searchLocations = ["grid"]),
      r.lineMatch && (r.searchInContext = !1),
      0 == Array.isArray(r.files))
    )
      for (var o in ((r.files = []), trans.project.files)) r.files.push(o);
    0 == r.caseSensitive && 0 == r.isRegexp && (n = n.toLowerCase());
    var a = new Date().getTime(),
      i = {
        keyword: n,
        count: 0,
        isRegexp: r.isRegexp,
        executionTime: 0,
        files: {},
      };
    if (r.isRegexp) {
      if (0 == (l = common.evalRegExpStr(n)))
        return (
          alert(
            n +
              t(
                " is not a valid javascript's regexp!\r\nFind out more about Javascipt's Regular Expression at :\r\nhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions"
              )
          ),
          i
        );
    } else if (n.includes("*"))
      try {
        var s = e(n)
            .toString()
            .replace(/\/\^(.*?)\$\//, "$1"),
          l = new RegExp(s, "i");
        console.log("Glob style keyword detected", l);
      } catch (e) {
        console.warn("Error when converting glob pattern to RegExp");
      }
    if (r.lineMatch) {
      for (var c in r.files) {
        var d = r.files[c];
        if (0 != Array.isArray(trans.project.files[d].data)) {
          var g = trans.project.files[d].data;
          for (let t = 0; t < g.length; t++)
            if (0 != g[t].length)
              for (let e = 0; e < g[t].length; e++)
                if ("string" == typeof g[t][e])
                  if (l) {
                    if (l.test(g[t][e])) {
                      var f = common.lineIndexRegExp(g[t][e], l);
                      (i.files[d] = i.files[d] || []),
                        i.files[d].push({
                          fullString: g[t][e],
                          row: t,
                          col: e,
                          type: "cell",
                          lineIndex: f,
                        }),
                        i.count++;
                      break;
                    }
                  } else {
                    if (r.caseSensitive) {
                      if (-1 == g[t][e].indexOf(n)) continue;
                    } else if (-1 == g[t][e].toLowerCase().indexOf(n)) continue;
                    f = common.lineIndex(g[t][e], n, r.caseSensitive);
                    if (-1 != f) {
                      (i.files[d] = i.files[d] || []),
                        i.files[d].push({
                          fullString: g[t][e],
                          row: t,
                          col: e,
                          type: "cell",
                          lineIndex: f,
                        }),
                        i.count++;
                      break;
                    }
                  }
        }
      }
      e = new Date().getTime();
      i.executionTime = e - a;
    } else {
      if (
        (console.log("Search location:", r.searchLocations),
        r.searchLocations.includes("grid"))
      )
        for (var u in r.files) {
          var p = r.files[u];
          if (0 != Array.isArray(trans.project.files[p].data)) {
            var h = trans.project.files[p].data;
            for (let t = 0; t < h.length; t++)
              if (0 != h[t].length)
                for (let e = 0; e < h[t].length; e++)
                  if ("string" == typeof h[t][e])
                    if (l) {
                      if (l.test(h[t][e])) {
                        (i.files[p] = i.files[p] || []),
                          i.files[p].push({
                            fullString: h[t][e],
                            row: t,
                            col: e,
                            type: "cell",
                          }),
                          i.count++;
                        break;
                      }
                    } else {
                      if (r.caseSensitive) {
                        if (-1 == h[t][e].indexOf(n)) continue;
                      } else if (-1 == h[t][e].toLowerCase().indexOf(n))
                        continue;
                      (i.files[p] = i.files[p] || []),
                        i.files[p].push({
                          fullString: h[t][e],
                          row: t,
                          col: e,
                          type: "cell",
                        }),
                        i.count++;
                    }
          }
        }
      if (r.searchLocations.includes("context"))
        for (var m in r.files) {
          var y = r.files[m];
          if (0 != Array.isArray(trans.project.files[y].context)) {
            var v = trans.project.files[y].context;
            for (let t = 0; t < v.length; t++)
              if (0 != Array.isArray(v[t]) && 0 != v[t].length)
                for (let e = 0; e < v[t].length; e++)
                  if ("string" == typeof v[t][e]) {
                    if (l) {
                      if (0 == l.test(v[t][e])) continue;
                    } else if (r.caseSensitive) {
                      if (-1 == v[t][e].indexOf(n)) continue;
                    } else if (-1 == v[t][e].toLowerCase().indexOf(n)) continue;
                    (i.files[y] = i.files[y] || []),
                      i.files[y].push({
                        fullString: v[t][e],
                        row: t,
                        col: 0,
                        type: "context",
                      }),
                      i.count++;
                  }
          }
        }
      if (r.searchLocations.includes("tag"))
        for (var T in r.files) {
          var w = r.files[T],
            j = n.split(" "),
            b = trans.project.files[w].data;
          for (let e = 0; e < b.length; e++)
            0 != trans.hasTags(j, e, w) &&
              ((i.files[w] = i.files[w] || []),
              i.files[w].push({
                fullString: b[e][this.keyColumn],
                row: e,
                col: 0,
                type: "cell",
              }),
              i.count++);
        }
      if (r.searchLocations.includes("comment"))
        for (var C in (console.log("searching comment"), r.files)) {
          var x = r.files[C];
          if (0 != Boolean(trans.project.files[x].comments)) {
            var S,
              I = trans.project.files[x].comments;
            for (S in (console.log("processing", x), I))
              if (0 != Boolean(I[S]))
                for (var k in I[S])
                  if ("string" == typeof I[S][k]) {
                    if (l) {
                      if (0 == l.test(I[S][k])) continue;
                    } else if (r.caseSensitive) {
                      if (-1 == I[S][k].indexOf(n)) continue;
                    } else if (-1 == I[S][k].toLowerCase().indexOf(n)) continue;
                    (i.files[x] = i.files[x] || []),
                      i.files[x].push({
                        fullString: I[S][k],
                        row: S,
                        col: k,
                        type: "comment",
                      }),
                      i.count++;
                  }
          }
        }
      s = new Date().getTime();
      i.executionTime = s - a;
    }
    return i;
  }),
  (Trans.prototype.replace = function (n, r, o) {
    if ((console.log("entering trans.search"), void 0 === n)) return null;
    if (typeof n.length <= 1) return t("Keyword too short!");
    if (void 0 === trans.project) return null;
    if (void 0 === trans.project.files) return null;
    if (
      ((r = r || ""),
      ((o = o || {}).caseSensitive = o.caseSensitive || !1),
      (o.isRegexp = o.isRegexp || !1),
      0 == Array.isArray(o.files))
    )
      for (var e in ((o.files = []), trans.project.files)) o.files.push(e);
    0 == o.caseSensitive && 0 == o.isRegexp && (n = n.toLowerCase());
    var a,
      i = new Date().getTime(),
      s = {
        keyword: n,
        count: 0,
        isRegexp: o.isRegexp,
        executionTime: 0,
        files: {},
      };
    if (o.isRegexp) {
      var l = common.evalRegExpStr(n);
      if (0 == l)
        return (
          alert(
            n +
              t(
                " is not a valid javascript's regexp!\r\nFind out more about Javascipt's Regular Expression at :\r\nhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions"
              )
          ),
          s
        );
    }
    for (a in o.files) {
      var c = o.files[a];
      if (0 != Array.isArray(trans.project.files[c].data)) {
        var d = trans.project.files[c].data;
        for (let t = 0; t < d.length; t++)
          if (0 != d[t].length)
            for (let e = 1; e < d[t].length; e++)
              if ("string" == typeof d[t][e])
                if (o.isRegexp) {
                  if (l.test(d[t][e])) {
                    var g = trans.project.files[c].data[t][e];
                    (trans.project.files[c].data[t][e] = d[t][e].replace(l, r)),
                      (s.files[c] = s.files[c] || []),
                      s.files[c].push({
                        fullString: trans.project.files[c].data[t][e],
                        row: t,
                        col: e,
                        originalString: g,
                      }),
                      s.count++;
                    break;
                  }
                } else {
                  if (o.caseSensitive) {
                    if (-1 == d[t][e].indexOf(n)) continue;
                  } else if (-1 == d[t][e].toLowerCase().indexOf(n)) continue;
                  g = trans.project.files[c].data[t][e];
                  (trans.project.files[c].data[t][e] = d[t][e].replaces(
                    n,
                    r,
                    !o.caseSensitive
                  )),
                    (s.files[c] = s.files[c] || []),
                    s.files[c].push({
                      fullString: trans.project.files[c].data[t][e],
                      row: t,
                      col: e,
                      originalString: g,
                    }),
                    s.count++;
                }
      }
    }
    var f = new Date().getTime();
    return (s.executionTime = f - i), trans.refreshGrid(), s;
  }),
  (Trans.prototype.findPut = function (n, r, o, a) {
    if ((console.log("entering trans.search"), void 0 === n)) return null;
    if (typeof n.length <= 1) return t("Keyword too short!");
    if (void 0 === trans.project) return null;
    if (void 0 === trans.project.files) return null;
    if (o < 1) return !1;
    if (
      (((a = a || {}).caseSensitive = a.caseSensitive || !1),
      (a.lineMatch = a.lineMatch || !1),
      void 0 === a.overwrite && (a.overwrite = !0),
      0 == Array.isArray(a.files))
    )
      for (var e in ((a.files = []), trans.project.files)) a.files.push(e);
    0 == a.caseSensitive && (n = n.toLowerCase());
    var i = new Date().getTime(),
      s = { keyword: n, count: 0, executionTime: 0, files: {} };
    if (n.includes("\n") || "rowByRow" == a.mode)
      console.log("Entering row by row search"),
        (s = this.findAndInsert(n, r, o, {
          insensitive: !a.caseSensitive,
          overwrite: a.overwrite,
        }));
    else
      for (var l in a.files) {
        var c = a.files[l];
        if (0 != Array.isArray(trans.project.files[c].data)) {
          var d = trans.project.files[c].data;
          for (let t = 0; t < d.length; t++)
            if (0 != d[t].length)
              for (let e = 0; e < d[t].length; e++)
                if ("string" == typeof d[t][e]) {
                  if (a.caseSensitive) {
                    if (-1 == d[t][e].indexOf(n)) continue;
                  } else if (-1 == d[t][e].toLowerCase().indexOf(n)) continue;
                  var g = common.lineIndex(d[t][e], n, a.caseSensitive);
                  if (-1 != g) {
                    var f = common.insertLineAt(d[t][o], r, g, {
                      lineBreak: trans.project.files[c].lineBreak || "\n",
                    });
                    (d[t][o] = f),
                      (s.files[c] = s.files[c] || []),
                      s.files[c].push({
                        fullString: d[t][e],
                        row: t,
                        col: e,
                        type: "cell",
                        lineIndex: g,
                      }),
                      s.count++;
                    break;
                  }
                }
        }
      }
    var u = new Date().getTime();
    return (s.executionTime = u - i), trans.refreshGrid(), s;
  });
class TransProjectHook {
  constructor() {
    this.hooks = {};
  }
}
(TransProjectHook.prototype.defineHook = function (e, t) {
  if ("string" != typeof e)
    throw new Error(`hookName must be a string ${typeof e} given`);
  if ("function" != typeof t)
    throw new Error(`hookName must be a function ${typeof t} given`);
  this.hooks[e] = t;
}),
  (TransProjectHook.prototype.getHook = function (e) {
    return this.hooks[e];
  }),
  (TransProjectHook.prototype.run = async function (e, ...t) {
    "function" == typeof this.hooks[e] &&
      (await this.hooks[e].apply(window.trans, t));
    e = trans.getOption("hooks");
    if (e && "string" == typeof e?.afterExport && (await ui.confirmRunScript()))
      return new (Object.getPrototypeOf(async function () {}).constructor)(
        e.afterExport
      ).apply(trans, t);
  });
var trans = new Trans();
((window.trans = trans).cellInfo = new Trans.CellInfo()),
  (trans.projectHook = new TransProjectHook()),
  (trans.gridContextMenu = {
    commentsAddEdit: {
      name: t("Add comment"),
      hidden: function () {
        return (
          !!trans.grid.isColumnHeaderSelected() ||
          !!trans.grid.isRowHeaderSelected()
        );
      },
    },
    commentsRemove: {
      name: t("Delete comment"),
      hidden: function () {
        return (
          !!trans.grid.isColumnHeaderSelected() ||
          !!trans.grid.isRowHeaderSelected()
        );
      },
    },
    sepx: "---------",
    translateThisCell: {
      name: function () {
        var e =
          "<span class='HOTMenuTranslateHere'>" +
          t("Translate here") +
          " <kbd>ctrl+g</kbd></span>";
        if (void 0 === trans.project) return e;
        trans.project.options = trans.project.options || {};
        var n,
          r,
          o = trans.getActiveTranslator();
        return (
          console.log("thisTrans", o),
          void 0 !== o &&
          ((n = trans.getSl() || "??"),
          (r = trans.getTl() || "??"),
          (o = trans.getTranslatorEngine(o)?.name))
            ? t("Translate here using ") +
              o +
              " (" +
              n +
              "<i class='icon-right-bold'></i>" +
              r +
              ") <kbd>ctrl+g</kbd>"
            : e
        );
      },
      callback: function () {
        trans.translateSelection();
      },
      hidden: function () {
        return (
          !!trans.grid.isColumnHeaderSelected() ||
          !!trans.grid.isRowHeaderSelected() ||
          !trans.getActiveTranslator()
        );
      },
    },
    translateUsing: {
      name: function () {
        return trans.drawGridTranslatorMenu(), t("Translate using...");
      },
      submenu: { items: [] },
      hidden: function () {
        return !!trans.grid.isRowHeaderSelected();
      },
    },
    mergeThenTranslate: {
      name: "<span>Merge then translate <kbd>ctrl+shift+g</kbd></span>",
      hidden: function () {
        return !!trans.grid.isRowHeaderSelected();
      },
      callback: async function () {
        trans.translateSelectionAsOneLine();
      },
    },
    translateSimiliar: {
      name: "<span>Translate like this <kbd>ctrl+l</kbd></span>",
      hidden: function () {
        return !!trans.grid.isRowHeaderSelected();
      },
      callback: async function () {
        var e;
        confirm(
          t(
            "Do you want to translate all the same texts found across this project with the translation on the selected cell(s)?"
          )
        ) &&
          ((e = await trans.translateAllBySelectedCells()),
          alert(e.length + t(" cell(s) has been written!")));
      },
    },
    "---------": {},
    columnWidth: {
      name: t("Column width"),
      callback: function (e, n, r) {
        console.log("column width : ", arguments);
        var o = common.gridSelectedCols(),
          a = prompt("Enter new width", this.getColWidth(o[0]));
        if ((a = parseInt(a)) < 1) return alert(t("Width must greater than 0"));
        for (var i = 0; i < o.length; i++) this.setColWidth(o[i], a);
      },
      hidden: function () {
        return (
          !this.isColumnHeaderSelected() && (this.isRowHeaderSelected(), !0)
        );
      },
    },
    sepn: {
      name: "---------",
      hidden: function () {
        return (
          !this.isColumnHeaderSelected() && (this.isRowHeaderSelected(), !0)
        );
      },
    },
    "col-right": {
      name: t("Insert column right"),
      callback: function () {
        trans.grid.insertColumnRight();
      },
      hidden: function () {
        return (
          !trans.grid.isColumnHeaderSelected() &&
          (trans.grid.isRowHeaderSelected(), !0)
        );
      },
    },
    duplicateCol: {
      name: t("Duplicate column"),
      callback: function () {
        var e = trans.grid.getSelected()[0][1],
          t = trans.columns.length,
          n = trans.colHeaders[e] || "New Col";
        trans.columns.push({}),
          common.arrayExchange(trans.columns, t, e + 1),
          common.arrayInsert(trans.colHeaders, e + 1, n),
          console.log(trans.columns),
          trans.insertCell(e + 1, null),
          trans.copyCol(e, e + 1),
          trans.grid.updateSettings({ colHeaders: trans.colHeaders });
      },
      hidden: function () {
        return (
          !trans.grid.isColumnHeaderSelected() ||
          trans.grid.getSelected()[0][1] != trans.grid.getSelected()[0][3] ||
          1 < trans.grid.getSelected().length
        );
      },
    },
    removeColumn: {
      name: t("Remove this column"),
      callback: function (e, n, r) {
        console.log(arguments),
          confirm(t("Remove selected column?\nThis can not be undone!")) &&
            trans.removeColumn(n[0].start.col, { refreshGrid: !0 });
      },
      hidden: function () {
        return (
          !trans.grid.isColumnHeaderSelected() &&
          (trans.grid.isRowHeaderSelected(), !0)
        );
      },
    },
    renameColumn: {
      name: t("Rename this column"),
      callback: function (e, n, r) {
        console.log(arguments);
        var n = n[0].start.col,
          o = trans.colHeaders[n],
          o = prompt(t("Please enter new name"), o);
        o && trans.renameColumn(n, o, { refreshGrid: !0 });
      },
      hidden: function () {
        return (
          !trans.grid.isColumnHeaderSelected() &&
          (trans.grid.isRowHeaderSelected(), !0)
        );
      },
    },
    sep0: "---------",
    tags: {
      name: "Tags",
      submenu: {
        items: [
          {
            key: "tags:red",
            name: '<i class="tag red icon-circle"></i> ' + t("Red"),
            callback: function (e, t, n) {
              trans.setTagForSelectedRow("red", t);
            },
          },
          {
            key: "tags:yellow",
            name: '<i class="tag yellow icon-circle"></i> ' + t("Yellow"),
            callback: function (e, t, n) {
              trans.setTagForSelectedRow("yellow", t);
            },
          },
          {
            key: "tags:green",
            name: '<i class="tag green icon-circle"></i> ' + t("Green"),
            callback: function (e, t, n) {
              trans.setTagForSelectedRow("green", t);
            },
          },
          {
            key: "tags:blue",
            name: '<i class="tag blue icon-circle"></i> ' + t("Blue"),
            callback: function (e, t, n) {
              trans.setTagForSelectedRow("blue", t);
            },
          },
          {
            key: "tags:gold",
            name: '<i class="tag gold icon-circle"></i> ' + t("Gold"),
            callback: function (e, t, n) {
              trans.setTagForSelectedRow("gold", t);
            },
          },
          {
            key: "tags:more",
            name:
              '<i class="tag icon-tags"></i> ' +
              t("More tags...") +
              " <kbd>ctrl+t</kbd>",
            callback: function (e, t, n) {
              ui.taggingDialog(t);
            },
          },
          {
            key: "tags:clear",
            name: '<i class="tag icon-blank"></i> ' + t("Clear tags"),
            callback: function (e, t, n) {
              trans.clearTags(void 0, t), trans.grid.render();
            },
          },
        ],
      },
    },
    sep1: "---------",
    deleteRow: {
      name: function () {
        return t("Delete Row") + " <kbd>shift+del</kbd>";
      },
      callback: function (e, n, r) {
        confirm(t("Do you want to remove the currently selected row(s)?")) &&
          (trans.removeRow(trans.getSelectedId(), common.gridSelectedRows()),
          trans.refreshGrid(),
          trans.grid.deselectCell());
      },
      hidden: function () {
        return (
          !!trans.grid.isColumnHeaderSelected() ||
          (trans.grid.isRowHeaderSelected(), !1)
        );
      },
    },
    clearContextTranslation: {
      name: t("Clear Context Translation") + " <kbd>alt+del</kbd>",
      callback: function (e, t, n) {
        trans.trigger("clearContextTranslationByRow", {
          file: trans.getSelectedId(),
          row: trans.grid.getSelectedRange(),
          type: "range",
        });
      },
      hidden: function () {
        return (
          !!trans.grid.isColumnHeaderSelected() ||
          (trans.grid.isRowHeaderSelected(), !1)
        );
      },
    },
    sep2: "---------",
    createAutomation: {
      name: t("Create Automation"),
      callback: function (e, t, n) {
        console.log(arguments);
        var r = {
          workspace: "gridSelection",
          cellRange: trans.grid.getSelectedRange(),
        };
        ui.openAutomationEditor("codeEditor_gridSelection", r);
      },
    },
    runAutomation: {
      name: () => (trans.updateRunScriptGridMenu(), t("Run Automation")),
    },
    clearAutomation: {
      name: t("Clear Automation"),
      callback: function () {
        confirm(t("Are you sure want to clear all quick launch scripts?")) &&
          (sys.setConfig("codeEditor/gridSelection", { quickLaunch: [] }),
          sys.saveConfig());
      },
    },
    sep3: "---------",
    appendToReference: {
      name: t("Append rows to reference") + " <kbd>ctrl+shift+d</kbd>",
      callback: function (e, t, n) {
        trans.appendSelectedRowToReference();
      },
      hidden: function () {
        return !!trans.grid.isColumnHeaderSelected();
      },
    },
    properties: {
      name: t("Row properties"),
      callback: function (e, t, n) {
        console.log(arguments), ui.openRowProperties();
      },
      hidden: function () {
        return (
          !!trans.grid.isColumnHeaderSelected() ||
          (trans.grid.isRowHeaderSelected(), !1)
        );
      },
    },
  }),
  (trans.fileLoader = new FileLoader()),
  trans.fileLoader.add("json", function (e) {
    trans.open(e);
  }),
  trans.fileLoader.add("trans", function (e) {
    trans.open(e);
  }),
  trans.fileLoader.add("tpp", function (e) {
    trans.importTpp(e);
  }),
  (window.Attachment = function (e) {
    (e = e || {}), Object.assign(this, e);
  }),
  $(document).ready(function () {
    0 != $("body").is('[data-window="trans"]') &&
      (trans.fileSelectorContextMenuInit(),
      $(window).resize(
        debounce(function () {
          $(document).trigger("windowResizeStop"),
            trans.grid.render(),
            ui.fixCellInfoSize();
        }, 100)
      ),
      trans.initTable(),
      (trans.isLoaded = !0),
      trans.on("transLoaded", async () => {
        console.warn("Trans loaded"),
          $(".menu-button > .button-gridInfo.gridInfo").removeClass("checked"),
          trans.getOption("gridInfo")?.isRuleActive &&
            $(".menu-button > .button-gridInfo.gridInfo").addClass("checked");
      }));
  });
update: this new version you mentioned also works in the way I described
Thank you very much for your explanation, jaden_yuki.
Even though I don’t really understand coding, I truly appreciate the information and the warning you've shared.
I’m just a regular user who uses this tool to translate games, so insights like these are really helpful to keep in mind.
 

Hero_Protagonist

New Member
Apr 6, 2024
3
1
update: this code that is fetched is also encrypted, a bad sign, and the decrypted code is minified as well, a very bad sign. I'll share it here

JavaScript:
/**=====LICENSE STATEMENT START=====
    Translator++
    CAT (Computer-Assisted Translation) tools and framework to create quality
    translations and localizations efficiently.

    Copyright (C) 2018  Dreamsavior<dreamsavior@gmail.com>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.
=====LICENSE STATEMENT END=====*/
/**
* @file trans.js The core class of Translator++
* @author Dreamsavior
* File version: 2024-04-03 14:22:34.304
*/

(window.fs = require("graceful-fs")),
  (window.afs = require("await-fs")),
  (window.nwPath = require("path")),
  (window.spawn = require("child_process").spawn),
  (window.debounce = require("debounce")),
  (window.BatchTranslate = require("www/js/BatchTranslate.js")),
  (window.insertArrayAt = function (e, t, n) {
    return Array.prototype.splice.apply(e, [t, 0].concat(n)), e;
  }),
  (global.common ||= {}),
  (common.arrayExchange = function (e, t, n) {
    var r = e[t];
    e.splice(t, 1), e.splice(n, 0, r);
  }),
  (common.arrayExchangeBatch = function (e, t, n) {
    0 == Array.isArray(t) && common.arrayExchange(e, t, n);
    for (var r = t.length - 1; 0 <= r; r--) common.arrayExchange(e, t[r], n);
    return e;
  }),
  (common.arrayMove = function (e, t, n) {
    if (0 != Array.isArray(e) && n !== t) {
      for (var r = e[t], o = n < t ? -1 : 1, a = t; a != n; a += o)
        e[a] = e[a + o];
      e[n] = r;
    }
    return e;
  }),
  (common.arrayMoveBatch = function (e, t, n) {
    if (0 == Array.isArray(t)) return common.arrayMove(e, t, n);
    for (var r = 0, o = t.length - 1; 0 <= o; o--)
      (e = common.arrayMove(e, t[o] + r, n)), r++;
    return e;
  }),
  (common.escapeSelector = function (e) {
    return "string" == typeof (e = e || "") && '"' + CSS.escape(e) + '"';
  }),
  (common.arrayInsert = function (e, t, n) {
    return e.splice(t, 0, n), e;
  }),
  (common.batchArrayInsert = function (e, t, n) {
    for (var r = 0; r < e.length; r++) this.arrayInsert(e[r], t, n);
    return e;
  });
var FileLoader = function () {
  this.handler = {};
};
(FileLoader.prototype.add = function (e, t) {
  this.handler[e] = t;
}),
  (FileLoader.prototype.open = function (e, t) {}),
  (window.FileLoader = FileLoader);
class Trans extends require("www/js/BasicEventHandler.js") {
  constructor() {
    super($(document)), this.init();
  }
}
(Trans.maxCols = 15),
  (Trans.CellInfo = function () {}),
  (Trans.CellInfo.prototype.getAll = function (e) {
    if (e && trans?.project?.files?.[e])
      return (
        (e = trans.getObjectById(e)).cellInfo || (e.cellInfo = []), e.cellInfo
      );
  }),
  (Trans.CellInfo.prototype.getRow = function (e, t) {
    e = this.getAll(e);
    if (e) return e[t];
  }),
  (Trans.CellInfo.prototype.getCell = function (e, t, n) {
    e = this.getRow(e, t);
    if (e) return e[n];
  }),
  (Trans.CellInfo.prototype.getBestCellInfo = function (e, t, n) {
    var r = trans.getData(e),
      r = trans.getTranslationColFromRow(r[t]),
      e = this.getCell(e, t, r);
    return e && (n ? e[n] : e);
  }),
  (Trans.CellInfo.prototype.get = function (e, t, n, r) {
    t = this.getCell(t, n, r);
    if (t) return t[e];
  }),
  (Trans.CellInfo.prototype.set = function (e, t, n, r, o) {
    n = this.getAll(n);
    return (n[r] = n[r] || []), (n[r][o] = n[r][o] || {}), (n[r][o][e] = t), !0;
  }),
  (Trans.CellInfo.prototype.delete = function (e, t, n, r) {
    t = this.getAll(t);
    return (
      (t[n] = t[n] || []), (t[n][r] = t[n][r] || {}), delete t[n][r][e], !0
    );
  }),
  (Trans.CellInfo.prototype.deleteRow = function (e, t) {
    e = this.getAll(e);
    empty(e) || (Array.isArray(e) ? e.splice(t, 1) : delete e[t]);
  }),
  (Trans.CellInfo.prototype.deleteCell = function (e, t, n) {
    e = this.getRow(e, t);
    if (Array.isArray(e)) return e.splice(n, 1), !0;
  }),
  (Trans.CellInfo.prototype.moveCell = function (e, t, n, r) {
    e = this.getRow(e, t);
    if (Array.isArray(e)) return common.arrayMoveBatch(e, n, r), !0;
  }),
  (Trans.prototype.init = function () {
    (this.config = {
      loadRomaji: !0,
      maxRequestLength: 3e3,
      autoSaveEvery: 600,
      batchDelay: 5e3,
      rpgTransFormat: !0,
      autoTranslate: !1,
    }),
      (this.keyColumn = 0),
      (this.isFreeEditing = !1),
      (this.gameTitle = ""),
      (this.gameEngine = ""),
      (this.projectId = ""),
      (this.indexIds = {}),
      (this.fileListLoaded = !1),
      (this.isLoadingFileList = !1),
      (this.unsavedChange = !1),
      (this.gameFolder = ""),
      (this.currentFile = ""),
      (this.skipElement = ["note", "Comment", "Script"]),
      (this.project = void 0),
      (this.timers = {}),
      (this.data = []),
      (this.colHeaders = [
        t("Original Text"),
        t("Initial"),
        t("Machine translation"),
        t("Better translation"),
        t("Best translation"),
      ]),
      (this.onFileNavLoaded = function () {}),
      (this.onFileNavUnloaded = function () {}),
      (this.validateKey = function (e, t) {
        console.log("key validator", e), t("" != e && null != e);
      }),
      (this.columns = [
        { readOnly: !1, validator: this.validateKey, width: 150 },
        { readOnly: !1 },
        { readOnly: !1 },
        { readOnly: !1 },
        { readOnly: !1 },
      ]),
      (this.default = {}),
      (this.default.columns = [
        { readOnly: !1, validator: this.validateKey },
        { readOnly: !1 },
        { readOnly: !1 },
        { readOnly: !1 },
        { readOnly: !1 },
      ]),
      (this.inProject = !1),
      (this.default.colHeaders = [
        t("Original Text"),
        t("Initial"),
        t("Machine translation"),
        t("Better translation"),
        t("Best translation"),
      ]);
  }),
  (Trans.prototype.isTrans = function (e) {
    return !(
      !e ||
      ("Object" !== e.constructor.name && "Trans" !== e.constructor.name) ||
      !e?.project?.files
    );
  }),
  (Trans.prototype.getOption = function (e) {
    if (trans.project)
      return (
        (trans.project.options ||= {}),
        void 0 === trans.project.options.gridInfo &&
          (trans.project.options.gridInfo = {
            isRuleActive: !0,
            enableTrail: !0,
            viewTrail: !1,
            viewOrganicCellMarker: !0,
            rowHeaderInfo: !1,
          }),
        trans.project.options[e]
      );
  }),
  (Trans.prototype.setOption = function (e, t) {
    trans.project &&
      (console.log("Setting option", e, t),
      (trans.project.options ||= {}),
      (trans.project.options[e] = t));
  }),
  (Trans.prototype.getConfig = function (e) {
    if (
      ((trans.project.config = trans.project.config || {}),
      "string" == typeof e)
    )
      return trans.project.config[e];
    if (Array.isArray(e)) {
      var t = trans.project.config;
      try {
        for (var n = 0; n < e.length; n++) t = t[e[n]];
        return t;
      } catch (e) {
        return;
      }
    }
  }),
  (Trans.prototype.setConfig = function (e, t) {
    if (
      ((trans.project.config = trans.project.config || {}),
      "string" == typeof e)
    )
      return (trans.project.config[e] = t), !0;
    if (Array.isArray(e)) {
      var n = trans.project.config;
      try {
        for (var r = 0; r < e.length - 1; r++)
          (n[e[r]] = n[e[r]] || {}), (n = n[e[r]]);
        return (n[e[r]] = t), !0;
      } catch (e) {
        return;
      }
    }
  }),
  (Trans.prototype.isInProject = function () {
    return this.inProject;
  }),
  (Trans.prototype.getTemplatePath = function () {
    var t =
      sys.config.templatePath || nw.App.manifest.localConfig.defaultTemplate;
    fs = fs || require("fs");
    try {
      if (fs.existsSync(t)) return t;
    } catch (e) {
      return nwPath.join(__dirname, t);
    }
  }),
  (Trans.prototype.mergeReference = function (e) {
    for (var t in (console.log("Merging reference"),
    ((e = e || {}).project = e.project || {}),
    (e.project.references = e.project.references || {}),
    (e.project.files = e.project.files || {}),
    e.project.references))
      console.log("assigning : ", t),
        (e.project.files[t] = this.project.references[t]);
    return e;
  }),
  (Trans.prototype.isFileSupported = function (e) {
    return (
      "string" == typeof e &&
      ((e = common.getFileExtension(e)), !!sys.supportedExtension.includes(e))
    );
  }),
  (Trans.prototype.openFile = function (e) {
    var t,
      n = require("child_process").spawn;
    return (
      0 != this.isFileSupported(e) &&
      ((t = common.getFileExtension(e)),
      "function" == typeof this.fileLoader.handler[t]) &&
      void (0 == this.fileListLoaded
        ? (ui.introWindowClose(), this.fileLoader.handler[t].apply(this, [e]))
        : n(nw.process.execPath, [e], { detached: !0 }))
    );
  }),
  (Trans.prototype.initProject = function () {
    if (void 0 !== this.project)
      return console.log("project is already been initialized! skipping!"), !1;
  }),
  (Trans.prototype.closeProject = function () {
    if (void 0 === this.project) return !1;
    "function" == typeof this.grid.destroy() && this.grid.destroy(),
      this.unInitFileNav(),
      this.unInitLocalStorage(),
      (this.project = {}),
      this.init(),
      ui.tableCornerHideLoading(!0),
      ui.closeAllChildWindow(),
      ui.ribbonMenu.clear(),
      ui.clearActiveCellInfo(),
      ui.clearPathInfo(),
      ui.setWindowTitle(""),
      trans.clearFooter(),
      this.initTable(),
      this.gridIsModified(!1);
  }),
  (Trans.prototype.generateNewDictionaryTable = function () {
    var e = "Common Reference";
    if (void 0 !== this.project.files[e]) return this.project.files[e];
    if ("object" == typeof this.project.references)
      for (var t in (console.log("trans.project.reference is an object"),
      this.project.references))
        this.project.files[t] = this.project.references[t];
    else {
      console.log("trans.project.reference is not an object");
      (e = this.getTemplatePath()), (e = this.loadJSONSync(e));
      console.log("template obj : ", e),
        !1 !== Boolean(e) &&
          ((this.project.references = e.project.references),
          console.log("assigning reference : ", this.project.references)),
        this.mergeReference(trans);
    }
    return this.project.references;
  }),
  (Trans.prototype.createProject = function (a) {
    var i, e;
    return (
      console.log("running trans.createProject"),
      !this.isLoadingFileList &&
        "" != this.gameFolder &&
        ((i = this),
        ((a = a || {}).force = a.force || ""),
        (a.selectedFile = a.selectedFile || ""),
        (a.onAfterLoading = a.onAfterLoading || function (e, t) {}),
        (a.options = a.options || {}),
        (this.isLoadingFileList = !0),
        ui.showLoading(),
        (e = {
          gameFolder: this.gameFolder,
          selectedFile: a.selectedFile,
          gameEngine: this.gameEngine,
          gameTitle: this.gameTitle,
          projectId: this.projectId,
          skipElement: this.skipElement,
          indexOriginal: 0,
          indexTranslation: 1,
          force: a.force,
          rpgTransFormat: i.config.rpgTransFormat,
          options: a.options,
        }),
        console.log("Sending this args to loadGameInfo.php : ", e),
        void php.spawn("loadGameInfo.php", {
          args: e,
          onData: function (e) {
            ui.loadingProgress(t("Loading"), e, {
              consoleOnly: !0,
              mode: "consoleOutput",
            });
          },
          onError: function (e) {
            ui.loadingProgress(t("Loading"), e, {
              consoleOnly: !0,
              mode: "consoleOutput",
              classStr: "stderr",
            });
          },
          onDone: function (e) {
            if (
              (console.log("onDone event defined from trans.js"),
              common.isJSON(e))
            )
              (i.project = e),
                (i.currentFile = ""),
                (i.gameTitle = e.gameTitle),
                (i.gameFolder = e.loc),
                (i.projectId = e.projectId),
                (i.gameEngine = e.gameEngine),
                (i.editorName = "Translator++"),
                (i.editorVersion = nw.App.manifest.version),
                i.generateHeader(),
                i.sanitize(),
                i.dataPadding(),
                sys.updateLastOpenedProject(),
                i.autoSave(),
                console.log(e),
                ui.setStatusBar(1, i.gameTitle),
                i.trigger("projectCreated", i, e),
                "function" == typeof a.onAfterLoading &&
                  a.onAfterLoading.call(i, e, this),
                (i.fileListLoaded = !0),
                (i.isLoadingFileList = !1),
                ui.showCloseButton();
            else {
              var e = $("<div>" + e + "</div>"),
                o = e.find("#initialDataPath").attr("data-path");
              if ((console.log("found initPath : " + o), 0 == Boolean(o)))
                ui.loadingProgress(
                  "Error!",
                  "Can not successfully parse your game! Read the documentation here: https://dreamsavior.net/?p=1311",
                  { consoleOnly: !0, mode: "consoleOutput" }
                ),
                  ui.showCloseButton(),
                  (i.fileListLoaded = !1),
                  (i.isLoadingFileList = !1);
              else {
                try {
                  fs.readFile(o, function (e, n) {
                    if (e)
                      throw (
                        (console.log("error opening file : " + o),
                        ui.loadingProgress(
                          "Error!",
                          "Error opening file : " + o,
                          { consoleOnly: !0, mode: "consoleOutput" }
                        ),
                        ui.showCloseButton(),
                        (i.fileListLoaded = !1),
                        (i.isLoadingFileList = !1),
                        e)
                      );
                    var n = n.toString(),
                      r = {};
                    try {
                      r = JSON.parse(n);
                    } catch (e) {
                      return (
                        ui.loadingProgress(
                          t("Error!"),
                          t("Error processing init file : ") + o + "\n" + e,
                          { consoleOnly: !0, mode: "consoleOutput" }
                        ),
                        ui.showCloseButton(),
                        (i.isLoadingFileList = !1)
                      );
                    }
                    if (0 == Boolean(r.files))
                      return (
                        ui.loadingProgress(
                          t("Error!"),
                          t("Error! File list not found in init file at : ") +
                            o,
                          { consoleOnly: !0, mode: "consoleOutput" }
                        ),
                        ui.loadingProgress(
                          t("Error!"),
                          t(
                            "This means that your game was not successfully parsed. Please visit https://dreamsavior.net/?p=1311 for possible solution for this issue."
                          ),
                          { consoleOnly: !0, mode: "consoleOutput" }
                        ),
                        ui.showCloseButton(),
                        (i.isLoadingFileList = !1)
                      );
                    (i.project = r),
                      (i.currentFile = ""),
                      (i.gameTitle = r.gameTitle),
                      (i.gameFolder = r.loc),
                      (i.projectId = r.projectId),
                      (i.gameEngine = r.gameEngine),
                      (i.editorName = "Translator++"),
                      (i.editorVersion = nw.App.manifest.version),
                      i.generateHeader(),
                      i.sanitize(),
                      i.dataPadding(),
                      sys.updateLastOpenedProject(),
                      i.autoSave(),
                      console.log(r),
                      ui.setStatusBar(1, i.gameTitle),
                      i.trigger("projectCreated", i, r),
                      "function" == typeof a.onAfterLoading &&
                        a.onAfterLoading.call(i, r, this),
                      (i.fileListLoaded = !0),
                      (i.isLoadingFileList = !1),
                      ui.loadingProgress(t("Done!"), t("All done!"), {
                        consoleOnly: !1,
                        mode: "consoleOutput",
                      }),
                      ui.loadingEnd();
                  });
                } catch (e) {
                  console.log("error opening file : " + o),
                    ui.loadingProgress(
                      t("Error!"),
                      t("Error opening file : ") + o,
                      { consoleOnly: !1, mode: "consoleOutput" }
                    ),
                    ui.loadingProgress(t("Error!"), e, {
                      consoleOnly: !0,
                      mode: "consoleOutput",
                    }),
                    ui.loadingEnd(),
                    (i.fileListLoaded = !1),
                    (i.isLoadingFileList = !1);
                }
                e = e.find("#tmpPath");
                0 < e.length && ui.showOpenCacheButton(e.text());
              }
            }
          },
        }))
    );
  }),
  (Trans.prototype.procedureCreateProject = function (t, n) {
    if (
      (console.log("running trans.procedureCreateProject"),
      console.log(arguments),
      void 0 === t)
    )
      return !1;
    ((n = n || {}).selectedFile = n.selectedFile || ""),
      (n.force = n.force || ""),
      (n.projectInfo = n.projectInfo || { id: "", title: "" }),
      (n.options = n.options || {}),
      (n.gameEngine = n.gameEngine || ""),
      this.closeProject(),
      (this.projectId = n.projectInfo.id),
      (this.gameTitle = n.projectInfo.title),
      (this.gameFolder = t),
      (this.gameEngine = n.gameEngine),
      ui.newProjectDialog.close(),
      this.createProject({
        selectedFile: n.selectedFile,
        force: n.force,
        onAfterLoading: async function (e) {
          this.drawFileSelector(),
            (this.project.options = this.project.options || {}),
            (this.project.options.init = n.options || {}),
            engines.hasHandler("onAfterCreateProject") &&
              (await common.wait(100),
              await engines.handler("onAfterCreateProject").call(this, t, n));
        },
        options: n.options,
      });
  }),
  (Trans.prototype.getRow = function (e, t) {
    if ("string" == typeof t)
      return (
        console.log("Get row", arguments),
        0 == e.indexIsBuilt &&
          (console.log("building index for the first time"),
          this.buildIndexFromData(e)),
        (e.indexIds = e.indexIds || {}),
        console.log("getRow result is : ", e.indexIds[t]),
        e.indexIds[t]
      );
  }),
  (Trans.prototype.updateProject = function (e, t) {
    "string" == typeof e && (e = JSON.parse(e)),
      ((t = t || {}).onAfterLoading =
        t.onAfterLoading || function (e, t, n) {}),
      (t.onSuccess = t.onSuccess || function (e, t) {}),
      (t.onFailed = t.onFailed || function (e, t) {}),
      (t.filePath = t.filePath || ""),
      (t.purgeNonExistingData ||= !1),
      (e.project = e.project || {}),
      (e.project.files = e.project.files || {});
    var n,
      r = e,
      o = this.getSaveData().project.files || {};
    for (n in (console.log("Base data", e),
    console.log("Preserved current files", o),
    (r.project.files = e.project.files),
    e.project.files)) {
      var a = r.project.files[n];
      if (o[n] && o[n].data && !(o[n].data.length < 1))
        if (
          (console.log("%cprocessing file", "color:aqua", n),
          t.purgeNonExistingData)
        )
          for (let t = 0; t < a.data.length; t++) {
            var i = a.data[t][0],
              s = this.getRow(o[n], i);
            if (
              (console.log("%cKey", "color:aqua", i),
              console.log("%coldFileRow", "color:aqua", s),
              void 0 !== s && o[n].data[s])
            )
              for (let e = 1; e < o[n].data[s].length; e++)
                a.data[t][e] = o[n].data[s][e];
          }
        else {
          var l,
            c,
            d,
            g = o[n];
          let t = 0;
          for (let e = 0; e < g.data.length; e++)
            g.data[e]?.length &&
              (l = g.data[e][0]) &&
              (void 0 === (c = this.getRow(a, l))
                ? ((d = a.data.push(g.data[e]) - 1),
                  (a.data.indexIds ||= {}),
                  (a.data.indexIds[l] = d),
                  (a.context[d] = ["RefreshCarryover/" + t]),
                  g.cellInfo?.[e] &&
                    ((a.cellInfo ||= []), (a.cellInfo[d] = g.cellInfo[e])),
                  g.comments?.[e] &&
                    ((a.comments ||= []), (a.comments[d] = g.comments[e])),
                  g.parameters?.[e] &&
                    ((a.parameters ||= []),
                    (a.parameters[d] = g.parameters[e])),
                  g.tags?.[e] && ((a.tags ||= []), (a.tags[d] = g.tags[e])),
                  t++)
                : ((a.data[c] = g.data[e]),
                  g.cellInfo?.[e] &&
                    ((a.cellInfo ||= []), (a.cellInfo[c] = g.cellInfo[e])),
                  g.comments?.[e] &&
                    ((a.comments ||= []), (a.comments[c] = g.comments[e])),
                  g.parameters?.[e] &&
                    ((a.parameters ||= []),
                    (a.parameters[c] = g.parameters[e])),
                  g.tags?.[e] && ((a.tags ||= []), (a.tags[c] = g.tags[e]))));
        }
    }
    return console.log("updatedProject", r), r;
  }),
  (Trans.prototype.updateProject2 = function (e, t = this.getSaveData()) {
    return e;
  }),
  (Trans.prototype.openFromTransObj = function (e, t) {
    "string" == typeof e && (e = JSON.parse(e)),
      ((t = t || {}).onAfterLoading =
        t.onAfterLoading || function (e, t, n) {}),
      (t.onSuccess = t.onSuccess || function (e, t) {}),
      (t.onFailed = t.onFailed || function (e, t) {}),
      (t.filePath = t.filePath || ""),
      (t.isNew = t.isNew || !1),
      t.isNew && ((e = this.initTransData(e)), console.log(e)),
      (this.currentFile = t.filePath),
      this.applySaveData(e),
      this.sanitize(),
      this.grid.render(),
      sys.insertOpenedFileHistory();
    try {
      ($DV.config.sl = this.project.options.sl || "ja"),
        ($DV.config.tl = this.project.options.tl || "en");
    } catch (e) {
      ($DV.config.sl = "ja"), ($DV.config.tl = "en");
    }
    "function" == typeof t.onSuccess && t.onSuccess.call(this, e),
      "function" == typeof t.onAfterLoading &&
        t.onAfterLoading.call(this, "success", e),
      this.updateStagingInfo(),
      (this.isOpeningFile = !1),
      ui.hideBusyOverlay(),
      e.project.selectedId
        ? this.selectFile(e.project.selectedId)
        : this.selectFile($(".fileList .data-selector").eq(0));
  }),
  (Trans.prototype.detectFormat = async function (e) {
    return (
      !!e &&
      (".tpp" == nwPath.extname(e).toLowerCase()
        ? "tpp"
        : ".trans" == nwPath.extname(e).toLowerCase() && "trans")
    );
  }),
  (Trans.prototype.open = async function (r, o) {
    var a;
    return (
      "" != (r = r || this.currentFile) &&
      null != r &&
      void 0 !== r &&
      (console.log("opening project : ", r),
      "tpp" == (await this.detectFormat(r))
        ? this.importTpp(r)
        : ((a = this),
          ((o = o || {}).onAfterLoading =
            o.onAfterLoading || function (e, t, n) {}),
          (o.onSuccess = o.onSuccess || function (e, t) {}),
          (o.onFailed = o.onFailed || function (e, t) {}),
          (a.isOpeningFile = !0),
          ui.showBusyOverlay(),
          void fs.readFile(r, function (n, e) {
            if (n)
              console.log(n),
                alert(t("error opening file (open): ") + r + "\r\n" + n),
                void 0 !== e &&
                  ((e = e.toString()),
                  "function" == typeof o.onFailed && o.onFailed.call(a, e),
                  "function" == typeof o.onAfterLoading) &&
                  o.onAfterLoading.call(a, "error", e),
                ui.hideBusyOverlay();
            else {
              e = e.toString();
              n = {};
              try {
                n = JSON.parse(e);
              } catch (e) {
                return (
                  console.warn("Failed to parse JSON data"),
                  alert(
                    "Failed to parse JSON data.\nThe .trans file is corrupted."
                  ),
                  "function" == typeof o.onAfterLoading &&
                    o.onAfterLoading.call(a, "Failed", n),
                  (a.isOpeningFile = !1),
                  void ui.hideBusyOverlay()
                );
              }
              console.log(n),
                (a.currentFile = r),
                a.applySaveData(n),
                a.sanitize(),
                a.grid.render(),
                sys.insertOpenedFileHistory();
              try {
                ($DV.config.sl = a.project.options.sl || "ja"),
                  ($DV.config.tl = a.project.options.tl || "en");
              } catch (e) {
                ($DV.config.sl = "ja"), ($DV.config.tl = "en");
              }
              "function" == typeof o.onSuccess && o.onSuccess.call(a, n),
                "function" == typeof o.onAfterLoading &&
                  o.onAfterLoading.call(a, "success", n),
                (a.isOpeningFile = !1),
                ui.hideBusyOverlay(),
                n.project.selectedId
                  ? a.selectFile(n.project.selectedId)
                  : a.selectFile($(".fileList .data-selector").eq(0)),
                a.gridIsModified(!1),
                (a.project.options = a.project.options || {}),
                console.log("displaying info "),
                Boolean(a.project.options.info) &&
                  a.project.options.displayInfo &&
                  ui.showPopup(
                    "infobox_" + a.project.projectId,
                    a.project.options.info,
                    {
                      title: "Project's Info",
                      allExternal: !0,
                      HTMLcleanup: !0,
                    }
                  ),
                a.isCacheError()
                  ? (ui.addIconOverlay($(".button-properties"), "attention"),
                    $(".button-properties").attr(
                      "title",
                      "Project properties - Staging path error!"
                    ))
                  : (ui.clearIconOverlay($(".button-properties")),
                    $(".button-properties").attr(
                      "title",
                      "Project properties"
                    ));
            }
          })))
    );
  }),
  (Trans.prototype.isCacheError = function () {
    return (
      (trans.project.cache = trans.project?.cache || {}),
      !(
        !trans.project.cache.cachePath ||
        0 != common.isDir(trans.project.cache.cachePath)
      )
    );
  }),
  (Trans.prototype.getSl = function () {
    return (
      (sys.config.default = sys.config.default || {}),
      this.getOption("sl") || sys.config.default?.sl || $DV.config.sl
    );
  }),
  (Trans.prototype.getTl = function () {
    return (
      (sys.config.default = sys.config.default || {}),
      this.getOption("tl") || sys.config.default?.tl || $DV.config.tl
    );
  }),
  (Trans.prototype.setSl = function (e) {
    this.project && this.setOption("sl", e);
  }),
  (Trans.prototype.setTl = function (e) {
    this.project && this.setOption("tl", e);
  }),
  (Trans.prototype.applyNewData = function (e) {
    e = e || [[]];
    for (var t = 0; t < e.length; t++) this.data[t] = e[t];
  }),
  (Trans.prototype.applyNewHeader = function (e) {
    e = e || [];
    for (var t = 0; t < e.length; t++) this.colHeaders[t] = e[t];
  }),
  (Trans.prototype.generateId = function () {
    return common.makeid(10, "tppSZ698");
  }),
  (Trans.prototype.initTransData = function (e) {
    e = e || {};
    var t = JSON.parse(fs.readFileSync("data/template.trans")),
      t =
        ((t.project ||= {}),
        (t.project.projectId = void 0),
        (t.project.buildOn = void 0),
        common.mergeDeep(t, e));
    return (
      (t.project = t.project || {}),
      (t.project.options = t.project.options || {}),
      (t.project.options.init = t.project.options.init || {}),
      (t.project.projectId = t.project.projectId || this.generateId(10)),
      (t.project.buildOn = t.project.buildOn || common.formatDate(Date.now())),
      (t.project.editorVersion = nw.App.manifest.version),
      (t.project.editorName = "Translator++"),
      t
    );
  }),
  (Trans.prototype.createFileData = function (e, t, n = {}) {
    return (
      (t = t || {}),
      (e = e.replace(/\\/g, "/")),
      n?.leadSlash && "/" !== e.charAt(0) && (e = "/" + e),
      (t.basename = t.basename || nwPath.basename(e)),
      (t.filename = t.filename || nwPath.basename(e)),
      (t.path = t.path || e),
      (t.relPath = t.relPath || e),
      (t.data = t.data || [[null]]),
      (t.originalFormat = t.originalFormat || "Autogenerated TRANS obj"),
      (t.type = t.type || ""),
      (t.context = t.context || []),
      (t.tags = t.tags || []),
      void 0 === t.extension && (t.extension = nwPath.extname(e)),
      void 0 === t.dirname && (t.dirname = nwPath.dirname(e)),
      t
    );
  }),
  (Trans.prototype.validateTransData = function (e) {
    var n,
      r,
      o,
      a = {};
    if (Array.isArray(e))
      return (
        console.log("Case 1 - transData is array"),
        ((n = this.loadJSONSync(this.getTemplatePath())).project.files[
          "/main"
        ] = this.createFileData("/main", { data: e })),
        n
      );
    if (
      0 == Boolean(e.project) &&
      0 == Boolean(e.files) &&
      Array.isArray(e.data)
    )
      return (
        console.log("Case 1 - transData is file structured"),
        (n = this.loadJSONSync(this.getTemplatePath())),
        (r = e.path || "/main"),
        (n.project.files[r] = this.createFileData(r, { data: e.data })),
        n
      );
    for (o in (0 == Boolean(e.project) && 1 == Boolean(e.files)
      ? (a.project = e)
      : (a = e),
    (a.project.gameTitle = a.project.gameTitle || t("untitled project")),
    (a.project.gameEngine = a.project.gameEngine || ""),
    (a.project.projectId = a.project.projectId || ""),
    (a.project.buildOn = a.project.buildOn || common.formatDate()),
    (a.project.files = a.project.files || {}),
    a.project.files))
      a.project.files[o] = this.createFileData(o, a.project.files[o]);
    return a;
  }),
  (Trans.prototype.normalizeHeader = function () {
    for (var e = 0; e < this.columns.length; e++)
      e == this.keyColumn && (this.columns[e].validator = this.validateKey),
        (this.columns[e].wordWrap = !0);
  }),
  (Trans.prototype.applySaveData = function (t) {
    if (
      (console.log("entering trans.applySaveData"),
      console.log(t),
      (t = this.validateTransData((t = t || {}))),
      (this.data = t.data || [[null]]),
      (this.columns = t.columns || this.default.columns || []),
      this.normalizeHeader(),
      (this.colHeaders = t.colHeaders || this.default.colHeaders || []),
      (this.project = t.project || {}),
      (this.gameTitle = t.project.gameTitle || ""),
      (this.gameEngine = t.project.gameEngine || ""),
      (this.projectId = t.project.projectId || ""),
      (this.gameFolder = t.project.loc || ""),
      0 == t.fileListLoaded)
    )
      try {
        void 0 !== t.project.files && (t.fileListLoaded = !0);
      } catch (e) {
        t.fileListLoaded = !1;
      }
    return (
      this.resetIndex(),
      (this.fileListLoaded = t.fileListLoaded || !1),
      this.initFileNav(),
      this.refreshGrid(),
      ui.setWindowTitle(),
      ui.setStatusBar(1, this.gameTitle),
      this
    );
  }),
  (Trans.prototype.getSaveData = function (e) {
    if (
      (((e = e || {}).filter = e.filter || []),
      (e.type = e.type || ""),
      !empty(this.project) && !empty(this.project.files))
    ) {
      this.project.projectId = this.project.projectId || common.makeid(10);
      var t = JSON.parse(JSON.stringify(this.project)) || {};
      if (
        0 < e.filter.length &&
        (console.log("filtering saved object", e), void 0 !== this.project) &&
        void 0 !== this.project.files
      ) {
        t.files = {};
        for (var n = 0; n < e.filter.length; n++) {
          var r = e.filter[n];
          console.log(
            "testing " + r,
            this.project.files[r],
            this.project.files
          ),
            void 0 !== this.project.files[r] &&
              (console.log("exist, assigning " + r),
              (t.files[r] = JSON.parse(JSON.stringify(this.project.files[r]))));
        }
      }
      var o,
        a = { data: [[null]] };
      (a.columns = this.columns || []),
        (a.colHeaders = this.colHeaders || []),
        (a.project = t),
        (a.fileListLoaded = this.fileListLoaded);
      for (let e = 0; e < this.grid.getColHeader().length; e++)
        a.columns[e] && (a.columns[e].width = this.grid.getColWidth(e));
      for (o in a.project.files)
        "reference" == a.project.files[o].type &&
          ((a.project.references = a.project.references || {}),
          (a.project.references[o] = JSON.parse(
            JSON.stringify(a.project.files[o])
          )),
          delete a.project.files[o]);
      return "json" == e.type ? JSON.stringify(a) : a;
    }
  }),
  (Trans.prototype.compress = async function (e, t) {
    t = t || {};
    var n = Buffer.from([]),
      n = Buffer.isBuffer(e)
        ? e
        : "string" == typeof e
        ? Buffer.from(e)
        : "object" != typeof e || empty(e)
        ? Buffer.from(JSON.stringify(this.getSaveData()))
        : Buffer.from(JSON.stringify(e));
    return common.gzip(n, t);
  }),
  (Trans.prototype.uncompress = async function (e, t) {
    t = t || {};
    var n = Buffer.from([]);
    if (Buffer.isBuffer(e)) n = e;
    else {
      if ("string" != typeof e)
        return console.error(
          "Can not uncompress from data:",
          e,
          "Only buffer or string is accepted"
        );
      n = Buffer.from(e);
    }
    return common.gunzip(n, t);
  }),
  (Trans.prototype.from = async function (e) {
    var t,
      n = "";
    if (
      (Buffer.isBuffer(e)
        ? (n = (
            "31,139,8,0" == e.slice(0, 10).join(",")
              ? (n = await common.gunzip(e))
              : e
          ).toString())
        : "string" == typeof e && (n = e),
      n)
    ) {
      if (0 == JSON.isJSON(n)) return console.error("unknown format :", e);
      t = JSON.parse(n);
    }
    return t;
  }),
  (Trans.prototype.createBackup = async function (e) {
    var t = parseInt(sys.getConfig("backupLevel"));
    if (sys.getConfig("autoBackup") && t) {
      if (!(await common.isFileAsync(e)))
        return console.warn("no such file ", e);
      if (0 != [".trans", ".tpp"].includes(nwPath.extname(e).toLowerCase())) {
        await common.unlink(e + `.${t}.bak`);
        for (var n = t - 1; 0 <= n; n--)
          0 == n
            ? await common.rename(e, e + `.${n + 1}.bak`)
            : 0 != (await common.isFileAsync(e + `.${n}.bak`)) &&
              (await common.rename(e + `.${n}.bak`, e + `.${n + 1}.bak`));
      }
    }
  }),
  (Trans.prototype.saveAs = async function (e, t) {
    e = await ui.saveAs(e || trans.currentFile || "");
    return console.log("Saving into : ", e), e ? this.save(e, t) : "";
  }),
  (Trans.prototype.save = async function (r, o) {
    if (!(r = r || this.currentFile)) return this.saveAs(r, o);
    var a = this;
    if (
      (((o = o || {}).initiator = o.initiator || "user"),
      (o.filter = o.filter || []),
      (o.onAfterLoading = o.onAfterLoading || function (e, t) {}),
      (o.onSuccess = o.onSuccess || function (e, t) {}),
      (o.onFailed = o.onFailed || function (e, t) {}),
      a.isSavingFile)
    )
      return console.warn(
        "Trans.prototype.save() is busy! Please wait until the previous save procedure to be completed before triggering another one!"
      );
    console.log("Saving data to : " + r);
    var i = a.getSaveData(o);
    return (
      console.log(i),
      (a.isSavingFile = !0),
      ui.saveIndicatorStart(),
      "user" == o.initiator && (await this.createBackup(r)),
      new Promise((t, n) => {
        fs.writeFile(r, JSON.stringify(i), (e) => {
          e
            ? ("function" == typeof o.onFailed && o.onFailed.call(a, i, r),
              ui.saveIndicatorEnd(),
              console.warn("Failed to save to : ", r, e),
              n())
            : ("auto" !== o.initiator &&
                (console.log(r + " successfully saved!"),
                sys.insertOpenedFileHistory(
                  r,
                  i.project.projectId,
                  i.project.gameTitle,
                  o.initiator
                ),
                (this.currentFile = r),
                a.gridIsModified(!1),
                ui.setWindowTitle()),
              "function" == typeof o.onSuccess && o.onSuccess.call(a, i, r),
              t(r)),
            o.onAfterLoading.call(a, i, r),
            setTimeout(function () {
              ui.saveIndicatorEnd();
            }, 1e3),
            (a.isSavingFile = !1);
        });
      })
    );
  }),
  (Trans.prototype.generateCachePath = function () {
    (this.project.cache = this.project.cache || {}),
      (this.project.cache.cacheID =
        this.project.cache.cacheID || this.project.projectId),
      this.project.cache.cacheID ||
        (this.project.cache.cacheID = this.project.projectId =
          common.makeid(10)),
      console.log(
        "Joining",
        sys.config.stagingPath,
        this.project.cache.cacheID
      ),
      (this.project.cache.cachePath =
        this.project.cache.cachePath ||
        nwPath.join(sys.config.stagingPath, this.project.cache.cacheID));
    try {
      fs.mkdirSync(this.project.cache.cachePath, { recursive: !0 });
    } catch (e) {
      console.warn(e);
    }
  }),
  (Trans.prototype.autoSave = async function (e) {
    if (((e = e || {}), void 0 === this.project))
      return (
        (e.onSuccess = e.onSuccess || function () {}),
        e.onSuccess.call(this),
        !1
      );
    try {
      (this.project.cache.cachePath &&
        common.isDir(this.project.cache.cachePath)) ||
        this.generateCachePath();
    } catch (e) {
      console.warn(e);
    }
    e.initiator = "auto";
    var t = nwPath.join(this.project.cache.cachePath, "autosave.json");
    return await this.save(t, e), t;
  }),
  (Trans.prototype.buildIndexFromData = function (e, t) {
    if ("object" != typeof e) return console.warn("fileData is not an object");
    if (0 == Array.isArray(e.data))
      return console.warn("fileData.data is not a valid array");
    if (!e.indexIsBuilt || t) {
      (e.data = e.data || []), (e.indexIds = e.indexIds || {});
      for (var n = 0; n < e.data.length; n++) {
        var r = e.data[n];
        r[0] && (e.indexIds[r[0]] = n);
      }
      e.indexIsBuilt = !0;
    }
    return e;
  }),
  (Trans.prototype.mergeTrans = function (e, t, n) {
    ((t = t || this).project = t.project || {}),
      (t.project.files = t.project.files || {}),
      ((e = e || {}).project = e.project || {}),
      (e.project.files = e.project.files || {}),
      ((n = n || {}).overwrite = n.overwrite || !1),
      (n.targetPair = n.targetPair || {}),
      (n.files = n.files || []),
      (n.all = n.all || !1),
      n.all && (n.targetPair = e.project.files);
    var r,
      o = !1;
    for (r in ((t = this.sanitize(t)) instanceof Trans && (o = !0),
    console.log("running mergeTrans with args : ", arguments),
    n.targetPair)) {
      var a = e.project.files[r],
        i = t.project.files[r];
      if (i) {
        if (
          (console.log("merging data", r),
          0 != Array.isArray(a.data) && 0 != a.data.length)
        ) {
          this.buildIndexFromData(i),
            (i.context = i.context || []),
            (a.context = a.context || []);
          for (var s = 0; s < a.data.length; s++) {
            var l,
              c = a.data[s];
            0 != Boolean(c[0]) &&
              (void 0 === (l = i.indexIds[c[0]]) && (l = i.data.length),
              (i.data[l] = common.clone(c)),
              (i.context[l] = common.clone(a.context[s])));
          }
        }
      } else
        (t.project.files[r] = common.clone(a)),
          o && this.addFileItem(r, t.project.files[r]);
    }
    return (
      o &&
        (this.generateHeader(t),
        this.evalTranslationProgress(),
        ui.fileList.reIndex(),
        ui.initFileSelectorDragSelect()),
      this.refreshGrid(),
      t
    );
  }),
  (Trans.prototype.loadJSONSync = function (t, e) {
    if ("" == t || null == t || void 0 === t) return !1;
    ((e = e || {}).onAfterLoading = e.onAfterLoading || function (e, t) {}),
      (e.onSuccess = e.onSuccess || function (e, t) {}),
      (e.onFailed = e.onFailed || function (e, t) {});
    (e = require("fs").readFileSync(t).toString()), (t = !1);
    try {
      return (t = JSON.parse(e));
    } catch (e) {
      return t;
    }
  }),
  (Trans.prototype.loadJSON = async function (t, e) {
    if ("" == t || null == t || void 0 === t) return !1;
    ((e = e || {}).onAfterLoading = e.onAfterLoading || function (e, t) {}),
      (e.onSuccess = e.onSuccess || function (e, t) {}),
      (e.onFailed = e.onFailed || function (e, t) {}),
      (this.isOpeningFile = !0),
      ui.showBusyOverlay();
    try {
      var n = await common.fileGetContents(t, "utf8", !1),
        r = JSON.parse(n);
    } catch (e) {
      alert("Error loading file: " + t);
    }
    return ui.hideBusyOverlay(), (this.isOpeningFile = !1), r;
  }),
  (Trans.prototype.importFromFile = async function (e, n) {
    ((n = n || {}).overwrite = n.overwrite || !1),
      (n.targetPair = n.targetPair || {}),
      (n.files = n.files || []),
      (n.mergeData = n.mergeData || !1);
    var r = this,
      o = this.isTrans(e)
        ? e
        : ((o = await r.loadJSON(e)), r.validateTransData(o));
    if (n.mergeData) r.mergeTrans(o, r, n);
    else {
      for (var a in n.targetPair) {
        "string" != typeof n.targetPair[a] && (n.targetPair[a] = a);
        try {
          "undefined" !== o.project.references[a] &&
            (r.project.files[n.targetPair[a]] = o.project.references[a]),
            void 0 !== o.project.files[a] &&
              ((r.project.files[n.targetPair[a]] = o.project.files[a]),
              console.log(
                t("create file list"),
                n.targetPair[a],
                r.project.files[n.targetPair[a]]
              ),
              r.addFileItem(n.targetPair[a], r.project.files[n.targetPair[a]]));
        } catch (e) {
          console.log(e);
          continue;
        }
      }
      ui.initFileSelectorDragSelect(),
        r.evalTranslationProgress(),
        ui.fileList.reIndex(),
        r.refreshGrid();
    }
  }),
  (Trans.prototype.selectCell = function (e, t) {
    return this.grid.selectCell(e, t);
  }),
  (Trans.prototype.getProjectChecksum = function () {
    if (!this.project.checksum) {
      var e,
        t = [],
        n = this.getAllFiles();
      for (e in (n.sort(), n)) {
        var r = this.project.files[n[e]];
        if (!empty(r) && !empty(r.data) && "*" != r.dirname) {
          for (var o = [], a = 0; a < r.data.length; a++)
            r.data[a][this.keyColumn] && o.push(r.data[a][this.keyColumn]);
          o.length < 1 ||
            (o.sort(), t.push(common.crc32String(JSON.stringify(o))));
        }
      }
      this.project.checksum = common.crc32String(JSON.stringify(t));
    }
    return this.project.checksum;
  }),
  (Trans.prototype.exportTPP = function (n, r) {
    if (void 0 === n) return !1;
    ((r = r || {}).showDetail = r.showDetail || !1),
      (r.onDone = r.onDone || function () {});
    for (
      var e = [],
        o = $(".fileList .data-selector .fileCheckbox:checked"),
        a = 0;
      a < o.length;
      a++
    )
      e.push(o.eq(a).attr("value"));
    (r.files = r.files || e || []),
      ui.saveIndicatorStart(),
      trans.autoSave({
        onSuccess: function () {
          php.spawn("saveTpp.php", {
            args: {
              path: n,
              password: r.password,
              gameFolder: trans.gameFolder,
              gameTitle: trans.gameTitle,
              projectId: trans.projectId,
              gameEngine: trans.gameEngine,
              files: r.files,
              exportMode: r.mode,
              rpgTransFormat: trans.config.rpgTransFormat,
            },
            onData: function (e) {
              r.showDetail &&
                ui.loadingProgress(t("Loading"), e, {
                  consoleOnly: !0,
                  mode: "consoleOutput",
                });
            },
            onError: function (e) {
              r.showDetail &&
                ui.loadingProgress(t("Loading"), e, {
                  consoleOnly: !0,
                  mode: "consoleOutput",
                  classStr: "stderr",
                });
            },
            onDone: function (e) {
              r.showDetail &&
                (ui.loadingProgress(t("Finished"), t("All process finished!"), {
                  consoleOnly: !1,
                  mode: "consoleOutput",
                }),
                ui.showCloseButton(),
                ui.log.addButtons(t("Open Explorer"), function () {
                  common.openExplorer(n);
                })),
                ui.saveIndicatorEnd(),
                r.onDone.call(trans, e);
            },
          });
        },
      });
  }),
  (Trans.prototype.importTpp = async function (e, r) {
    if (void 0 === e) return !1;
    (r = r || {}).onDone = r.onDone || function () {};
    var n = sys.getConfig("stagingPath");
    (await common.isDir(n)) || (await common.mkDir(n));
    trans.closeProject(),
      trans.autoSave({
        onSuccess: function () {
          ui.showLoading(),
            php.spawn("loadTpp.php", {
              args: { path: e, password: r.password },
              onData: function (e) {
                ui.loadingProgress(t("Loading"), e, {
                  consoleOnly: !0,
                  mode: "consoleOutput",
                });
              },
              onError: function (e) {
                ui.loadingProgress(t("Loading"), e, {
                  consoleOnly: !0,
                  mode: "consoleOutput",
                  classStr: "stderr",
                });
              },
              onDone: function (e) {
                console.log("done");
                var n = $(".console").find("output.cachepath").text(),
                  n = nwPath.join(n, "autosave.json");
                console.log("new cache path : ", n),
                  ui.loadingProgress(t("Loading"), t("Opening file!"), {
                    consoleOnly: !1,
                    mode: "consoleOutput",
                  }),
                  trans.open(n, {
                    onSuccess: function () {
                      (trans.project.cache = trans.project.cache || {}),
                        (trans.project.cache.cachePath = nwPath.dirname(n)),
                        ui.loadingProgress(
                          t("Loading"),
                          t(
                            "Assigning new staging path : " +
                              trans.project.cache.cachePath
                          ),
                          { consoleOnly: !1, mode: "consoleOutput" }
                        ),
                        ui.loadingProgress(t("Loading"), t("Success!"), {
                          consoleOnly: !1,
                          mode: "consoleOutput",
                        }),
                        ui.loadingProgress(
                          t("Finished"),
                          t("All process finished!"),
                          { consoleOnly: !1, mode: "consoleOutput" }
                        ),
                        ui.showCloseButton(),
                        r.onDone.call(trans, e);
                    },
                    onFailed: function () {
                      ui.loadingProgress(t("Loading"), t("Failed!"), {
                        consoleOnly: !1,
                        mode: "consoleOutput",
                      }),
                        ui.loadingProgress(
                          t("Finished"),
                          t("All process finished!"),
                          { consoleOnly: !1, mode: "consoleOutput" }
                        ),
                        ui.showCloseButton(),
                        r.onDone.call(trans, e);
                    },
                  });
              },
            });
        },
      });
  }),
  (Trans.prototype.export = async function (e, t) {
    if (void 0 === e) return !1;
    ((t = t || {}).options = t.options || {}),
      console.log("Exporting with arguments:", arguments),
      (t.mode = t.mode || "dir"),
      (t.onDone = t.onDone || function () {}),
      (t.dataPath = t.dataPath || ""),
      (t.transPath = t.transPath || ""),
      (t.options.filterTag = t.options.filterTag || t.filterTag || []),
      (t.options.filterTagMode =
        t.options.filterTagMode || t.filterTagMode || ""),
      (t.custom = t.custom || t.options.custom),
      delete t.options.custom,
      console.log("exporting project", arguments);
    for (
      var n = [],
        r = $(".fileList .data-selector .fileCheckbox:checked"),
        o = 0;
      o < r.length;
      o++
    )
      n.push(r.eq(o).attr("value"));
    t.files = t.files || n || [];
    var a = trans.project.gameEngine;
    if (
      void 0 !== engines[a] &&
      "function" == typeof engines[a].exportHandler
    ) {
      var i = await engines[a].exportHandler.apply(this, arguments);
      if ((console.log("Is process halt?", i), i))
        return void (await this.projectHook.run("afterExport", t));
    }
    (!["csv", "xlsx", "xls", "ods", "html", "RPGMakerTrans"].includes(t.mode) &&
      "spreadsheet" != a) ||
      this.legacyExport(e, t),
      console.log("Export process is finished");
  }),
  (Trans.prototype.legacyExport = async function (e, n) {
    var r = await trans.autoSave(),
      o =
        (ui.log.show(),
        await ui.log(
          "Exporting project to " + n.mode + " format with legacy mode"
        ),
        (trans.project.options = trans.project.options || {}),
        (trans.project.options.init = trans.project.options.init || {}),
        Object.assign(trans.project.options.init, n.options));
    php.spawn("export.php", {
      args: {
        path: e,
        gameFolder: trans.gameFolder,
        gameTitle: trans.gameTitle,
        projectId: trans.projectId,
        gameEngine: trans.gameEngine,
        files: n.files,
        exportMode: n.mode,
        options: o,
        rpgTransFormat: trans.config.rpgTransFormat,
        dataPath: n.dataPath,
        transPath: nwPath.resolve(n.transPath || r),
      },
      onData: function (e) {
        ui.loadingProgress(t("Loading"), e, {
          consoleOnly: !0,
          mode: "consoleOutput",
        });
      },
      onError: function (e) {
        ui.loadingProgress(t("Loading"), e, {
          consoleOnly: !0,
          mode: "consoleOutput",
          classStr: "stderr",
        });
      },
      onDone: async (e) => {
        console.log("done"),
          ui.loadingProgress(t("Finished"), t("All process finished!"), {
            consoleOnly: !1,
            mode: "consoleOutput",
          }),
          await this.projectHook.run("afterExport", n),
          ui.loadingEnd(),
          n.onDone.call(trans, e);
      },
    });
  }),
  (Trans.prototype.revertToOriginal = async function (e, t = {}) {
    var n = require("better-copy");
    if (
      ((e = e || (await ui.openRevertToOriginalDialog())),
      (t.dataPath = t.dataPath || "data"),
      e)
    ) {
      ui.showLoading(), ui.loadingProgress(0, "Reverting original data");
      var r,
        o = this.project.files,
        a =
          (0 < this.getCheckedFiles().length && (o = this.getCheckedObjects()),
          0),
        i = 0,
        s = Object.keys(o).length || 1;
      for (r in (ui.log(`Processing ${s} file(s)`), o)) {
        i++;
        var l = this.getStagingDataPath(),
          c = this.getStagingFile(o[r]),
          d = common.getRelativePath(c, l);
        await ui.loadingProgress(Math.round((i / s) * 100), "Reverting : " + d),
          (await common.isFileAsync(c))
            ? (await ui.log(i + `/${s} Copying : ` + c),
              await n(c, nwPath.join(e, d), { overwrite: !0 }),
              a++)
            : await ui.log("File not found: " + c);
      }
      await ui.log(`Completed! ${a} file(s) reverted to original!`),
        ui.log.addButtons(
          "Open folder",
          function () {
            nw.Shell.showItemInFolder(nwPath.join(e, d));
          },
          { class: "icon-folder-open" }
        ),
        ui.loadingEnd();
    }
  }),
  (Trans.prototype.importSheet = async function (n, o, a) {
    (o = o || 1),
      ((a = a || {}).sourceColumn = a.sourceColumn || "auto"),
      (a.overwrite = a.overwrite || !1),
      (a.files = a.files || trans.getCheckedFiles() || []),
      (a.sourceKeyColumn = a.sourceKeyColumn || 0),
      (a.keyColumn = a.keyColumn || 0),
      (a.newLine = a.newLine || void 0),
      (a.stripCarriageReturn = a.stripCarriageReturn || !1),
      (a.ignoreNewLine = !0),
      console.log("trans.importSheet"),
      console.log(arguments),
      0 == Array.isArray(n) && (n = [n]),
      ui.showLoading(),
      ui.loadingProgress(0, t("Collecting paths"), {
        consoleOnly: !0,
        mode: "consoleOutput",
      }),
      ui.log("Building indexes"),
      0 == a.files?.length && (a.files = this.getAllFiles()),
      (a.indexes = this.buildIndexes(a.files, !1, { stripCarriageReturn: !0 }));
    var r,
      i = [];
    for (let e = 0; e < n.length; e++) {
      var s,
        l = n[e];
      0 == common.isExist(l)
        ? (ui.loadingProgress(0, t("Path : '") + l + t("' doesn't exist"), {
            consoleOnly: !0,
            mode: "consoleOutput",
          }),
          console.log("Error, path not exist"))
        : common.isDir(l)
        ? ((s = common.dirContentSync(l)), (i = i.concat(s)))
        : i.push(l);
    }
    ui.loadingProgress(0, i.length + t(" file(s) collected!"), {
      consoleOnly: !0,
      mode: "consoleOutput",
    }),
      ui.loadingProgress(0, t("Start importing data!"), {
        consoleOnly: !0,
        mode: "consoleOutput",
      }),
      (r = common.parseSheet
        ? (ui.log("Import using sheet parser add-on"),
          async function (e) {
            var t,
              n = await common.parseSheet(e),
              r = [];
            for (t in n)
              console.log("Merging data", n[t]),
                n[t] && n[t].length && (r = r.concat(n[t]));
            console.log("output data :"),
              console.log(r),
              trans.translateFromArray(r, o, a);
          })
        : (ui.log("Import using legacy sheet importer"),
          function (e) {
            (e = e || l),
              php.spawnSync("import.php", {
                args: {
                  path: e,
                  output: null,
                  mergeSheet: !0,
                  prettyPrint: !0,
                },
                onDone: function (e) {
                  console.log("output data :"),
                    console.log(e),
                    trans.translateFromArray(e, o, a);
                },
              });
          }));
    for (let e = 0; e < i.length; e++) {
      var c = i[e];
      ui.loadingProgress(
        Math.round((e / i.length) * 100),
        t("Importing : ") + c,
        { consoleOnly: !0, mode: "consoleOutput" }
      ),
        await r(c),
        ui.loadingProgress(Math.round(((e + 1) / i.length) * 100), t("Done!"), {
          consoleOnly: !0,
          mode: "consoleOutput",
        });
    }
    trans.refreshGrid(),
      trans.evalTranslationProgress(),
      ui.loadingProgress(t("Done!"), t("All Done!"), {
        consoleOnly: !0,
        mode: "consoleOutput",
      }),
      ui.loadingEnd();
  }),
  (Trans.prototype.importRPGMTrans = function (e, n, r) {
    (n = n || 1),
      ((r = r || {}).sourceColumn = r.sourceColumn || "auto"),
      (r.overwrite = r.overwrite || !1),
      (r.files = r.files || trans.getCheckedFiles() || []),
      (r.sourceKeyColumn = r.sourceKeyColumn || 0),
      (r.keyColumn = r.keyColumn || 0),
      (r.newLine = r.newLine || void 0),
      (r.stripCarriageReturn = r.stripCarriageReturn || !1),
      (r.ignoreNewLine = !0),
      console.log("trans.importRPGMTrans"),
      console.log(arguments),
      0 == Array.isArray(e) && (e = [e]),
      ui.showLoading(),
      ui.loadingProgress(0, t("Collecting paths"), {
        consoleOnly: !0,
        mode: "consoleOutput",
      });
    for (var o = [], a = 0; a < e.length; a++) {
      var i,
        s = e[a];
      0 == common.isExist(s)
        ? (ui.loadingProgress(0, t("Path : '") + s + t("' doesn't exist"), {
            consoleOnly: !0,
            mode: "consoleOutput",
          }),
          console.log("Error, path not exist"))
        : common.isDir(s)
        ? ((i = common.dirContentSync(s)), (o = o.concat(i)))
        : o.push(s);
    }
    ui.loadingProgress(0, o.length + t(" file(s) collected!"), {
      consoleOnly: !0,
      mode: "consoleOutput",
    }),
      ui.loadingProgress(0, t("Start importing data!"), {
        consoleOnly: !0,
        mode: "consoleOutput",
      });
    for (let e = 0; e < o.length; e++) {
      var l = o[e];
      ui.loadingProgress(
        Math.round((e / o.length) * 100),
        t("Importing : ") + l,
        { consoleOnly: !0, mode: "consoleOutput" }
      ),
        (l = (l = l) || s),
        php.spawnSync("parseTrans.php", {
          args: { path: l, prettyPrint: !0 },
          onDone: function (e) {
            console.log("output data :"),
              console.log(e),
              Array.isArray(e.data) && trans.translateFromArray(e.data, n, r);
          },
        }),
        ui.loadingProgress(Math.round(((e + 1) / o.length) * 100), t("Done!"), {
          consoleOnly: !0,
          mode: "consoleOutput",
        });
    }
    trans.refreshGrid(),
      trans.evalTranslationProgress(),
      ui.loadingProgress(t("Done!"), t("All Done!"), {
        consoleOnly: !0,
        mode: "consoleOutput",
      }),
      ui.loadingEnd();
  }),
  (Trans.prototype.clearFooter = function () {
    $(".footer .footer1 span").html(""),
      $(".footer .footer2 span").html(""),
      $(".footer .footer3 span").html(""),
      $(".footer .footer4 span").html(""),
      $(".footer .footer5 span").html("");
  }),
  (Trans.prototype.setStatusBarContext = function (e) {
    void 0 === e &&
      Array.isArray(trans.grid.getSelected()) &&
      (e = trans.grid.getSelected()[0][0]);
    var t = trans.getSelectedId();
    try {
      "> ANTI TES PATCH FILE VERSION 0.2" ==
        trans.project.files[t].originalFormat &&
      "rmrgss" !== this.project.parser
        ? $(".footer .footer1>span").html(
            trans.buildContextFromParameter(
              trans.project.files[t].parameters[e]
            )
          )
        : $(".footer .footer1>span").html(
            trans.project.files[t].context[e].join("; ")
          ),
        $(".footer .footer1>span").addClass("icon-th-2");
    } catch (e) {
      $(".footer .footer1>span").html(""),
        $(".footer .footer1>span").removeClass("icon-th-2");
    }
  }),
  (Trans.prototype.setStatusBarNumData = function () {
    if (void 0 === trans.project) return !1;
    try {
      $(".footer .footer3 span").html(
        "rows : " + trans.project.files[trans.getSelectedId()].data.length
      );
    } catch (e) {
      $(".footer .footer3 span").html("");
    }
  }),
  (Trans.prototype.setStatusBarEngine = function () {
    if (void 0 === trans.project) return !1;
    try {
      var e = "";
      trans.project.parser &&
        (e = `/<span title='parser'>${trans.project.parser}</span>`),
        $(".footer .footer4 span").html(trans.project.gameEngine + e);
    } catch (e) {
      $(".footer .footer4 span").html("");
    }
  }),
  (Trans.prototype.setTrayIcon = function (e) {
    e = e || "translatorPlusPlus";
    var t = $('<i class="icon trayIcon"></i>');
    t.addClass(e), $(".footer .footer5 span").html(t);
  }),
  (Trans.prototype.goToNewKey = function () {
    if (0 == Array.isArray(this.data)) return !1;
    this.grid.scrollViewportTo(this.data.length - 1),
      this.grid.selectCell(this.data.length - 1, 0);
  }),
  (Trans.prototype.clearEditor = function () {
    var e = $("#currentCellText");
    return (
      e.val(""),
      e.prop("readonly", !0),
      e.data("column", null),
      e.data("row", null),
      !0
    );
  }),
  (Trans.prototype.clearCellInfo = function () {
    return $("#currentCoordinate").val(""), !0;
  }),
  (Trans.prototype.setCellInfo = function (e, t) {
    $("#currentCoordinate").val(e + 1 + "," + (t + 1)),
      (trans.lastSelectedCell = [e, t]);
  }),
  (Trans.prototype.drawCellEmblem = function () {
    var e = this.lastSelectedCell[0],
      t = this.lastSelectedCell[1];
    $(".cellEmblems > i").addClass("hidden"),
      t != this.keyColumn &&
        ($(".cellEmblems > .emblemComment").attr("title", ""),
        this.isOrganicCell(e, t) &&
          $(".cellEmblems > .emblemOrganic").removeClass("hidden"),
        (this.isVisitedCell(e, t)
          ? $(".cellEmblems > .emblemFootprint")
          : $(".cellEmblems > .emblemFirstVisit")
        ).removeClass("hidden"),
        (e = this.getCellComment(e, t))) &&
        ($(".cellEmblems > .emblemComment").removeClass("hidden"),
        $(".cellEmblems > .emblemComment").attr(
          "title",
          "<b>Cell comment:</b><br />" + e
        ));
  }),
  (Trans.prototype.connectData = function () {
    return this.getSelectedId() && this.project.files[this.getSelectedId()].data
      ? void (this.project.files[this.getSelectedId()].data = trans.data)
      : console.warn("unable to connect data with selected id");
  }),
  (Trans.prototype.isLastRow = function (e) {
    return (
      0 == Boolean(trans.data) && ((trans.data = []), trans.connectData()),
      (e = e || 0) == trans.data.length - 1
    );
  }),
  (Trans.prototype.getCurrentData = function () {
    return this.data;
  }),
  (Trans.prototype.getTextFromLastSelected = function () {
    var e = this.getCurrentData();
    return empty(this.lastSelectedCell)
      ? ""
      : e[this.lastSelectedCell[0]][this.lastSelectedCell[1]];
  }),
  (Trans.prototype.textEditorSetValue = function (e, t = !1) {
    $("#currentCellText").val(e),
      ui.generateBackgroundNumber(),
      t && $("#currentCellText").trigger("change");
  }),
  (Trans.prototype.doAfterSelection = function (e, t, n, r) {
    var o = $("#currentCellText"),
      a = (o.val(trans.data[e][t]), o.prop("readonly", !1), trans.isLastRow(e));
    if (
      (0 == t && 0 == a && o.prop("readonly", !0),
      o.data("column", t),
      o.data("row", e),
      trans.setCellInfo(e, t),
      trans.setStatusBarContext(e),
      trans.translateSelectedRow(e),
      ui.generateBackgroundNumber(o),
      "undefined" != typeof romaji)
    ) {
      if (0 == trans.config.loadRomaji) return !0;
      romaji.resolve(trans.data[e][0], $("#currentRomaji .text"));
    }
    $("#currentRomaji .header").text(this.getRowInfoText(e, !0) || ""),
      this.drawCellEmblem(),
      this.getOption("gridInfo")?.isRuleActive &&
        this.getOption("gridInfo")?.enableTrail &&
        (this._cellInfoTrack && clearTimeout(this._cellInfoTrack),
        t != this.keyColumn) &&
        this.getText(e, t) &&
        (this._cellInfoTrack = setTimeout(() => {
          clearTimeout(this._cellInfoTrack),
            (this._cellInfoTrack = void 0),
            console.log("Setting cellInfo", "v", 1, this.getSelectedId(), e, t),
            this.cellInfo.set("v", 1, this.getSelectedId(), e, t),
            $(`table tbody td[data-coord="${e}-${t}"]`).addClass("viewed");
        }, 1e3)),
      (this.getSelectedObject().lastSelectedCell = [e, t]),
      this.trigger("onAfterSelectCell", {
        fromRow: e,
        fromCol: t,
        toRow: n,
        toCol: r,
        isLastRow: a,
      });
  }),
  (Trans.prototype.resetCurentCellEditor = function () {
    var e = $("#currentCellText");
    e.val(""),
      e.data("row", 0),
      e.data("column", 0),
      trans.setCellInfo(0, 0),
      trans.setStatusBarContext(0),
      $("#currentRomaji .text").text(""),
      $("#currentRomaji .header").text("");
  }),
  (Trans.prototype.createFile = function (e, n, r) {
    ((r = r || {}).originalFormat = r.originalFormat || ""),
      (r.type = r.type || null);
    var o = require("is-valid-path");
    return (
      (n = n || "/"),
      o(e)
        ? o(n) || "*" === n
          ? ((o = nwPath.join("/", n, e)),
            this.getObjectById(o)
              ? { error: !0, msg: o + t(" is already exist") }
              : ((r =
                  "*" == n
                    ? ((o = e),
                      (r.type = r.type || "reference"),
                      this.createFileData(o, {
                        originalFormat:
                          r.originalFormat || "TRANSLATOR++ GENERATED TABLE",
                        type: r.type,
                        dirname: "*",
                      }))
                    : ((o = o.replace(/\\/g, "/")),
                      this.createFileData(o, {
                        originalFormat: r.originalFormat,
                        type: r.type,
                      }))),
                (trans.project.files[o] = r),
                trans.addFileItem(o, r),
                this.evalTranslationProgress(),
                ui.fileList.reIndex(),
                ui.initFileSelectorDragSelect(),
                {}))
          : { error: !0, msg: n + t(" is not a valid directory name") }
        : { error: !0, msg: e + t(" is not a valid object name") }
    );
  }),
  (Trans.prototype.selectFile = function (e, t) {
    ((t = t || {}).onDone = t.onDone || void 0), this.grid.deselectCell();
    t = (e =
      "string" == typeof e
        ? $(".fileList [data-id=" + common.escapeSelector(e) + "]")
        : e)
      .closest("li")
      .data("id");
    return (
      this.trigger("beforeSelectFile", [trans?.project?.selectedId, t]),
      e.closest(".tree").find("li").removeClass("selected"),
      e.closest("li").addClass("selected"),
      (trans.project.selectedId = t),
      (trans.data = trans.project.files[t].data),
      (trans.selectedData = trans.project.files[t]),
      trans.buildIndex(),
      trans.clearCellInfo(),
      trans.clearEditor(),
      trans.setStatusBarNumData(),
      trans.resetCurentCellEditor(),
      $(".menu-button.addNote").hasClass("checked") && ui.openFileNote(),
      $(".fileId").val(t),
      ui.disableGrid(!1),
      ui.evalFileNoteIcon(),
      this.trigger("objectSelected", t),
      this.grid.loadData(trans.data),
      trans.loadComments(),
      trans.renderGridInfo(),
      trans.grid.setFixedTableHeightByData(trans.data),
      trans.grid.scrollViewportTo(0, 0),
      e
    );
  }),
  (Trans.prototype.renderGridInfo = function () {
    var e = this.getOption("gridInfo") || {};
    e?.isRuleActive && e?.rowHeaderInfo
      ? ((e = e.rowHeaderWidth || 130),
        trans.grid.updateSettings({ rowHeaderWidth: e }),
        $("#table").css("--row-header-width", e + "px"))
      : (trans.grid.updateSettings({ rowHeaderWidth: null }),
        (e = $('#table [data-role="tablecorner"]').outerWidth()),
        $("#table").css("--row-header-width", e + "px"));
  }),
  (Trans.prototype.addFileGroup = function (e, t) {
    return (
      $("#fileList [data-group='" + CSS.escape(e) + "']").length < 1 &&
      ((e = $(
        "<li class='group-header'  data-group='" + e + "'>" + e + "</li>"
      )),
      0 < $("#fileList .fileListUl .group-header[data-group='*']").length
        ? $("#fileList .fileListUl .group-header[data-group='*']").before(e)
        : $("#fileList .fileListUl").append(e),
      !0)
    );
  }),
  (Trans.prototype.fileItemExist = function (e, t) {
    return (
      0 <
      $(
        "#fileList [data-group='" +
          CSS.escape(t.dirname) +
          "'][data-id='" +
          CSS.escape(e) +
          "']"
      ).length
    );
  }),
  (Trans.prototype.drawFileStatus = function (o) {
    "string" == typeof o && (o = [o]);
    for (var a = $("#fileList"), i = 0; i < o.length; i++)
      (() => {
        var e,
          t = o[i],
          n = this.getObjectById(t),
          r = a.find(`[data-id="${CSS.escape(o[i])}"]`);
        0 != r.length &&
          (r.removeClass("isCompleted"),
          r.removeClass("isRequireAttention"),
          n.isCompleted && r.addClass("isCompleted"),
          n.isRequireAttention && r.addClass("isRequireAttention"),
          r.data("noteTooltipIsActive") &&
            (r.tooltip("destroy"), r.data("noteTooltipIsActive", !1)),
          (t = r.find(".markers")).empty(),
          n.note) &&
          (t.append($('<span class="hidden"></span>').text(n.note)),
          (e = $('<i class="icon-commenting"></i>')),
          t.append(e),
          n.noteColor && e.css("color", n.noteColor),
          r.tooltip({
            content: function () {
              var e = $("<div class='fileObjTooltipWindow'></div>");
              return (
                n.noteColor &&
                  (e.css("border-left-color", n.noteColor),
                  e.addClass("hasColor")),
                e.text(n.note),
                e.on("mouseenter", function () {
                  ui.fileObjectTooltip.open(e.clone(), r);
                }),
                e
              );
            },
            tooltipClass: "fileObjTooltipWrapper",
            show: { effect: "fade", duration: 100 },
            hide: { effect: "none", delay: 100 },
            position: { my: "left top", at: "right+6 top-16", of: r },
            open: function (e, t) {},
          }),
          r.data("noteTooltipIsActive", !0));
      })();
  }),
  (Trans.prototype.addFileItem = function (e, t) {
    if (this.fileItemExist(e, t)) return !1;
    this.addFileGroup(t.dirname);
    var n = $("<li></li>");
    n.append(
      "<input type='checkbox' class='fileCheckbox' title='hold shift for bulk selection' /><a href='#' class='filterable'><span class='filename'></span><span class='markers'></span><span class='percent' title='progress'></span><div class='progress' title='progress'></div></a>"
    ),
      n.attr("title", e),
      n.attr("data-group", t.dirname),
      n.find(".fileCheckbox").attr("value", e),
      n.find(".filename").text(t.filename),
      n.addClass("data-selector"),
      n.data("id", e),
      n.attr("data-id", e),
      n.find("a").on("mousedown", function (e) {
        if (2 == e.which) return e.preventDefault(), trans.clearSelection(), !1;
      }),
      n.find("a").on("dblclick", function (e) {
        var t = $(this).closest("li").find(".fileCheckbox");
        t.prop("checked", !t.prop("checked")).trigger("change");
      }),
      n.find("a").on("click", function (e) {
        e.preventDefault(), trans.selectFile($(this).closest("li"));
      }),
      n.find(".fileCheckbox").on("change", function () {
        1 == $(this).prop("checked")
          ? ((trans.$lastCheckedFile = $(this)),
            $(this).closest(".data-selector").addClass("hasCheck"))
          : ((trans.$lastCheckedFile = void 0),
            $(this).closest(".data-selector").removeClass("hasCheck"));
      }),
      n.find(".fileCheckbox").on("mousedown", function (e) {
        if (
          (console.log("mouse down", console.log($(this).closest("li"))),
          (async () => {
            await common.wait(200),
              $(this).closest("li").removeClass("ds-hover");
          })(),
          !trans.$lastCheckedFile)
        )
          return !1;
        if (e.shiftKey) {
          console.log("The SHIFT key was pressed!");
          var t,
            n = $(".fileList .fileCheckbox"),
            e = n.index(trans.$lastCheckedFile),
            r = n.index(this),
            o = e < r ? ((t = e), r) : ((t = r), e);
          console.log("check from index " + t + " to " + o);
          for (var a = t; a < o; a++)
            n.eq(a).prop("checked", !0).trigger("change");
        }
      }),
      $("#fileList [data-group='" + CSS.escape(t.dirname) + "']")
        .last()
        .after(n);
  }),
  (Trans.prototype.drawFileSelector = function () {
    if (void 0 === this.project.files) return !1;
    for (var e in ($("#fileList .fileListUl").empty(),
    this.generateNewDictionaryTable(),
    this.project.files))
      this.addFileItem(e, this.project.files[e]);
    this.drawFileStatus(this.getAllFiles()),
      this.setStatusBarEngine(),
      this.evalTranslationProgress(),
      ui.fileList.reIndex(),
      ui.initFileSelectorDragSelect(),
      ui.enableButtons(),
      this.renderGridInfo();
    var t = require("www/js/TranslationByContext.js");
    (ui.translationByContext = new t()),
      ui.ribbonMenu.select("home"),
      (this.inProject = !0),
      engines.current().triggerHandler("onLoadTrans", this, arguments),
      this.initLocalStorage(),
      this.trigger("onLoadTrans");
  }),
  (Trans.prototype.initLocalStorage = async function () {
    var e = trans?.project?.projectId || "global";
    this.localStorage = new (require("better-localstorage"))("tp" + e);
  }),
  (Trans.prototype.unInitLocalStorage = async function () {
    "function" == typeof this.localStorage?.db?.close &&
      (await this.localStorage.db.close()),
      (this.localStorage = void 0);
  }),
  (Trans.prototype.setMarkAsComplete = function (e, t) {
    (t = t || trans.getCheckedFiles()).length < 1 && (t = trans.getAllFiles());
    for (var n = 0; n < t.length; n++) {
      var r = t[n];
      this.getObjectById(r).isCompleted = e;
    }
    return this.drawFileStatus(t), !0;
  }),
  (Trans.prototype.selectAll = function (t, e) {
    (e = e || !1), "string" == typeof (t = t || []) && (t = [t]);
    var n = $("#fileList .fileCheckbox");
    0 == t.length
      ? n.each(function () {
          $(this).prop("checked", !0).trigger("change");
        })
      : (e || n.prop("checked", !1).trigger("change"),
        n.each(function () {
          var e = $(this);
          t.includes(e.closest("li").data("id")) &&
            e.prop("checked", !0).trigger("change");
        }));
  }),
  (Trans.prototype.selectObjectsByFilter = function (t) {
    var e = $("#fileList .fileCheckbox");
    "function" == typeof t &&
      e.each(function () {
        var e = $(this);
        t(e.closest("li").data("id"), e) &&
          e.prop("checked", !0).trigger("change");
      });
  }),
  (Trans.prototype.invertSelection = function () {
    $("#fileList .fileCheckbox").each(function () {
      $(this).prop("checked", !$(this).prop("checked")).trigger("change");
    });
  }),
  (Trans.prototype.clearSelection = function () {
    $("#fileList .fileCheckbox").each(function () {
      $(this).prop("checked", !1).trigger("change");
    });
  }),
  (Trans.prototype.initFileNav = function () {
    console.log("running trans.initFileNav");
    try {
      void 0 !== trans.project.files
        ? (trans.fileListLoaded = !0)
        : (trans.fileListLoaded = !1);
    } catch (e) {
      trans.fileListLoaded = !1;
    }
    if (0 == trans.fileListLoaded)
      return (
        trans.createProject({
          onAfterLoading: function () {
            trans.drawFileSelector();
          },
        }),
        !1
      );
    this.unInitFileNav(),
      trans.drawFileSelector(),
      this.onFileNavLoaded.call(this),
      this.trigger("transLoaded", this);
  }),
  (Trans.prototype.unInitFileNav = function () {
    $("#fileList .fileListUl").empty(),
      ui.fileList.reIndex(),
      this.onFileNavUnloaded.call(this),
      engines.handler("onUnloadTrans").apply(this, arguments),
      ui.ribbonMenu.clear(),
      ui.disableButtons(),
      this.trigger("onUnloadTrans");
  }),
  (Trans.prototype.evalTranslationProgress = function (e, t) {
    e = e || [];
    var n,
      r = t || trans.countTranslated(e) || {};
    for (n in r) {
      var o = $(".fileList [data-id=" + common.escapeSelector(n) + "]");
      o.find(".percent").text(Math.round(r[n].percent)),
        o
          .find(".progress")
          .css(
            "background",
            "linear-gradient(to right, #3159f9 0%,#3159f9 " +
              r[n].percent +
              "%,#ff0004 " +
              r[n].percent +
              "%,#ff0004 100%)"
          );
    }
  }),
  (Trans.prototype.getStats = function (e) {
    var t = {
        files: 0,
        folders: 0,
        progress: 0,
        words: 0,
        characters: 0,
        rows: 0,
        rowTranslated: 0,
        percent: 0,
        organic: 0,
      },
      n = !1;
    if (this.project && this.project.files) {
      for (var r in (e ||
        (this.project.stats && ((n = !0), (t = this.project.stats))),
      this.project.files)) {
        var o = this.project.files[r];
        if (
          "TRANSLATOR++ GENERATED TABLE" != o.originalFormat &&
          (t.files++,
          o.progress &&
            ((t.rows += o.progress.length),
            (t.rowTranslated += o.progress.translated)),
          !n && !empty(o.data))
        )
          for (var a = 0; a < o.data.length; a++) {
            var i = o.data[a];
            empty(i) ||
              (i[this.keyColumn] &&
                ((t.characters += i[this.keyColumn].length),
                (t.words += i[this.keyColumn].trim().split(/\s+/).length),
                "HU" == this.cellInfo.getBestCellInfo(r, a, "t")) &&
                t.organic++);
          }
      }
      0 < t.rows && (t.percent = (t.rowTranslated / t.rows) * 100),
        (t.folders = $(".fileList  .group-header").length - 1),
        (t.organicPercent = (t.organic / t.rowTranslated) * 100),
        (this.stats = t);
    }
    return t;
  }),
  (Trans.prototype.setFileNoteColor = function (e, t) {
    for (var n in ((t ||= this.getSelectedId()),
    (t = 0 == Array.isArray(t) ? [t] : t))) {
      n = this.getObjectById(t[n]);
      e ? (n.noteColor = e) : n.noteColor && delete n.noteColor;
    }
    this.drawFileStatus(t), ui.evalFileNoteIcon();
  }),
  (Trans.prototype.setFileNote = function (e, t) {
    for (var n in ((t ||= this.getSelectedId()),
    (t = 0 == Array.isArray(t) ? [t] : t)))
      this.getObjectById(t[n]).note = e;
    this.drawFileStatus(t), ui.evalFileNoteIcon(), ui.fileList.reIndex();
  }),
  (Trans.prototype.loadComments = function () {
    trans.grid.comment = trans.grid.comment || trans.grid.getPlugin("comments");
    var e,
      t = trans.getSelectedObject();
    if (!t) return !1;
    if (void 0 === t.comments) return !1;
    for (e in t.comments)
      for (var n in t.comments[e])
        trans.grid.comment.setCommentAtCell(
          parseInt(e),
          parseInt(n),
          t.comments[e][n]
        );
  }),
  (Trans.prototype.runCustomScript = async function (e, n, r) {
    console.log("Running custom script with arguments:", arguments),
      (r = r || {});
    var o = new (require("www/js/CodeRunner.js"))(),
      a = await common.fileGetContents(n);
    if (!a) return alert(t("Error opening file :" + n));
    await ui.showBusyOverlay(), await common.wait(200);
    try {
      var i = await o.run(a, e, r);
      i && alert(i);
    } catch (e) {
      alert(t("Error executing :") + nwPath.basename(n) + "\n" + e.toString());
    }
    await ui.hideBusyOverlay();
  }),
  (Trans.prototype.updateRunScriptMenu = function () {
    console.log("Updating run script menu"),
      (this.fileSelectorMenu = this.fileSelectorMenu || {}),
      (this.fileSelectorMenu.withSelected.items.runScript.items.forEachRowRun.items =
        {});
    var a =
        this.fileSelectorMenu.withSelected.items.runScript.items.forEachRowRun
          .items,
      i = sys.getConfig("codeEditor/rowIterator");
    i || sys.setConfig("codeEditor/rowIterator", { quickLaunch: [] }),
      ((i ||= {}).quickLaunch ||= []);
    for (let n = 0; n < i.quickLaunch.length; n++)
      (() => {
        var r = i.quickLaunch[n],
          o = common.getFilename(r),
          e = common.generateId();
        a[e] = {
          name: o,
          callback: (e, n) => {
            confirm(
              t("Are you sure want to execute the following script?") + "\n" + o
            ) && this.runCustomScript("rowIterator", r);
          },
        };
      })();
    0 < Object.keys(a).length
      ? ((a.sep0 = "---------"),
        (a.clearQuickLaunch = {
          name: t("Clear quick launch"),
          icon: "context-menu-icon icon-trash",
          callback: (e, n) => {
            confirm(t("Are you sure want to clear quick launch?")) &&
              (sys.setConfig("codeEditor/rowIterator", { quickLaunch: [] }),
              sys.saveConfig(),
              this.updateRunScriptMenu());
          },
        }))
      : (a.howToAdd = {
          name: t("How to add Automation here"),
          icon: "context-menu-icon icon-help",
          callback: (e, t) => {
            nw.Shell.openExternal(
              "https://dreamsavior.net/docs/translator/execute-script/pin-your-automation-to-quickly-launch-from-translator/"
            );
          },
        }),
      (this.fileSelectorMenu.withSelected.items.runScript.items.forEachObjectRun.items =
        {});
    var s =
        this.fileSelectorMenu.withSelected.items.runScript.items
          .forEachObjectRun.items,
      l = sys.getConfig("codeEditor/objectIterator");
    l ||
      (sys.setConfig("codeEditor/objectIterator", { quickLaunch: [] }),
      (l = sys.getConfig("codeEditor/objectIterator"))),
      (l.quickLaunch = l.quickLaunch || []);
    for (let n = 0; n < l.quickLaunch.length; n++)
      (() => {
        var r = l.quickLaunch[n],
          o = common.getFilename(r),
          e = common.generateId();
        s[e] = {
          name: o,
          callback: (e, n) => {
            confirm(
              t("Are you sure want to execute the following script?") + "\n" + o
            ) && this.runCustomScript("objectIterator", r);
          },
        };
      })();
    0 < Object.keys(s).length
      ? ((s.sep0 = "---------"),
        (s.clearQuickLaunch = {
          name: t("Clear quick launch"),
          icon: "context-menu-icon icon-trash",
          callback: (e, n) => {
            confirm(t("Are you sure want to clear quick launch?")) &&
              (sys.setConfig("codeEditor/objectIterator", { quickLaunch: [] }),
              sys.saveConfig(),
              this.updateRunScriptMenu());
          },
        }))
      : (s.howToAdd = {
          name: t("How to add Automation here"),
          icon: "context-menu-icon icon-help",
          callback: (e, t) => {
            nw.Shell.openExternal(
              "https://dreamsavior.net/docs/translator/execute-script/pin-your-automation-to-quickly-launch-from-translator/"
            );
          },
        });
  }),
  (Trans.prototype.updateRunScriptGridMenu = function () {
    this.gridContextMenu.runAutomation.submenu = { items: [] };
    var n = this.gridContextMenu.runAutomation.submenu.items,
      a = sys.getConfig("codeEditor/gridSelection");
    a ||
      (sys.setConfig("codeEditor/gridSelection", { quickLaunch: [] }),
      (a = sys.getConfig("codeEditor/gridSelection"))),
      (a.quickLaunch = a.quickLaunch || []);
    for (var i = 0; i < a.quickLaunch.length; i++)
      (() => {
        var r = a.quickLaunch[i],
          o = (console.log("Adding context menu", r), common.getFilename(r)),
          e = common.generateId();
        n.push({
          name: o,
          key: "runAutomation:" + e,
          callback: (e, n) => {
            confirm(
              t("Are you sure want to execute the following script?") + "\n" + o
            ) && this.runCustomScript("gridSelection", r);
          },
        });
      })();
  }),
  (Trans.prototype.fileSelectorContextMenuInit = function () {
    console.log("trans.fileSelectorContextMenuInit");
    var a = this;
    if (
      ((this.fileSelectorMenu = {
        selectAll: {
          name: t("Select all"),
          icon: "context-menu-icon icon-check2-all",
        },
        clearSelection: { name: t("Clear selection") },
        selectCompleted: { name: t("Select 100%") },
        selectIncompleted: { name: t("Select <100%") },
        selectProgressGT: { name: t("Select progress ≥ ...") },
        selectMarkedAsCompleted: { name: t("Select completed") },
        invertSelection: { name: t("Invert selection") },
        sep0: "---------",
        markCompleteCurrent: {
          name: t("Toggle mark as complete"),
          icon: function () {
            return "context-menu-icon icon-ok";
          },
        },
        sep1: "---------",
        withSelected: {
          name: () => {
            var e = $(".fileCheckbox:checked").length;
            return 0 == e
              ? ((a.fileSelectorMenu.withSelected.icon =
                  "context-menu-icon icon-docs-1"),
                (a.fileSelectorMenu.withSelected.items.deleteFiles.visible =
                  !1),
                t("With all"))
              : t("With ") + e + t(" selected");
          },
          icon: function () {
            return "context-menu-icon icon-check";
          },
          items: {
            markComplete: {
              name: t("Mark as complete"),
              icon: "context-menu-icon icon-ok",
            },
            unsetMarkComplete: { name: t("Un-mark as complete") },
            "sep0-0": "---------",
            batchTranslation: {
              name: t("Batch translation"),
              icon: "context-menu-icon icon-language",
            },
            sendTo: {
              name: t("Send to..."),
              icon: "context-menu-icon icon-share-ios-line",
              items: {},
            },
            "sep0-1": "---------",
            wrapText: {
              name: t("Wrap texts"),
              icon: "context-menu-icon icon-wordwrap",
            },
            trim: { name: t("Trim"), icon: "context-menu-icon icon-article" },
            padding: {
              name: t("Auto padding"),
              icon: "context-menu-icon icon-list-nested",
            },
            createScript: {
              name: t("Create Automation"),
              icon: "context-menu-icon icon-code",
              items: {
                forEachObject: {
                  name: t("For each object"),
                  icon: "context-menu-icon icon-doc",
                },
                forEachRow: {
                  name: t("For each row"),
                  icon: "context-menu-icon icon-menu-1",
                },
              },
            },
            runScript: {
              name: t("Run Automation"),
              icon: "context-menu-icon icon-play",
              items: {
                forEachObjectRun: {
                  name: t("For each object"),
                  icon: "context-menu-icon icon-doc",
                  items: {},
                },
                forEachRowRun: {
                  name: () => (
                    console.log("rendering for each row"), t("For each row")
                  ),
                  icon: "context-menu-icon icon-menu-1",
                  items: {},
                },
              },
            },
            "sep0-2": "---------",
            import: {
              name: t("Import from..."),
              icon: "context-menu-icon icon-login",
              items: {
                importFromTrans: {
                  name: t("Trans File"),
                  icon: "context-menu-icon icon-tpp",
                },
                importFromSheet: {
                  name: t("Spreadsheets"),
                  icon: "context-menu-icon icon-file-excel",
                },
                importFromRPGMTransPatch: {
                  name: t("RPGMTransPatch Files"),
                  icon: "context-menu-icon icon-doc-text",
                },
              },
            },
            export: {
              name: t("Export into..."),
              icon: "context-menu-icon icon-export",
              items: {
                exportToGamePatch: {
                  name: t("A folder"),
                  icon: () => "context-menu-icon icon-folder-add",
                },
                exportToGamePatchZip: {
                  name: t("Zipped Game Patch"),
                  icon: () => "context-menu-icon icon-file-archive",
                },
                exportToCsv: {
                  name: t("Comma Separated Value (csv)"),
                  icon: () => "context-menu-icon icon-file-excel",
                },
                exportToXlsx: {
                  name: t("Excel 2007 Spreadsheets (xlsx)"),
                  icon: () => "context-menu-icon icon-file-excel",
                },
                exportToXls: {
                  name: t("Excel Spreadsheets (xls)"),
                  icon: () => "context-menu-icon icon-file-excel",
                },
                exportToOds: {
                  name: t("ODS Spreadsheets"),
                  icon: () => "context-menu-icon icon-file-excel",
                },
                exportToHtml: {
                  name: t("Html Spreadsheets"),
                  icon: () => "context-menu-icon icon-file-code",
                },
                exportToTransPatch: {
                  name: t("RMTrans Patch"),
                  icon: () => "context-menu-icon icon-doc-text",
                },
              },
            },
            inject: {
              name: t("Inject Translation"),
              icon: "context-menu-icon icon-download",
            },
            revert: {
              name: t("Revert to original"),
              icon: "context-menu-icon icon-ccw",
            },
            "sep0-3": "---------",
            clearTranslationSel: {
              name: t("Clear translation"),
              icon: "context-menu-icon icon-eraser",
            },
            deleteFiles: {
              name: t("Delete files"),
              icon: "context-menu-icon icon-trash-empty",
            },
          },
        },
        sep2: "---------",
        properties: {
          name: t("Properties"),
          icon: "context-menu-icon icon-cog",
        },
      }),
      a.fileSelectorContextMenuIsInitialized)
    )
      return !1;
    $.contextMenu({
      selector: ".fileList .data-selector",
      events: { preShow: function (e, t) {}, hide: function (e, t) {} },
      build: function (e, n) {
        return (
          a.updateRunScriptMenu(),
          {
            zIndex: 1e3,
            callback: function (e, n) {
              switch (e) {
                case "selectAll":
                  a.selectAll();
                  break;
                case "clearSelection":
                  a.clearSelection();
                  break;
                case "invertSelection":
                  a.invertSelection();
                  break;
                case "selectCompleted":
                  a.selectAll(a.getAllCompletedFiles());
                  break;
                case "selectIncompleted":
                  a.selectAll(a.getAllIncompletedFiles());
                  break;
                case "selectProgressGT":
                  let n = prompt(t("Select progress greater than"), "0");
                  isNaN(n)
                    ? alert(t("Please input a number"))
                    : a.selectObjectsByFilter((e, t) => {
                        e = a.getObjectById(e);
                        return (
                          !!e.progress &&
                          (e.progress.translated / e.progress.length) * 100 >=
                            parseInt(n)
                        );
                      });
                  break;
                case "selectMarkedAsCompleted":
                  a.selectAll(a.getAllMarkedAsCompleted());
                  break;
                case "markCompleteCurrent":
                  var r = $("#fileList .context-menu-active"),
                    o = !r.hasClass("isCompleted"),
                    r = r.data("id");
                  a.setMarkAsComplete(o, [r]);
                  break;
                case "markComplete":
                  a.setMarkAsComplete(!0);
                  break;
                case "unsetMarkComplete":
                  a.setMarkAsComplete(!1);
                  break;
                case "batchTranslation":
                  ui.translateAllDialog();
                  break;
                case "forEachObject":
                  ui.openAutomationEditor("codeEditor_objectIterator", {
                    workspace: "objectIterator",
                  });
                  break;
                case "forEachRow":
                  ui.openAutomationEditor("codeEditor_rowIterator", {
                    workspace: "rowIterator",
                  });
                  break;
                case "clearTranslationSel":
                  (o = confirm(t("Do you want to clear translation?"))),
                    (r = a.getCheckedFiles());
                  o &&
                    a.removeAllTranslation(a.getCheckedFiles(), {
                      refreshGrid: !0,
                    }),
                    a.evalTranslationProgress(r);
                  break;
                case "clearTranslationAll":
                  (o = confirm(t("Do you want to clear translation?"))),
                    (r = a.getAllFiles());
                  o &&
                    a.removeAllTranslation(a.getAllFiles(), {
                      refreshGrid: !0,
                    }),
                    a.evalTranslationProgress(r);
                  break;
                case "deleteFiles":
                  ui.deleteFiles();
                  break;
                case "wrapText":
                  ui.batchWrapingDialog();
                  break;
                case "trim":
                  ui.openTrimWindow();
                  break;
                case "padding":
                  ui.openPaddingWindow();
                  break;
                case "properties":
                  ui.openFileProperties();
                  break;
                case "importFromSheet":
                  ui.openImportSpreadsheetDialog();
                  break;
                case "importFromTrans":
                  $("#importTrans").trigger("click");
                  break;
                case "importFromRPGMTransPatch":
                  ui.openImportRPGMTransDialog();
                  break;
                case "exportToGamePatch":
                  $("#dialogExport").data("options", {
                    files: a.getCheckedFiles(),
                  }),
                    $("#exportDir").trigger("click");
                  break;
                case "exportToGamePatchZip":
                  $("#dialogExport").data("options", {
                    files: a.getCheckedFiles(),
                  }),
                    $("#export").trigger("click");
                  break;
                case "exportToCsv":
                  $("#exportCSV").trigger("click");
                  break;
                case "exportToXlsx":
                  $("#dialogExport").data("options", {
                    files: a.getCheckedFiles(),
                  }),
                    $("#exportXLSX").trigger("click");
                  break;
                case "exportToXls":
                  $("#dialogExport").data("options", {
                    files: a.getCheckedFiles(),
                  }),
                    $("#exportXLS").trigger("click");
                  break;
                case "exportToOds":
                  $("#dialogExport").data("options", {
                    files: a.getCheckedFiles(),
                  }),
                    $("#exportODS").trigger("click");
                  break;
                case "exportToHtml":
                  $("#dialogExport").data("options", {
                    files: a.getCheckedFiles(),
                  }),
                    $("#exportHTML").trigger("click");
                  break;
                case "exportToTransPatch":
                  $("#dialogExport").data("options", {
                    files: a.getCheckedFiles(),
                  }),
                    $("#exportTrans").trigger("click");
                  break;
                case "inject":
                  ui.openInjectDialog();
                  break;
                case "revert":
                  a.revertToOriginal();
              }
            },
            items: a.fileSelectorMenu,
          }
        );
      },
    }),
      (a.fileSelectorContextMenuIsInitialized = !0);
  }),
  (Trans.prototype.gridBodyContextMenu = function () {
    $.contextMenu({
      selector: ".ht_master .htCore tbody, .ht_clone_left .htCore tbody",
      events: {
        preShow: function (e, t) {
          t = $(t.target);
          console.log(t),
            t.hasClass("highlight") && console.log("previously hightlighted"),
            console.log(arguments);
        },
        show: function (e, t) {
          console.log("selection on show : "),
            (trans.grid.lastContextMenuCellRange =
              trans.grid.getSelectedRange());
        },
        hide: function (e, t) {
          if (
            (console.log("reload selection : "),
            void 0 === trans.grid.lastContextMenuCellRange)
          )
            return !1;
          trans.grid.selectCells(trans.grid.lastContextMenuCellRange),
            console.log(trans.grid.getSelectedRange());
        },
      },
      build: function (e, n) {
        return {
          zIndex: 1e3,
          callback: function (e, t) {
            switch (e) {
              case "addComment":
                var n = void 0;
                try {
                  n = trans.grid.lastContextMenuCellRange[0].highlight;
                } catch (e) {}
                trans.editNoteAtCell(n);
                break;
              case "removeComment":
                trans.removeNoteAtSelected(trans.grid.lastContextMenuCellRange);
            }
          },
          items: {
            addComment: {
              name: t("Add comment"),
              icon: function () {
                return "context-menu-icon icon-commenting-o";
              },
            },
            removeComment: {
              name: t("Remove comment"),
              icon: function () {
                return "context-menu-icon icon-comment-empty";
              },
            },
            selectAll: { name: t("Select all") },
            invertSelection: { name: t("Invert selection") },
            sep0: "---------",
            withSelected: {
              name: "With all",
              items: {
                batchTranslation: { name: t("Batch translation") },
                wordWrap: { name: t("Wrap texts") },
              },
            },
          },
        };
      },
    });
  }),
  (Trans.prototype.evalContextsQuery = function () {
    if (0 == arguments.length) return !1;
    for (var e, t = [], n = 0; n < arguments.length; n++)
      "string" == typeof arguments[n]
        ? 0 != arguments[n].length &&
          ((e = arguments[n].split("\n").map(function (e) {
            return common.stripCarriageReturn(e);
          })),
          (t = t.concat(e)))
        : Array.isArray(arguments[n]) &&
          0 != arguments[n].length &&
          (t = t.concat(arguments[n]));
    return t;
  }),
  (Trans.prototype.isInContext = function (e, t, n) {
    if (0 == (n = n || []).length) return !0;
    if (
      ("string" == typeof n && (n = [n]),
      void 0 !== trans.project.files[e] &&
        void 0 !== trans.project.files[e].context[t])
    )
      for (
        var r = trans.project.files[e].context[t],
          o = (r =
            (r = 0 == Array.isArray(r) ? [r] : r).length < 1 &&
            void 0 !== trans.project.files[e].parameters[t]
              ? [
                  trans.buildContextFromParameter(
                    trans.project.files[e].parameters[t]
                  ),
                ]
              : r).join("\n"),
          a = 0;
        a < n.length;
        a++
      )
        if (-1 != (o = o.toLowerCase()).indexOf(n[a].toLowerCase())) return !0;
    return !1;
  }),
  (Trans.prototype.removeRowByContext = function (e, t, n, r) {
    (n = n || {}).matchAll = n.matchAll || !1;
    var o,
      a = trans.travelContext(e, t, {
        onMatch: function (e, t) {},
        matchAll: n.matchAll,
      });
    for (o in a)
      for (var i = a[o].length - 1; 0 <= i; i--)
        ((1 == a[o][i] && !0 !== r) || (1 != a[o][i] && !0 === r)) &&
          (console.log(
            "removing " +
              o +
              " row " +
              i +
              (!0 === r ? " (Not on whitelist)" : "")
          ),
          trans.removeRow(o, i));
    trans.refreshGrid();
  }),
  (Trans.prototype.collectContextKeyword = function (t, n, e) {
    if (void 0 === (t = t || trans.project)) return !1;
    if ((n = "string" == typeof (n = n || []) ? [n] : n).length < 1)
      for (var r in trans.project.files) n.push(r);
    var o = {};
    for (let e = 0; e < n.length; e++)
      for (var a = n[e], i = t.files[a].context, s = 0; s < i.length; s++)
        if (0 != Array.isArray(i[s]))
          for (var l = 0; l < i[s].length; l++)
            for (var c = (i[s][l] || "").split("/"), d = 0; d < c.length; d++)
              isNaN(c[d]) && ((o[c[d]] = o[c[d]] || 0), (o[c[d]] += 1));
    return o;
  }),
  (Trans.prototype.travelContext = function (t, n, r) {
    if (
      ((t = t || []),
      (n = n || []),
      ((r = r || {}).onMatch = r.onMatch || function () {}),
      (r.onNotMatch = r.onNotMatch || function () {}),
      (r.matchAll = r.matchAll || !1),
      "string" == typeof t && (t = [t]),
      0 == Array.isArray(n) && (n = [n]),
      t.length < 1)
    )
      for (var e in trans.project.files) t.push(e);
    var o = {};
    for (let e = 0; e < t.length; e++) {
      var a = t[e];
      o[a] = [];
      for (let e = 0; e < trans.project.files[a].context.length; e++) {
        var i = trans.project.files[a].context[e];
        if (
          (0 == Array.isArray(i) && (i = [i]), (o[a][e] = !1), i.length < 1)
        ) {
          if (!trans.project.files[a].parameters[e]) continue;
          i = [
            trans.buildContextFromParameter(
              trans.project.files[a].parameters[e]
            ),
          ];
        }
        for (var s = 0; s < i.length; s++)
          for (var l = i[s], c = 0; c < n.length; c++)
            r.matchAll
              ? common.matchAllWords(l, n[c]) && (o[a][e] = !0)
              : 0 <= l.toLowerCase().indexOf(n[c].toLowerCase()) &&
                (o[a][e] = !0);
      }
      for (let e = 0; e < o[a].length; e++)
        (1 == o[a][e] ? r.onMatch : r.onNotMatch).call(
          trans.project.files[a],
          a,
          e
        );
    }
    return o;
  }),
  (Trans.prototype.isOrganicCell = function (e, t, n) {
    return (
      !!this.project &&
      ((n ||= this.getSelectedId()), "HU" == this.cellInfo.getCell(n, e, t)?.t)
    );
  }),
  (Trans.prototype.isVisitedCell = function (e, t, n) {
    return (
      !!this.project &&
      ((n ||= this.getSelectedId()), Boolean(this.cellInfo.get("v", n, e, t)))
    );
  }),
  (Trans.prototype.getData = function (e) {
    return void 0 === e
      ? this.getCurrentData()
      : "string" == typeof e
      ? this.getObjectById(e).data
      : "object" == typeof e && Array.isArray(e.data)
      ? e.data
      : (console.warn("invalid id or object ", e), []);
  }),
  (Trans.prototype.addRow = function (e, t, n) {
    var r,
      o,
      e =
        "object" == typeof e
          ? e
          : ((e = e || this.getSelectedId()), this.getObjectById(e));
    return (
      (e.indexIds ||= {}),
      "string" == typeof t && t
        ? ((r = this.getIndexByKey(e, t)),
          console.log("Existing index is", r),
          void 0 !== r
            ? r
            : (((r = Array(trans.colHeaders.length).fill(null))[
                this.keyColumn
              ] = t),
              n && (r[1] = n),
              console.log("inserting row:", r),
              (n = trans.getData(e)),
              console.log("theData", n),
              empty(n[n.length - 1][0])
                ? ((n[(o = n.length - 1)] = r), (e.indexIds[t] = o))
                : ((o = n.push(r)), (e.indexIds[t] = o - 1), o)))
        : -1
    );
  }),
  (Trans.prototype.appendRow = function (e, t = []) {
    e =
      "object" == typeof e
        ? e
        : ((e = e || this.getSelectedId()), this.getObjectById(e));
    if (((e.indexIds ||= {}), 0 == Array.isArray(t))) return -1;
    if (t.length < 1) return -1;
    var n = t[this.keyColumn];
    if ("string" != typeof n) return -1;
    if (!n) return -1;
    var r = this.getIndexByKey(e, n);
    if ((console.log("Existing index is", r), void 0 !== r)) return r;
    t.length = trans.colHeaders.length;
    var o,
      r = common.clone(t),
      t = trans.getData(e);
    return (
      console.log("theData", t),
      empty(t[t.length - 1][0])
        ? ((t[(o = t.length - 1)] = r), (e.indexIds[n] = o))
        : ((o = t.push(r)), (e.indexIds[n] = o - 1), o)
    );
  }),
  (Trans.prototype.getIndexIds = function (e) {
    var t;
    return "string" == typeof (e = void 0 === e ? this.getSelectedId() : e)
      ? (t = this.getObjectById(e))
        ? (t.indexIsBuilt || this.buildIndex(e), t.indexIds)
        : {}
      : "object" == typeof e
      ? (t = (t = e).indexIsBuilt ? t : this.buildIndexFromData(t)).indexIds
      : (console.warn("Error getting Index ID for file:", e), {});
  }),
  (Trans.prototype.getIndexByKey = function (e, t) {
    return this.getIndexIds(e)[t];
  }),
  (Trans.prototype.isAllSelected = function () {
    return (
      trans.getCheckedFiles().length == Object.keys(trans.project.files).length
    );
  }),
  (Trans.prototype.getActiveTranslator = function () {
    return trans.project
      ? ((trans.project.options = trans?.project.options || {}),
        trans.project?.options?.translator || sys.config.translator)
      : sys.config?.translator;
  }),
  (Trans.prototype.appendTextToReference = function (e) {
    var n, r;
    return (
      !!this.isInProject() &&
      "string" == typeof e &&
      (e.trim()
        ? trans.isKeyExistOn(e, "Common Reference")
          ? trans.alert(
              "Unable to add <b>" +
                e +
                "</b>. That value already exist on Common Reference!"
            )
          : ((r =
              (n = trans.project.files["Common Reference"]).data.length - 1),
            0 == Boolean(n.data[r][0])
              ? (console.log("inserting to ref.data[lastKey][0]"),
                (n.data[r][0] = e),
                (n.indexIds[e] = r))
              : (console.log("append new data"),
                ((r = (r = new Array(trans.colHeaders.length)).fill(null))[0] =
                  e),
                n.data.push(r),
                (n.indexIds[e] = n.data.length - 1)),
            trans.alert("<b>" + e + "</b> " + t("added to reference table!")),
            !0)
        : trans.alert(
            "Cannot add empty text to reference. Please try again with a text selected, or use <b>CTRL+SHIFT+D</b> to add the selected row into reference."
          ))
    );
  }),
  (Trans.prototype.appendSelectedRowToReference = function () {
    var n = common.gridSelectedRows();
    if (this.isInProject()) {
      if (!n?.length) return this.alert("No row selected.");
      if (!this.getObjectById("Common Reference"))
        return this.alert(
          "This project don't have <b>Common Reference</b> file. Please create one first."
        );
      let t = 0;
      for (let e = 0; e < n.length; e++)
        -1 < this.appendRow("Common Reference", this.getData()[e]) && t++;
      return this.alert(t + " row(s) added to Common Reference."), !0;
    }
  }),
  (Trans.prototype.wordWrapFiles = function (e, n, r, o) {
    if (
      (0 == (e = "string" == typeof (e = e || []) ? [e] : e).length &&
        (e = this.getAllFiles()),
      (n = n || 1),
      0 == (r = r || n + 1))
    )
      return trans.alert(t("Can not modify Column 0"));
    ((o = o || {}).maxLength = o.maxLength || 41),
      (o.onDone = o.onDone || function () {}),
      (o.context = o.context || []);
    for (var a = 0; a < e.length; a++) {
      var i = e[a];
      if (
        (console.log("Wordwrapping file : " + i),
        void 0 !== trans.project.files[i])
      ) {
        o.lineBreak = o.lineBreak || trans.project.files[i].lineBreak || "\n";
        for (var s = trans.project.files[i].data, l = 0; l < s.length; l++)
          trans.isInContext(i, l, o.context) &&
            ("string" != typeof s[l][n] && (s[l][r] = s[l][n]),
            (s[l][r] = common.wordwrapLocale(
              s[l][n],
              o.maxLength,
              this.getTl(),
              o.lineBreak
            )));
      }
    }
    o.onDone.call(trans);
  }),
  (Trans.prototype.fillEmptyLine = function (e, t, n, r, o) {
    "string" == typeof (e = e || []) && (e = [e]),
      ((o = o || {}).project = o.project || trans.project),
      (o.keyColumn = o.keyColumn || 0),
      (o.lineFilter =
        o.lineFilter ||
        function () {
          return !0;
        }),
      (o.fromKeyOnly = o.fromKeyOnly || !1),
      (o.filterTag = o.filterTag || []),
      (o.overwrite = o.overwrite || !1),
      o.fromKeyOnly &&
        (console.warn("collecting data from key only"),
        (o.sourceCol = r || o.keyColumn)),
      "number" == typeof (t = t || []) && (t = [t]),
      0 == e.length && (e = trans.getAllFiles()),
      console.log(e);
    for (var a = 0; a < e.length; a++) {
      var i = e[a];
      if (!(0 < t.length))
        for (var s = o.project.files[i].data, l = 0; l < s.length; l++) {
          if ("blacklist" == o.filterTagMode) {
            if (this.hasTags(o.filterTag, l, i)) continue;
          } else if (
            "whitelist" == o.filterTagMode &&
            !this.hasTags(o.filterTag, l, i)
          )
            continue;
          (void 0 === n &&
            null == (n = trans.getTranslationColFromRow(s[l]))) ||
            (0 == o.overwrite && s[l][n]) ||
            (o.project.files[i].data[l][n] = trans.getTranslationByLine(
              s[l],
              o.keyColumn,
              {
                includeIndex: !0,
                priorityCol: n,
                onBeforeLineAdd: o.lineFilter,
                sourceCol: o.sourceCol,
              }
            ));
        }
    }
  }),
  (Trans.prototype.trimTranslation = function (e, t, n) {
    if (!trans.project) return !1;
    (e = e || trans.getSelectedId()),
      ((n = n || {}).refreshGrid = n.refreshGrid || !1),
      0 == Array.isArray(e) && (e = [e]),
      0 == Array.isArray(t) && (t = [t]);
    for (var r = 0; r < e.length; r++)
      for (
        var o = e[r],
          a = trans.project.files[o].data,
          i = trans.project.files[o].lineBreak || "\n",
          s = 0;
        s < a.length;
        s++
      )
        for (var l in t) {
          var c,
            l = t[l];
          l < 1 ||
            ("string" == typeof trans.project.files[o].data[s][l] &&
              ((c = trans.project.files[o].data[s][l]
                .split("\n")
                .map(function (e) {
                  return e.trim();
                })),
              (trans.project.files[o].data[s][l] = c.join(i))));
        }
    trans.refreshGrid();
  }),
  (Trans.prototype.paddingTranslation = function (e, t, n) {
    if (!trans.project) return !1;
    (e = e || trans.getSelectedId()),
      ((n = n || {}).keyId = n.keyId || 0),
      (n.includeInitialWhitespace = n.includeInitialWhitespace || !1),
      (n.refreshGrid = n.refreshGrid || !1),
      0 == Array.isArray(e) && (e = [e]),
      0 == Array.isArray(t) && (t = [t]);
    for (var r = /^[\s\u0009\u200b\u180e\u2060]+/g, o = 0; o < e.length; o++)
      for (
        var a = e[o],
          i = trans.project.files[a].data,
          s = trans.project.files[a].lineBreak || "\n",
          l = 0;
        l < i.length;
        l++
      )
        if ("string" == typeof trans.project.files[a].data[l][n.keyId]) {
          for (
            var c,
              d = trans.project.files[a].data[l][n.keyId].split(s),
              g = [],
              f = 0;
            f < d.length;
            f++
          ) {
            var u = d[f].match(r);
            0 == Boolean(u) && (u = ""), g.push(u);
          }
          for (c in t) {
            var p = t[c];
            if (
              !(p < 1) &&
              "string" == typeof trans.project.files[a].data[l][p]
            ) {
              for (
                var h = trans.project.files[a].data[l][p].split(s),
                  m = [],
                  y = 0;
                y < h.length;
                y++
              ) {
                var v = g[y] || "";
                n.includeInitialWhitespace
                  ? m.push(v + h[y])
                  : m.push(v + h[y].trim());
              }
              trans.project.files[a].data[l][p] = m.join(s);
            }
          }
        }
    trans.refreshGrid();
  }),
  (Trans.prototype.removeAllTranslation = function (e, t) {
    if (!trans.project) return !1;
    (e = e || trans.getSelectedId()),
      ((t = t || {}).refreshGrid = t.refreshGrid || !1),
      0 == Array.isArray(e) && (e = [e]);
    for (var n = 0; n < e.length; n++)
      for (
        var r = e[n], o = trans.project.files[r].data, a = 0;
        a < o.length;
        a++
      )
        for (var i = 1; i < o[a].length; i++)
          trans.project.files[r].data[a][i] = null;
    this.trigger("removeAllTranslation", { files: e, options: t }),
      t.refreshGrid && trans.refreshGrid();
  }),
  (Trans.prototype.deleteFile = function (e, n) {
    if (!trans.project) return !1;
    if (
      ((e = e || trans.getSelectedId()),
      (e = 0 == Array.isArray(e) ? [e] : e).length < 1)
    )
      return !0;
    for (var r = 0; r < e.length; r++) {
      var o,
        a = e[r];
      "reference" == trans.project.files[a].type
        ? alert(t("Unable to delete table : ") + a)
        : (a == trans.getSelectedId() && ui.disableGrid(!0),
          (o = JSON.parse(JSON.stringify(trans.project.files[a]))),
          (trans.project.trash = trans.project.trash || {}),
          (trans.project.trash[a] = o),
          $(
            ".panel-left .fileList [data-id=" + common.escapeSelector(a) + "]"
          ).remove(),
          delete trans.project.files[a]);
    }
    ui.fileList.reIndex(), this.trigger("afterDeleteFile", [e]);
  }),
  (Trans.prototype.stagingFilesRemove = async function (e) {
    Array.isArray(e) || (e = [e]);
    var t = this.getStagingPath();
    if (!t) return [];
    var n,
      r = [];
    for (n in e) {
      var o = nwPath.join(t, "data", e[n]);
      console.log("Removing", o),
        (await common.isFileAsync(o)) || console.log("Not found:", o),
        r.push(await common.unlink(e[n]));
    }
    return r;
  }),
  (Trans.prototype.removeRow = function (e, t, n) {
    if ((console.log("removing row : ", arguments), void 0 === e)) return !1;
    if (void 0 === t) return !1;
    (t = (t = 0 === t ? [0] : t) || []),
      (n = n || {}),
      0 == Array.isArray(t) && (t = [t]),
      (n.permanent = n.permanent || !1),
      (n.refreshGrid = n.refreshGrid || !1),
      (t = common.arrayUnique(t)).sort(function (e, t) {
        return t - e;
      }),
      console.log("Removing rows > should be ordered descendingly:", t);
    for (var r = 0; r < t.length; r++) {
      var o,
        a = t[r];
      void 0 === trans.project.files[e].data[a] ||
        (trans.project.files[e].data.splice(a, 1),
        trans.project.files[e].parameters &&
          trans.project.files[e].parameters.splice(a, 1),
        trans.project.files[e].context &&
          trans.project.files[e].context.splice(a, 1),
        trans.project.files[e].tags && trans.project.files[e].tags.splice(a, 1),
        this.cellInfo.deleteRow(e, a),
        (o = this.getObjectById(e).comments),
        empty(o)) ||
        (Array.isArray(o) ? o.splice(a, 1) : delete o[a]);
    }
    0 < t.length && (trans.project.files[e].indexIsBuilt = !1),
      this.trigger("afterRemoveRow", { file: e, rows: t, options: n }),
      n.refreshGrid && trans.refreshGrid();
  }),
  (Trans.prototype.clearRow = function (e, t, n = {}) {
    if ((e = "string" == typeof e ? trans.getObjectById(e) : e)) {
      if ("object" != typeof e || !Array.isArray(e.data))
        return console.warn("Invalid argument 1");
      Array.isArray(t) || (t = [t]), (n ||= {});
      for (var r = 0, o = 0; o < t.length; o++)
        for (var a = e.data[t[o]], i = 0; i < a.length; i++)
          i != this.keyColumn && ((a[i] = ""), r++);
      return r;
    }
  }),
  (Trans.prototype.removeColumn = function (e, n) {
    if (0 === e) return trans.alert(t("Can not remove key column!"));
    if (
      (((n = n || {}).permanent = n.permanent || !1),
      (n.refreshGrid = n.refreshGrid || !1),
      void 0 === trans.project)
    )
      return trans.alert(t("Please open or create a project first"));
    for (var r in trans.project.files)
      if (
        0 != Array.isArray(trans.project.files[r].data) &&
        0 != trans.project.files[r].data.length
      )
        for (var o = 0; o < trans.project.files[r].data.length; o++)
          trans.project.files[r].data[o].splice(e, 1),
            this.cellInfo.deleteCell(r, o, e);
    trans.colHeaders.splice(e, 1),
      trans.columns.splice(e, 1),
      n.refreshGrid && trans.refreshGrid();
  }),
  (Trans.prototype.renameColumn = function (e, n, r) {
    return 0 === e
      ? trans.alert(t("Can not set column name to blank!"))
      : (((r = r || {}).refreshGrid = r.refreshGrid || !1),
        void 0 !== trans.colHeaders[e] &&
          ((trans.colHeaders[e] = n),
          void (r.refreshGrid && trans.refreshGrid())));
  }),
  (Trans.prototype.rowHasMultipleContext = function (e, t) {
    return (
      !!(t = t || this.getSelectedObject()).context &&
      !(!t.context[e] || t.context[e].length <= 1)
    );
  }),
  (Trans.prototype.isTranslatedRow = function (e, t) {
    t = t || trans.data;
    for (var n = 1; n < t[e].length; n++)
      if (0 < (t[e][n] || "").length) return !0;
    return !1;
  }),
  (Trans.prototype.countFilledCol = function (e, t) {
    t = t || trans.data;
    for (var n = 0, r = 1; r < t[e].length; r++)
      0 < (t[e][r] || "").length && n++;
    return n;
  }),
  (Trans.prototype.getTranslationFromRow = function (t, n, r = []) {
    if (((r ||= []), 0 == Array.isArray(t))) return !1;
    if (0 == (n = n || 0)) {
      for (let e = t.length; 0 < e; e--)
        if (!r.includes(e) && t[e]) return t[e];
    } else
      for (let e = t.length; 0 <= e; e--)
        if (e != n && !r.includes(e) && t[e]) return t[e];
    return null;
  }),
  (Trans.prototype.getTranslationColFromRow = function (t, n) {
    if (0 == Array.isArray(t)) return !1;
    if (0 == (n = n || 0)) {
      for (let e = t.length; e > n; e--) if (t[e]) return e;
    } else for (let e = t.length; 0 <= e; e--) if (e != n && t[e]) return e;
    return null;
  }),
  (Trans.prototype.getTranslationByLine = function (t, e, n) {
    if (0 == Array.isArray(t)) return !1;
    ((n = n || {}).includeIndex = n.includeIndex || !1),
      (n.lineBreak = n.lineBreak || "\n"),
      (n.onBeforeLineAdd =
        n.onBeforeLineAdd ||
        function () {
          return !0;
        });
    var r = [];
    if (void 0 !== n.sourceCol) {
      var o = (t[n.sourceCol] || "").split("\n").map(function (e) {
        return common.stripCarriageReturn(e);
      });
      for (let e = 0; e < o.length; e++)
        0 != Boolean(o[e]) && n.onBeforeLineAdd(o[e]) && (r[e] = o[e]);
    } else
      for (let e = 0; e < t.length; e++)
        if (0 != e && (void 0 === n.priorityCol || e != n.priorityCol)) {
          var a = (t[e] || "").split("\n").map(function (e) {
            return common.stripCarriageReturn(e);
          });
          for (let e = 0; e < a.length; e++)
            0 != Boolean(a[e]) && n.onBeforeLineAdd(a[e]) && (r[e] = a[e]);
        }
    if (n.includeIndex) {
      var i = (t[0] || "").split("\n").map(function (e) {
        return common.stripCarriageReturn(e);
      });
      for (let e = 0; e < i.length; e++)
        0 != Boolean(i[e]) && n.onBeforeLineAdd(i[e]) && (r[e] = i[e]);
    }
    if (void 0 !== n.priorityCol)
      for (
        var s = (t[n.priorityCol] || "").split("\n").map(function (e) {
            return common.stripCarriageReturn(e);
          }),
          l = 0;
        l < s.length;
        l++
      )
        0 != Boolean(s[l]) && (r[l] = s[l]);
    return r.join(n.lineBreak);
  }),
  (Trans.prototype.generateTranslationPair = function (e, t) {
    if (((t = t || 0), 0 == Array.isArray(e))) return {};
    for (var n, r = {}, o = 0; o < e.length; o++)
      0 != Boolean(e[o][0]) &&
        null != (n = trans.getTranslationFromRow(e[o], t)) &&
        (r[e[o][0]] = n);
    return r;
  }),
  (Trans.prototype.getProgressColumnIndices = function () {
    var t = sys.getConfig("progressColumnIndices");
    if (t) {
      let e = t.replaceAll(" ", "").split(",");
      return (
        (e = e.map(function (e) {
          return parseInt(e);
        })),
        common.arrayUnique(e)
      );
    }
  }),
  (Trans.prototype.countTranslated = function (e) {
    0 == (e = "string" == typeof (e = e || []) ? [e] : e).length &&
      (e = this.getAllFiles());
    for (
      var t = this.getProgressColumnIndices(),
        n = (console.log("Progress column indices", t), {}),
        r = 0;
      r < e.length;
      r++
    ) {
      var o = this.project.files[e[r]].data;
      n[e[r]] = { translated: 0, length: 0, percent: 100 };
      for (var a = 0; a < o.length; a++)
        if (0 != Boolean(o[a][this.keyColumn])) {
          if (
            ((o[a][this.keyColumn] = o[a][this.keyColumn] || ""),
            (o[a][this.keyColumn] = o[a][this.keyColumn] + ""),
            this.lineByLineMode)
          ) {
            try {
              var i = o[a][0].split("\n").length;
            } catch (e) {
              throw (
                (console.error(
                  "Error when trying to split key string ",
                  o[a][0]
                ),
                e)
              );
            }
            for (var s = 1; s < o[a].length; s++)
              if (0 != Boolean(o[a][s]))
                if (
                  ("string" != typeof o[a][s] && (o[a][s] = o[a][s] + ""),
                  (o[a][s] = o[a][s] || ""),
                  i <= o[a][s].split("\n").length)
                ) {
                  n[e[r]].translated++;
                  break;
                }
          } else
            this.rowHasTranslation(o[a], this.keyColumn, t) &&
              n[e[r]].translated++;
          n[e[r]].length++;
        }
      0 < n[e[r]].length &&
        (n[e[r]].percent = (n[e[r]].translated / n[e[r]].length) * 100),
        100 < n[e[r]].percent && (n[e[r]].percent = 100),
        n[e[r]].percent < 0 && (n[e[r]].percent = 0),
        (this.project.files[e[r]].progress = n[e[r]]);
    }
    return n;
  }),
  (Trans.prototype.resetIndex = function (e) {
    for (var t in this.project.files) this.project.files[t].indexIsBuilt = !1;
  }),
  (Trans.prototype.buildIndex = function (e, t, n) {
    if (
      ((e = e || trans.getSelectedId()), (n = n || trans.keyColumn || 0), e)
    ) {
      var r = trans.project.files[e];
      if (r.indexIsBuilt && !0 !== t) return r.indexIds;
      var o = {};
      for (let e = 0; e < r.data.length; e++)
        void 0 !== r.data[e] &&
          null != r.data[e][n] &&
          "" != r.data[e][n] &&
          void 0 !== r.data[e][n] &&
          (o[r.data[e][n]] = e);
      return (
        (r.indexIds = o),
        (r.indexIsBuilt = !0),
        e == trans.getSelectedId() &&
          ((trans.indexIds = r.indexIds),
          (trans.indexIsBuilt = r.indexIsBuilt)),
        o
      );
    }
    if (!trans.indexIsBuilt || !0 === t) {
      for (let e = 0; e < trans.data.length; e++)
        void 0 !== trans.data[e] &&
          null != trans.data[e][n] &&
          "" != trans.data[e][n] &&
          void 0 !== trans.data[e][n] &&
          (trans.indexIds[trans.data[e][n]] = e);
      trans.indexIsBuilt = !0;
    }
    return trans.indexIds;
  }),
  (Trans.prototype.buildIndexes = function (n, e = !1, r = {}) {
    if (
      ((r ||= {}).customFilter,
      (r.indexId ||= ""),
      (this.customIndexes ||= {}),
      "function" == typeof r.customFilter)
    ) {
      console.log("Generating custom index mode");
      try {
        if ("string" != typeof r.customFilter("test"))
          return console.error(
            "Invalid customFilter. Custom filter should return string"
          );
      } catch (e) {
        return console.error(
          "Invalid customFilter. Custom filter should return string"
        );
      }
      r.indexId = "#auto.fn." + common.crc32String(r.customFilter.toString());
    }
    r.indexId && (this.customIndexes[r.indexId] = {}),
      0 == (n = (n = "string" == typeof n ? [n] : n) || []).length &&
        (n = this.getAllFiles());
    var o = {};
    if (e) {
      for (let t = 0; t < n.length; t++) {
        var a = this.getObjectById(n[t]);
        if (a) {
          a.indexIsBuilt || this.buildIndex(n[t]);
          var i,
            s = this.getObjectById(n[t]).indexIds;
          for (i in s)
            for (
              var l = i.replaceAll("\r", "").split("\n"), c = 0;
              c < l.length;
              c++
            ) {
              let e = l[c];
              (o[
                (e =
                  "function" == typeof r.customFilter ? r.customFilter(e) : e)
              ] = o[e] || []),
                o[e].push({ file: n[t], row: s[i], line: c });
            }
        }
      }
      r.indexId ? (this.customIndexes[r.indexId] = o) : (this._tempIndexes = o);
    } else {
      console.log("Files is", n);
      for (let e = 0; e < n.length; e++) {
        console.log("handling file:", n[e]);
        var t = this.getObjectById(n[e]);
        if ((console.log("ThisObject:", t), t)) {
          t.indexIsBuilt || this.buildIndex(n[e]);
          var d,
            g = this.getObjectById(n[e]).indexIds;
          for (d in g) {
            o[
              (d = "function" == typeof r.customFilter ? r.customFilter(d) : d)
            ] = o[d] || [];
            var f,
              u = { file: n[e], row: g[d] };
            o[d].push(u),
              d.includes("\r") &&
                r.stripCarriageReturn &&
                ((o[(f = d.replaceAll("\r", ""))] = o[f] || []), o[f].push(u));
          }
        }
      }
      r.indexId ? (this.customIndexes[r.indexId] = o) : (this._tempIndexes = o),
        console.log("Indexes is", o);
    }
    return o;
  }),
  (Trans.prototype.getFromIndexes = function (e, t, n) {
    return (
      "function" == typeof n &&
        ((n = "#auto.fn." + common.crc32String(n.toString())),
        this.customIndexes[n]) &&
        this.customIndexes[n][e],
      (t = t || this._tempIndexes || {})[e]
    );
  }),
  (Trans.prototype.clearTemporaryIndexes = function (e) {
    e
      ? "string" == typeof e
        ? this.customIndexes[e] && delete this.customIndexes[e]
        : "function" == typeof e &&
          ((e = "#auto.fn." + common.crc32String(e.toString())),
          this.customIndexes[e]) &&
          delete this.customIndexes[e]
      : delete this.customIndexes,
      (this._tempIndexes = void 0);
  }),
  (Trans.prototype.findIdByIndex = function (e, t) {
    return (
      null != trans.data &&
      "" != trans.data &&
      void 0 !== trans.data &&
      (void 0 === t
        ? (void 0 === trans.indexIds && trans.buildIndex(),
          void 0 !== trans.indexIds[e] && trans.indexIds[e])
        : (0 == trans.project.files[t].indexIsBuilt && trans.buildIndex(t),
          void 0 === trans.project.files[t].indexIds && trans.buildIndex(t),
          void 0 !== trans.project.files[t].indexIds[e] &&
            trans.project.files[t].indexIds[e]))
    );
  }),
  (Trans.prototype.getClearOnNextHumanInteract = function (e) {
    return (
      (this._clearOnNextHumanInteract = this._clearOnNextHumanInteract || {}),
      e
        ? ((this._clearOnNextHumanInteract[e] =
            this._clearOnNextHumanInteract[e] || {}),
          this._clearOnNextHumanInteract[e])
        : this._clearOnNextHumanInteract
    );
  }),
  (Trans.prototype.getRowIdByTextInsensitive = function (e, t) {
    if (null == this.data || "" == this.data || void 0 === this.data) return !1;
    if (!t) throw "second argument fileId is required!";
    var n = this.getClearOnNextHumanInteract("insensitiveIndex_" + t),
      r = this.getData(t),
      o = (e) => (e ? common.trimRightParagraph(e).toLowerCase() : "");
    if (empty(n))
      for (var a = 0; a < r.length; a++) n[o(r[a][this.keyColumn])] = a;
    return n[o(e)];
  }),
  (Trans.prototype.copyTranslationToRow = function (e, t, n) {
    if ((console.log("copyTranslationToRow", arguments), void 0 === e))
      return !1;
    if (
      (void 0 !== e.files && (e = e.files),
      (t = t || n.targetColumn || 1),
      ((n = n || {}).files = n.files || []),
      (n.mode = n.mode || ""),
      (n.fetch = n.fetch || ""),
      (n.filterTag = n.filterTag || []),
      (n.filterTagMode = n.filterTagMode || ""),
      (n.overwrite = n.overwrite || !1),
      0 == Array.isArray(n.files) && (n.files = [n.files]),
      0 == n.files.length)
    )
      for (var r in e) n.files.push(r);
    for (var o = 0; o < n.files.length; o++) {
      var a = n.files[o];
      if ((console.log("Handling", a), 0 != Boolean(e[a])))
        for (var i = trans.getObjectById(a), s = 0; s < e[a].data.length; s++) {
          var l,
            c = e[a].data[s];
          0 == Boolean(c[0]) ||
            empty(i.data[s]) ||
            (0 == n.overwrite && Boolean(i.data[s][t])) ||
            ((l = trans.getTranslationFromRow(c)),
            0 == Boolean(l) && (l = c[0]),
            (i.data[s][t] = l));
        }
    }
  }),
  (Trans.prototype.generateContextTranslationPair = function (t, n) {
    if ((console.log("Entering trans.generateTranslationTable"), void 0 === t))
      return !1;
    void 0 !== t.files && (t = t.files),
      console.log("obj files inside trans.generateTranslationTable :"),
      console.log(t);
    var r = {};
    if (
      (((n = n || {}).files = n.files || []),
      (n.mode = n.mode || ""),
      (n.fetch = n.fetch || ""),
      (n.filterTag = n.filterTag || []),
      (n.filterTagMode = n.filterTagMode || ""),
      0 == Array.isArray(n.files) && (n.files = [n.files]),
      0 == n.files.length)
    )
      for (var e in t) n.files.push(e);
    console.log("Worked option files : "), console.log(n.files);
    for (let e = 0; e < n.files.length; e++) {
      var o = n.files[e];
      if (0 != Boolean(t[o]))
        for (var a = 0; a < t[o].context.length; a++)
          if (0 != Boolean(t[o].context[a]) && 0 != Boolean(t[o].data[a])) {
            var i = trans.getTranslationFromRow(t[o].data[a]);
            if (
              (0 == Boolean(i) && (i = t[o].data[a][trans.keyColumn]),
              0 != Boolean(i))
            )
              for (var s = 0; s < t[o].context[a].length; s++)
                r[t[o].context[a][s]] = i;
          }
    }
    return console.log("translation table collection is : "), console.log(r), r;
  }),
  (Trans.prototype.generateTranslationTable = function (t, n) {
    if ((console.log("Entering trans.generateTranslationTable"), void 0 === t))
      return !1;
    void 0 !== t.files && (t = t.files),
      console.log("obj files inside trans.generateTranslationTable :"),
      console.log(t);
    var r = {};
    if (
      (((n = n || {}).files = n.files || []),
      (n.caseSensitive = n.caseSensitive || !1),
      (n.mode = n.mode || ""),
      (n.fetch = n.fetch || ""),
      (n.filterTag = n.filterTag || []),
      (n.filterTagMode = n.filterTagMode || ""),
      0 == Array.isArray(n.files) && (n.files = [n.files]),
      0 == n.files.length)
    )
      for (var e in t) n.files.push(e);
    if (
      (console.log("Worked option files : "),
      console.log(n.files),
      "linebyline" == n.mode.toLowerCase())
    )
      for (let e = 0; e < n.files.length; e++) {
        var o = n.files[e];
        console.log(o);
        for (var a = 0; a < t[o].data.length; a++)
          if (0 != Boolean(t[o].data[a][0])) {
            if ("blacklist" == n.filterTagMode) {
              if (this.hasTags(n.filterTag, a, o)) continue;
            } else if (
              "whitelist" == n.filterTagMode &&
              !this.hasTags(n.filterTag, a, o)
            )
              continue;
            var i = trans.getTranslationFromRow(t[o].data[a]);
            if ("untranslated" == n.fetch) {
              if (1 == Boolean(i)) continue;
            } else if ("both" != n.fetch && 0 == Boolean(i)) continue;
            for (
              var s = t[o].data[a][0].split("\n"),
                l = (i = i || "").split("\n").map(function (e) {
                  return (e = e || "").replaceAll(/\r/g, "");
                }),
                c = 0;
              c < s.length;
              c++
            ) {
              if ("untranslated" == n.fetch) {
                if (1 == Boolean(l[c])) continue;
              } else if ("both" != n.fetch && 0 == Boolean(l[c])) continue;
              r[s[c]] = l[c] || "";
            }
          }
      }
    else
      for (let e = 0; e < n.files.length; e++) {
        var d,
          g = n.files[e];
        if (0 != Boolean(t[g]))
          for (let e = 0; e < t[g].data.length; e++)
            0 != Boolean(t[g].data[e][0]) &&
              ((d = trans.getTranslationFromRow(t[g].data[e])),
              0 != Boolean(d)) &&
              (r[t[g].data[e][0]] = d);
      }
    return console.log("translation table collection is : "), console.log(r), r;
  }),
  (Trans.prototype.generateTranslationTableLine = function (t, n) {
    if (
      (console.log("Entering trans.generateTranslationTableLine", t, n),
      void 0 === t)
    )
      return !1;
    void 0 !== t.files && (t = t.files),
      console.log("obj files inside trans.generateTranslationTable :"),
      console.log(t);
    var r = {};
    ((n = n || {}).files = n.files || []),
      (n.caseSensitive = n.caseSensitive || !1),
      (n.mode = n.mode || ""),
      (n.fetch = n.fetch || ""),
      (n.keyColumn = n.keyColumn || 0),
      (n.filterTag = n.filterTag || []),
      (n.filterTagMode = n.filterTagMode || ""),
      (n.ignoreTranslated = n.ignoreTranslated || !1),
      (n.overwrite = n.overwrite || !1),
      (n.collectAddress = n.collectAddress || !1);
    try {
      n.filterLanguage = n.filterLanguage || this.getSl() || "ja";
    } catch (e) {
      n.filterLanguage = "ja";
    }
    if (
      ((n.ignoreLangCheck = n.ignoreLangCheck || !1),
      console.log("ignore language check?"),
      console.log(n.ignoreLangCheck),
      0 == Array.isArray(n.files) && (n.files = [n.files]),
      0 == n.files.length)
    )
      for (var e in t) n.files.push(e);
    console.log("Worked option files : "), console.log(n.files);
    var o = {};
    for (let e = 0; e < n.files.length; e++) {
      var a = n.files[e];
      console.log("fetching translatable data from:", a);
      for (let e = 0; e < t[a].data.length; e++)
        if (0 != Boolean(t[a].data[e][n.keyColumn])) {
          if ("blacklist" == n.filterTagMode) {
            if (this.hasTags(n.filterTag, e, a)) continue;
          } else if (
            "whitelist" == n.filterTagMode &&
            !this.hasTags(n.filterTag, e, a)
          )
            continue;
          if (
            !(
              (n.ignoreTranslated &&
                this.rowHasTranslation(t[a].data[e], n.keyColumn)) ||
              (0 == n.overwrite &&
                n.targetColumn &&
                t[a].data[e][n.targetColumn])
            )
          ) {
            console.log("Reached here!");
            for (
              var i = trans.getTranslationFromRow(t[a].data[e], n.keyColumn, [
                  0,
                ]),
                s =
                  (console.log("current translation", i),
                  t[a].data[e][n.keyColumn].split("\n")),
                l = (i = i || "").split("\n").map(function (e) {
                  return (e = e || "").replaceAll(/\r/g, "");
                }),
                c = 0;
              c < s.length;
              c++
            ) {
              if ("untranslated" == n.fetch) {
                if (1 == Boolean(l[c])) continue;
              } else if ("both" != n.fetch && 0 == Boolean(l[c])) continue;
              (0 == n.ignoreLangCheck &&
                0 == common.isInLanguage(s[c], n.filterLanguage)) ||
                ((r[s[c]] = l[c] || ""),
                n.collectAddress &&
                  ((o[s[c]] ||= []),
                  o[s[c]].push({
                    line: c,
                    file: a,
                    row: e,
                    rowObj: t[a].data[e],
                  })));
            }
          }
        }
    }
    return (
      console.log("result is : "),
      console.log(r),
      console.log("addresses:", o),
      n.collectAddress ? { pairs: r, addresses: o } : r
    );
  }),
  (Trans.prototype.generateTranslationTableFromStrings = function (t, e, n) {
    n = n || {};
    try {
      n.filterLanguage = n.filterLanguage || this.getSl() || "ja";
    } catch (e) {
      n.filterLanguage = "ja";
    }
    var r;
    n.ignoreLangCheck = n.ignoreLangCheck || !1;
    try {
      r = n.ignoreLangCheck || e.getOptions("ignoreLangCheck");
    } catch (e) {
      r = !1;
    }
    "string" == typeof t && (t = [t]);
    var o = { include: {}, exclude: {} };
    if ("rowByRow" == n.mode)
      for (let e = 0; e < t.length; e++)
        "string" != typeof t[e] ||
          t[e].length < 1 ||
          (r || 0 != common.isInLanguage(t[e], n.filterLanguage)
            ? (o.include[t[e]] = "")
            : (o.exclude[t[e]] = t[e]));
    else
      for (let e = 0; e < t.length; e++)
        if ("string" == typeof t[e] && !(t[e].length < 1))
          for (
            var a = t[e].replaceAll("\r", "").split("\n"), i = 0;
            i < a.length;
            i++
          ) {
            if (n.ignoreWhitespace) {
              if (!a[i]) continue;
              if (!a[i].trim()) continue;
            }
            r && 0 == common.isInLanguage(a[i], n.filterLanguage)
              ? (o.exclude[a[i]] = a[i])
              : (o.include[a[i]] = "");
          }
    return o;
  }),
  (Trans.prototype.generateTranslationTableFromResult = function (e, t, n) {
    for (var r = n || {}, o = 0; o < e.length; o++)
      void 0 !== t[o] && (r[e[o]] = t[o]);
    return r;
  }),
  (Trans.prototype.generateSelectedTranslationTable = function (e, t, n) {
    (e = e || this.grid.getSelectedRange() || [[]]),
      (t = t || this.getSelectedId());
    for (
      var r = common.gridSelectedCells(e), o = this.getData(t), a = {}, i = 0;
      i < r.length;
      i++
    ) {
      var s = r[i].row,
        l = r[i].col,
        c = o[s][this.keyColumn];
      (a[c] = a[c] || []),
        a[c].push({ col: l, row: s, value: o[s][l], file: t });
    }
    return a;
  }),
  (Trans.prototype.wordWrapText = function (t, n = [], r = [], o = "\n") {
    if (!empty(r) && !empty(n)) {
      if (window.langTools?.isCJK(this.getTl()))
        for (let e = 0; e < r.length; e++)
          if (0 < common.arrayIntersect(n, r[e].tags).length)
            return common.wordwrapLocale(t, r[e].maxLength, this.getTl(), o);
      for (let e = 0; e < r.length; e++)
        if (0 < common.arrayIntersect(n, r[e].tags).length)
          return common.wordwrap(t, r[e].maxLength, o);
    }
    return t;
  }),
  (Trans.prototype.getTranslationData = function (e, t) {
    ((t = t || {}).keyCol = t.keyCol || 0),
      (t.groupIndex = t.groupIndex || void 0),
      (t.groupBy = t.groupBy || "path"),
      (t.objectGrouping = t.objectGrouping || !1),
      (t.includeTagsInfo = t.includeTagsInfo || !1),
      (e = e || trans.getSaveData()),
      ((e = JSON.parse(JSON.stringify(e))).project = e.project || {}),
      (e.project.files = e.project.files || {}),
      (t.options = t.options || {}),
      (t.filterTag = t.filterTag || t.options.filterTag || []),
      (t.filterTagMode = t.filterTagMode || t.options.filterTagMode || ""),
      (t.wordWrapByTags =
        t.wordWrapByTags ||
        t.options.wordWrapByTags ||
        e.project.options.wordWrapByTags),
      (t.useSelectedFiles ??= !0),
      (t.disableEvent ||= !1),
      (t.collectUntranslated ||= !1);
    var n = t.contextSeparator || "\n",
      r = [];
    if (t.useSelectedFiles)
      for (
        var o = $(".fileList .data-selector .fileCheckbox:checked"), a = 0;
        a < o.length;
        a++
      )
        r.push(o.eq(a).attr("value"));
    if (((t.files = t.files || r || []), "id" == t.groupBy))
      for (var i in e.project.files)
        e.project.files[i] && (e.project.files[i].id = i);
    var s,
      l = {},
      c = { filterTag: t.filterTag, filterTagMode: t.filterTagMode };
    for (s in (empty(t.wordWrapByTags) || (c.wordWrapByTags = t.wordWrapByTags),
    e.project.files)) {
      var d = e.project.files[s];
      if (
        ((d.data = d.data || [[]]),
        (d.tags = d.tags || []),
        !(0 < t.files.length && 0 == t.files.includes(s)))
      ) {
        l[d[t.groupBy]] = l[d[t.groupBy]] || {
          info: { groupLevel: d.groupLevel },
          translationPair: {},
        };
        for (var g = 0; g < d.data.length; g++)
          if (0 != Boolean(d.data[g]) && 0 != Boolean(d.data[g][t.keyCol])) {
            var f = d.tags[g] || [];
            if ("" !== t.filterTagMode) {
              var u = t.filterTag.filter((e) => f.includes(e));
              if ("whitelist" == t.filterTagMode) {
                if (0 == u.length) continue;
              } else if (0 < u.length) continue;
            }
            try {
              var p,
                h,
                m = (d.data[g][t.keyCol] = d.data[g][t.keyCol] || ""),
                y = trans.getTranslationFromRow(d.data[g], t.keyCol),
                v = ui.translationByContext.generateContextTranslation(g, s, m);
              t.collectUntranslated
                ? (0 < v.length &&
                    (l[d[t.groupBy]].translationPair = Object.assign(
                      l[d[t.groupBy]].translationPair,
                      v.translation
                    )),
                  t.objectGrouping
                    ? d[t.groupIndex]
                      ? ((l[d[t.groupBy]].translationPair[d[t.groupIndex]] =
                          l[d[t.groupBy]].translationPair[d[t.groupIndex]] ||
                          {}),
                        (l[d[t.groupBy]].translationPair[d[t.groupIndex]][m] =
                          trans.wordWrapText(y, f, t.wordWrapByTags) || ""))
                      : (l[d[t.groupBy]].translationPair[m] =
                          trans.wordWrapText(y, f, t.wordWrapByTags) || "")
                    : ((p = d[t.groupIndex] ? d[t.groupIndex] + n + m : m),
                      (l[d[t.groupBy]].translationPair[p] =
                        trans.wordWrapText(y, f, t.wordWrapByTags) || "")))
                : (0 == Boolean(y) && 0 == v.length) ||
                  (0 < v.length &&
                    (l[d[t.groupBy]].translationPair = Object.assign(
                      l[d[t.groupBy]].translationPair,
                      v.translation
                    )),
                  t.objectGrouping
                    ? d[t.groupIndex]
                      ? ((l[d[t.groupBy]].translationPair[d[t.groupIndex]] =
                          l[d[t.groupBy]].translationPair[d[t.groupIndex]] ||
                          {}),
                        !1 !== Boolean(y) &&
                          (l[d[t.groupBy]].translationPair[d[t.groupIndex]][m] =
                            trans.wordWrapText(y, f, t.wordWrapByTags)))
                      : !1 !== Boolean(y) &&
                        (l[d[t.groupBy]].translationPair[m] =
                          trans.wordWrapText(y, f, t.wordWrapByTags))
                    : ((h = d[t.groupIndex] ? d[t.groupIndex] + n + m : m),
                      !1 !== Boolean(y) &&
                        (l[d[t.groupBy]].translationPair[h] =
                          trans.wordWrapText(y, f, t.wordWrapByTags))));
            } catch (e) {
              throw (
                (console.log(
                  "Error when processing",
                  s,
                  "row",
                  g,
                  d.data[g][t.keyCol]
                ),
                e)
              );
            }
          }
      }
    }
    return (
      t.disableEvent ||
        this.trigger("onGenerateTranslationData", {
          info: c,
          translationData: l,
        }),
      { info: c, translationData: l }
    );
  }),
  (Trans.prototype.buildContextFromParameter = function (e) {
    return (
      e["VALUE ID"] + "/" + consts.eventCode[trans.gameEngine][e["EVENT CODE"]]
    );
  }),
  (Trans.prototype.getStagingPath = function (e) {
    try {
      return (e ||= this), nwPath.resolve(e?.project?.cache?.cachePath);
    } catch (e) {}
  }),
  (Trans.prototype.getStagingDataPath = function (e) {
    var t = engines.current().getProperty("stagingDataPath") || "data";
    return nwPath.join(this.getStagingPath(e), t);
  }),
  (Trans.prototype.updateStagingInfo = async function (e) {
    e ||= this;
    var t = nwPath.join(this.getStagingPath(e) || "", "gameInfo.json"),
      n = (console.log("Staging info:", t), {});
    return (
      ((n = (await common.isFileAsync(t))
        ? JSON.parse(await common.fileGetContents(t))
        : n).title = e.project.gameTitle),
      (n.engine = e.project.gameEngine),
      await common.filePutContents(t, JSON.stringify(n, void 0, 2), "UTF8", !1),
      n
    );
  }),
  (Trans.prototype.getStagingFile = function (e) {
    if (
      (e = "string" == typeof e ? this.getObjectById(e) : e) &&
      "object" == typeof e &&
      e.path
    )
      return nwPath.join(this.getStagingDataPath(), e.path);
  }),
  (Trans.prototype.insertCell = function (e, n) {
    if (
      ((n = n || null),
      common.batchArrayInsert(trans.data, e, n),
      void 0 === trans.project)
    )
      return trans.alert(t("Please open or create a new project first!"));
    for (var r in trans.project.files)
      r != trans.getSelectedId() &&
        common.batchArrayInsert(trans.project.files[r].data, e, n);
  }),
  (Trans.prototype.copyCol = function (e, t, n, r) {
    if (
      (console.log("Copying column"),
      console.log(arguments),
      void 0 === (n = n || trans.project))
    )
      return console.log("project is undefined");
    if (void 0 === n.files) return console.log("project.files are undefined");
    for (var o in n.files)
      if (0 == Array.isArray(n.files[o].data))
        console.log("no data for files " + o);
      else
        for (var a in n.files[o].data)
          n.files[o].data[a][t] = n.files[o].data[a][e];
  }),
  (Trans.prototype.gridIsModified = function (e) {
    return void 0 === e
      ? this.unsavedChange
      : this.project
      ? (this.unsavedChange !== e &&
          this.trigger("documentModifiedStateChange", e),
        (this.unsavedChange = e),
        (e = this.getSelectedId()),
        0 != Boolean(this.project.files) &&
          !!this.project.files[e] &&
          ((this.project.files[e].cacheResetOnChange = {}), this.unsavedChange))
      : void (this.unsavedChange = !1);
  }),
  (Trans.prototype.walkToAllFile = function () {
    console.log($(".fileList .selected"));
    for (
      var e = $(".fileList li").index($(".fileList .selected")), t = 0;
      t < $(".fileList li").length;
      t++
    )
      $(".fileList li").eq(t).trigger("click");
    $(".fileList li").eq(e).trigger("click");
  }),
  (Trans.prototype.moveColumn = async function (e, t) {
    if (
      (console.log("trans.moveColumn"),
      console.log(arguments),
      void 0 === trans.project)
    )
      return !1;
    if (
      (t > Math.min.apply(null, e) && (console.log("move to rigth"), (t -= 1)),
      e[0] == t)
    )
      return !1;
    for (var n in (t < Math.max.apply(null, e) && console.log("move to left"),
    ui.showBusyOverlay(),
    trans.project.files))
      for (var r = 0; r < trans.project.files[n].data.length; r++)
        (trans.project.files[n].data[r] = common.arrayMoveBatch(
          trans.project.files[n].data[r],
          e,
          t
        )),
          this.cellInfo.moveCell(n, r, e, t);
    return (
      (trans.colHeaders = common.arrayMoveBatch(trans.colHeaders, e, t)),
      (trans.column = common.arrayMoveBatch(trans.column, e, t)),
      await common.wait(250),
      trans.grid.destroy(),
      trans.initTable(),
      ui.hideBusyOverlay(),
      trans.renderGridInfo(),
      trans.gridIsModified(!0),
      trans
    );
  }),
  (Trans.prototype.dataPadding = function () {
    if (void 0 === trans.data) return !1;
    for (var e in (console.log("Trans data : ", trans.data), trans.data)) {
      var t;
      0 == Array.isArray(trans.data[e]) && (trans.data[e] = []),
        trans.data[e].length >= trans.colHeaders.length ||
          (t = trans.colHeaders.length - trans.data[e].length) < 0 ||
          (console.log("trans.data[i] : ", trans.data[e]),
          console.log("trans.data : ", trans.data[e].length),
          console.log("dif length : ", t),
          (t = Array(t).fill(null)),
          (trans.data[e] = trans.data[e].concat(t)));
    }
    if (void 0 === trans.project) return !1;
    for (var n in trans.project.files)
      for (var r in trans.project.files[n].data) {
        var o;
        trans.project.files[n].data[r].length >= trans.colHeaders.length ||
          ((o =
            trans.colHeaders.length - trans.project.files[n].data[r].length),
          (o = Array(o).fill(null)),
          (trans.project.files[n].data[r] =
            trans.project.files[n].data[r].concat(o)));
      }
    return trans.refreshGrid(), trans;
  }),
  (Trans.prototype.generateHeader = function (t, n) {
    n = n || "";
    var e,
      r = 0;
    for (e in (t = t || this).project.files) {
      var o = t.project.files[e].data || [];
      for (let e = 0; e < o.length; e++)
        0 != Array.isArray(o[e]) && o[e].length > r && (r = o[e].length);
    }
    for (let e = t.colHeaders.length - 1; e < r; e++)
      t.colHeaders.push(n + String.fromCharCode(65 + e)), t.columns.push({});
    return t.colHeaders;
  }),
  (Trans.prototype.sanitize = function (e) {
    if (
      ((e = e || this),
      console.log("running trans.sanitize"),
      void 0 === e.project)
    )
      return !1;
    if (void 0 === e.project.files) return !1;
    for (var t in e.project.files) {
      var n = e.project.files[t].data,
        r = e.project.files[t].context || [],
        o = e.project.files[t].tags || [],
        a = e.project.files[t].parameters || [],
        i = {},
        s = [],
        l = [],
        c = [],
        d = [];
      if (((this.colHeaders = this.colHeaders || []), 0 == Array.isArray(n)))
        e.project.files[t].data = [
          JSON.parse(JSON.stringify(this.colHeaders)).fill(null),
        ];
      else if (0 == n.length)
        e.project.files[t].data = [
          JSON.parse(JSON.stringify(this.colHeaders)).fill(null),
        ];
      else {
        for (var g, n = n || [], f = 0; f < n.length; f++)
          "string" != typeof n[f][0] ||
            n[f][0].length < 1 ||
            (void 0 === i[n[f][0]] &&
              (s.push(n[f]),
              (g = s.length - 1),
              r[f] && (l[g] = r[f]),
              o[f] && (c[g] = o[f]),
              a[f] && (d[g] = a[f]),
              (i[n[f][0]] = !0)));
        (e.project.files[t].data = s),
          (e.project.files[t].context = l),
          (e.project.files[t].tags = c),
          (e.project.files[t].parameters = d);
      }
    }
    return (e.project.isDuplicatesRemoved = !0), e;
  }),
  (Trans.prototype.removeDuplicates = function () {
    console.log("running trans.removeDuplicates");
    for (var e = {}, t = [], n = 0; n < trans.data.length; n++)
      void 0 === e[trans.data[n][0]] &&
        (t.push(trans.data[n]), (e[trans.data[n]] = !0));
    return (trans.data = t), trans.data;
  }),
  (Trans.prototype.isKeyExistOn = function (e, t) {
    return (
      void 0 === t && (t = trans.getSelectedId()),
      "number" == typeof trans.findIdByIndex(e, t)
    );
  }),
  (Trans.prototype.isKeyExist = function (e) {
    return "number" == typeof trans.findIdByIndex(e);
  }),
  (Trans.prototype.setTags = function (e, t, n, r) {
    return (
      (r = r || {}),
      0 == Array.isArray(n) && (n = [n]),
      void 0 !== this.project &&
        void 0 !== this.project.files[e] &&
        "number" == typeof t &&
        (void 0 === this.project.files[e].tags &&
          (this.project.files[e].tags = []),
        1 == Boolean(r.append)
          ? ((this.project.files[e].tags[t] =
              this.project.files[e].tags[t] || []),
            this.project.files[e].tags[t].push.apply(
              this.project.files[e].tags[t],
              n
            ),
            (this.project.files[e].tags[t] = this.project.files[e].tags[
              t
            ].filter((e, t, n) => n.indexOf(e) === t)))
          : (this.project.files[e].tags[t] = n),
        this.project.files[e].tags[t])
    );
  }),
  (Trans.prototype.removeTags = function (e, t, n, r) {
    if (
      (console.log("removeTags", arguments),
      (e = e || this.getSelectedId()),
      0 == Array.isArray(n) && (n = [n]),
      void 0 === this.project)
    )
      return !1;
    if (void 0 === this.project.files[e]) return !1;
    if ("number" != typeof t) return !1;
    void 0 === this.project.files[e].tags && (this.project.files[e].tags = []);
    let o = this.project.files[e].tags?.[t];
    return (
      console.log("Current tags", o),
      0 == Array.isArray(o)
        ? []
        : ((o = o.filter((e) => !n.includes(e))),
          (this.project.files[e].tags[t] = o),
          this.project.files[e].tags[t])
    );
  }),
  (Trans.prototype.clearTags = function (t, n, e) {
    if (((t = t || this.getSelectedId()), void 0 === this.project)) return !1;
    if (void 0 === this.project.files[t]) return !1;
    if ("number" == typeof n)
      return (
        (this.project.files[t].tags[n] = []), this.project.files[t].tags[n]
      );
    for (let e = 0; e < n.length; e++) {
      var r = n[e].start || n[e].from,
        o = n[e].end || n[e].to;
      if (void 0 !== r.row && void 0 !== o.row) {
        this.project.files[t].tags = this.project.files[t].tags || [];
        for (var a = r.row; a <= o.row; a++) this.project.files[t].tags[a] = [];
      }
    }
    return this.project.files[t].tags[a];
  }),
  (Trans.prototype.resetTags = function (e, t) {
    return (
      (e = e || this.getSelectedId()),
      void 0 !== this.project &&
        void 0 !== this.project.files[e] &&
        (this.project.files[e].tags = [])
    );
  }),
  (Trans.prototype.appendTags = function (e, t, n, r) {
    return this.setTags(e, t, n, { append: !0, noRefresh: !0 });
  }),
  (Trans.prototype.setTagForSelectedRow = function (t, n, r, o) {
    if (
      (void 0 === (o = o || {}).append && (o.append = !0),
      (r = r || this.getSelectedId()),
      0 == Boolean(n))
    )
      return !1;
    if (0 == Array.isArray(n)) return !1;
    for (let e = 0; e < n.length; e++) {
      var a = n[e].start || n[e].from,
        i = n[e].end || n[e].to;
      if (void 0 !== a.row && void 0 !== i.row)
        for (var s = a.row; s <= i.row; s++) this.setTags(r, s, t, o);
    }
    return this.grid.render(), !0;
  }),
  (Trans.prototype.removeTagForSelectedRow = function (t, n, r, o) {
    if (
      (console.log("removeTagForSelectedRow", arguments),
      ((o = o || {}).append = o.append || !0),
      (r = r || this.getSelectedId()),
      0 == Boolean(n))
    )
      return !1;
    if (0 == Array.isArray(n)) return !1;
    for (let e = 0; e < n.length; e++) {
      var a = n[e].start || n[e].from,
        i = n[e].end || n[e].to;
      if (void 0 !== a.row && void 0 !== i.row)
        for (var s = a.row; s <= i.row; s++) this.removeTags(r, s, t, o);
    }
    return this.grid.render(), !0;
  }),
  (Trans.prototype.hasTags = function (e, t, n) {
    if (!e) return !1;
    if (void 0 === t) return !1;
    n = n || this.getSelectedId();
    var r = this.getObjectById(n);
    if (!r) return !1;
    if (!r.tags) return !1;
    if (!Array.isArray(r.tags[t])) return !1;
    Array.isArray(e) || (e = [e]);
    try {
      for (var o in e) if (r.tags[t].includes(e[o])) return !0;
      return !1;
    } catch (e) {
      return !1;
    }
  }),
  (Trans.prototype.alert = async function (t, r) {
    return (
      (r = r || 3e3),
      $("#appInfo").attr("title", t),
      new Promise((n, e) => {
        $("#appInfo").tooltip({
          content: function () {
            return t;
          },
          show: { effect: "slideDown", duration: 200 },
          hide: { effect: "fade", delay: 250 },
          position: { my: "left top", at: "left bottom", of: "#table" },
          open: function (e, t) {
            setTimeout(function () {
              $("#appInfo").tooltip("close"),
                $("#appInfo").attr("title", ""),
                n();
            }, r);
          },
        }),
          $("#appInfo").tooltip("open");
      })
    );
  }),
  (Trans.prototype.refreshGrid = function (e) {
    if (
      (((e = e || {}).rebuild = e.rebuild || !1),
      trans.getSelectedId() &&
        (trans.data = trans?.project?.files[trans.getSelectedId()].data),
      trans.data || (trans.data = [[null]]),
      1 == trans.data.length &&
        (0 == Array.isArray(trans.data[0]) && (trans.data = [[null]]),
        0 == Boolean(trans.data[0][0])) &&
        (trans.data = [[null]]),
      0 == trans.data.length && (trans.data = [[null]]),
      trans.getSelectedId() &&
        (trans.project.files[trans.getSelectedId()].data = trans.data),
      "function" == typeof e.onDone &&
        trans.grid.addHookOnce("afterRender", function () {
          e.onDone.call(trans.grid);
        }),
      e.rebuild)
    )
      return trans.grid.destroy(), trans.initTable(), !0;
    trans.grid.updateSettings({
      data: trans.data,
      colHeaders: trans.colHeaders,
      columns: trans.columns,
    }),
      trans.loadComments();
  }),
  (Trans.prototype.editNoteAtCell = function (e) {
    if (void 0 === e)
      try {
        e = trans.grid.getSelectedRange()[0].highlight;
      } catch (e) {
        return console.log(e), !1;
      }
    trans.grid.getPlugin("comments").showAtCell(e.row, e.col),
      $(".htCommentTextArea").trigger("click"),
      $(".htCommentTextArea").focus();
  }),
  (Trans.prototype.removeNoteAtSelected = function (e) {
    if (
      (console.log("trans.removeNoteAtSelected"),
      void 0 === e && (e = trans.grid.getSelectedRange()),
      0 == Boolean(e))
    )
      return console.log("no selection were made"), !1;
    console.log(e);
    for (
      var t = Math.min(e[0].from.row, e[0].to.row),
        n = Math.max(e[0].from.row, e[0].to.row),
        r = Math.min(e[0].from.col, e[0].to.col),
        o = Math.max(e[0].from.col, e[0].to.col),
        a = trans.grid.getPlugin("comments"),
        i = t;
      i <= n;
      i++
    )
      for (var s = r; s <= o; s++) a.removeCommentAtCell(i, s);
  }),
  (Trans.prototype.drawGridTranslatorMenu = function () {
    if (!this.translatorContextMenuIsInitialized) {
      if (
        (console.log("Initializing translator context menu"),
        (TranslatorEngine.translators = TranslatorEngine.translators || {}),
        empty(TranslatorEngine.translators))
      )
        return;
      for (var n in ((this.gridContextMenu.translateUsing.submenu.items = []),
      TranslatorEngine.translators))
        (() => {
          var e = n,
            t = TranslatorEngine.translators[n];
          this.gridContextMenu.translateUsing.submenu.items.push({
            key: "translateUsing:" + e,
            name: t.name,
            callback: () => {
              this.translateSelection(void 0, { translatorEngine: t });
            },
            hidden: () =>
              !!this.grid.isColumnHeaderSelected() ||
              !!this.grid.isRowHeaderSelected() ||
              void 0,
          });
        })();
      this.translatorContextMenuIsInitialized = !0;
    }
    return this.gridContextMenu;
  }),
  (Trans.prototype.getGridContextMenu = function () {
    return this.drawGridTranslatorMenu(), this.gridContextMenu;
  }),
  (Trans.prototype.updateGridContextMenu = function (e) {
    console.log("updateGridContextMenu", e), this.gridContextMenuIsModified;
  }),
  (Trans.prototype.modifyGridContextMenu = function (e) {
    this.gridContextMenuIsModified = !0;
  }),
  (Trans.prototype.calculateTableHeights = async function (e = this.data) {
    console.log("Calculating table height");
    return e?.length
      ? e.length < 1e3
        ? 23 * t(e) + 46
        : (e = await new (require("www/js/CommonWorker.js").Handler)(
            "./www/js/trans.worker.js",
            {
              command: "calculateHeights",
              data: e,
              options: { logTarget: "ui" },
            }
          ).getResult())?.result
        ? 23 * e.result + 46
        : 23
      : 23;
    function t(r) {
      let e = 0;
      for (let n = 0; n < r.length; n++)
        if (r[n]?.length) {
          let t = 1;
          for (let e = 0; e < r[n].length; e++) {
            var o;
            r[n][e] && (o = r[n][e].split("\n").length) > t && (t = o);
          }
          e += t;
        }
      return e < r.length ? r.length : e;
    }
  }),
  (Trans.prototype.initTable = function (e) {
    var n = document.getElementById("table");
    if (0 == Boolean(n)) return !1;
    Handsontable.dom.addEvent(n, "blur", function (e) {
      console.log("event", e);
    }),
      (Handsontable.debugLevel = common.debugLevel()),
      (this.grid = new Handsontable(n, {
        data: trans.data,
        comments: !0,
        rowHeaders: !0,
        colHeaders: trans.colHeaders,
        columns: trans.columns,
        formulas: !1,
        search: !0,
        outsideClickDeselects: !1,
        viewportColumnRenderingOffset: 15,
        maxCols: Trans.maxCols,
        autoRowSize: !1,
        minSpareRows: 1,
        filters: !1,
        dropdownMenu: !1,
        autoWrapRow: !0,
        manualColumnMove: !0,
        manualColumnResize: !0,
        copyPaste: { columnsLimit: 15, rowsLimit: 1e5 },
        beforeChange: function (e, n) {
          if (
            (console.log("beforeChange", arguments),
            console.log(e),
            console.log(n),
            void 0 === trans.selectedData)
          )
            return console.warn("unknown selected data");
          for (var r = 0; r < e.length; r++) {
            if (0 == e[r][1] && e[r][0] < trans.grid.getData().length - 1)
              return (
                console.log(JSON.stringify(e, void 0, 2)),
                trans.alert(t("You should not edit key value")),
                !1
              );
            if (0 == e[r][1]) {
              if (0 == Boolean(e[r][3])) return !1;
              if (trans.isKeyExistOn(e[r][3]))
                return (
                  trans.alert(
                    t("Ilegal value") +
                      " <b>'" +
                      e[r][3] +
                      "'</b> " +
                      t("That value already exist!")
                  ),
                  !1
                );
              "number" == typeof trans.findIdByIndex(e[r][2]) &&
                delete trans.indexIds[e[r][2]],
                (trans.selectedData.indexIds[e[r][3]] = e[r][0]);
            }
          }
        },
        afterChange: function (e, t) {
          if ((trans.gridIsModified(!0), null == e)) return !0;
          if (!trans.getSelectedId()) return !0;
          var n,
            r,
            o = !1,
            a = trans.project.files[trans.getSelectedId()].progress;
          for (n in e)
            0 != Array.isArray(e[n]) &&
              trans.data[e[n][0]][0] &&
              ((e[n][2] = e[n][2] || ""),
              (e[n][3] = e[n][3] || ""),
              e[n][0] == trans.lastSelectedCell[0] &&
                e[n][1] == trans.lastSelectedCell[1] &&
                trans.textEditorSetValue(e[n][3]),
              0 < e[n][2].length && 0 == e[n][3].length
                ? 0 != trans.countFilledCol(e[n][0]) ||
                  a.translated <= 0 ||
                  (a.translated--,
                  0 < a.length
                    ? (a.percent = (a.translated / a.length) * 100)
                    : (a.percent = 0),
                  (o = !0))
                : 0 == e[n][2].length &&
                  0 < e[n][3].length &&
                  (1 != trans.countFilledCol(e[n][0]) ||
                    a.translated >= a.length ||
                    (a.translated++,
                    0 < a.length
                      ? (a.percent = (a.translated / a.length) * 100)
                      : (a.percent = 0),
                    (o = !0))));
          o &&
            (((r = {})[trans.getSelectedId()] = a),
            trans.evalTranslationProgress(trans.getSelectedId(), r)),
            trans.trigger("afterCellChange", [e, t]);
        },
        beforeContextMenuShow: (e) => {
          trans.updateGridContextMenu(e);
        },
        contextMenu: { items: trans.getGridContextMenu() },
        cells: function (e, t, n) {
          var r = {};
          if (0 == t) {
            if (void 0 === trans.data[e]) return r;
            null !== trans.data[e][t] &&
              "" !== trans.data[e][t] &&
              (r.readOnly = !0);
          }
          return r;
        },
        afterSelection: function (e, t, n, r, o, a) {
          console.log("do after selection", arguments),
            trans.trigger("beforeProcessSelection", arguments),
            trans.doAfterSelection(e, t, n, r);
        },
        beforeInit: function () {
          console.log("running before init");
        },
        afterInit: function () {
          trans.buildIndex();
        },
        beforeColumnMove: function (e, t) {
          return (
            console.log("beforeColumnMove"),
            0 != t && 1 != e.includes(0) && (trans.moveColumn(e, t), !0)
          );
        },
        afterColumnMove: function (e, t) {
          return console.log("afterColumnMove"), 0 != t && 1 != e.includes(0);
        },
        afterSetCellMeta: function (t, n, e, r) {
          if ("comment" == e) {
            e = trans.getSelectedObject();
            if (e)
              if (null == r)
                try {
                  delete e.comments[t][n];
                } catch (e) {
                  console.log(
                    "unable to delete comment.\nData row:" +
                      t +
                      ", col:" +
                      n +
                      " is not exist on trans.project.files[trans.getCurrentID].comments!"
                  );
                }
              else
                (e.comments = e.comments || []),
                  (e.comments[t] = e.comments[t] || []),
                  (e.comments[t][n] = r.value);
            return !0;
          }
        },
        afterRender: function (e) {
          if (1 == e) return !0;
          $("#currentCellText").is(":focus") &&
            !1 !== (e = ui.getCurrentEditedCellElm()) &&
            ($("#table .currentCell").removeClass("currentCell"),
            e.addClass("currentCell"));
        },
        afterRenderer: function (e, t, n, r, o, a) {
          e.setAttribute("data-coord", t + "-" + n),
            0 < n &&
              trans.getOption("gridInfo")?.isRuleActive &&
              (trans.getOption("gridInfo")?.viewOrganicCellMarker &&
              trans.isOrganicCell(t, n)
                ? $(e).addClass("organic")
                : trans.getOption("gridInfo")?.viewTrail &&
                  trans.isVisitedCell(t, n) &&
                  $(e).addClass("viewed")),
            0 < n ||
              (t >= trans.data.length - 1 && $(e).addClass("newKeyField"));
        },
        afterGetColHeader: function (e, t) {
          -1 == e && $(t).attr("data-role", "tablecorner");
        },
        afterGetRowHeader: function (t, n) {
          var e,
            r = $(n),
            n = $(n).closest("tr"),
            o = r.find(".rowInfo");
          if (
            (o.length ||
              ((e = r.find(">div")),
              (o = $('<span class="rowInfo"></span>').appendTo(e))),
            void 0 !== trans.selectedData &&
              0 != Array.isArray(trans.selectedData.tags) &&
              0 != Array.isArray(trans.selectedData.tags[t]) &&
              1 != n.hasClass("tagRendered"))
          ) {
            var a = [];
            let e = 0;
            for (var i = 0; i < trans.selectedData.tags[t].length; i++) {
              var s = trans.selectedData.tags[t][i];
              void 0 !== consts.tagColor[s] &&
                ((e += consts.tagStripThickness),
                a.push("inset " + e + "px 0px 0px 0px " + consts.tagColor[s])),
                r.addClass("tag-" + trans.selectedData.tags[t][i]);
            }
            0 != a.length && r.css("box-shadow", a.join(",")),
              n.addClass("hasTag"),
              n.addClass("tagRendered");
          }
          ui.translationByContext &&
            trans.rowHasMultipleContext(t, trans.selectedData) &&
            (r.addClass("hasMC"),
            ui.translationByContext.rowHasContextTranslation(
              t,
              trans.selectedData
            )) &&
            r.addClass("hasTC"),
            (e = trans.getRowInfoText(t)) ? o.text(e) : o.text("");
        },
        afterCreateRow: function (e, t, n) {
          var r = trans.getSelectedId();
          if (0 == Boolean(r)) return !1;
          trans.evalTranslationProgress([r]);
        },
        beforePaste: function (e, t) {},
        afterScrollVertically() {
          this.skipScrollEvent ||
            (this._scrollTimer && clearTimeout(this._scrollTimer),
            (this._scrollTimer = setTimeout(async () => {
              $("#table .wtHolder>*:eq(0)").height() -
                $("#table .wtHolder").scrollTop() -
                $("#table .wtHolder").height() <=
                0 &&
                ($(".newKeyField").visible() ||
                  (this.render(),
                  (this.skipScrollEvent = !0),
                  trans.grid.scrollViewportTo(ui.getFirstFullyVisibleRow()),
                  await common.wait(50),
                  (this.skipScrollEvent = !1)));
            }, 200)));
        },
      })),
      Handsontable.dom.addEvent($("#quickFind")[0], "input", function (e) {
        var t = trans.grid.getPlugin("search").query(this.value);
        console.log(t), trans.grid.render();
      }),
      (trans.grid.autoRowSize = trans.grid.getPlugin("autoRowSize")),
      (trans.grid.isFixedHeight = !0),
      (trans.grid.view.wt.ignoreAdjustElementSize = !1);
    async function r(e = trans.getSelectedId()) {
      !trans.grid.getSettings().autoRowSize ||
        trans.grid.isFixedHeight ||
        trans.data?.length < 1e3 ||
        (console.log("Saving cache rowheights for ", e),
        trans?.localStorage &&
          (console.log(
            "Calculated row heights length ",
            trans.grid.autoRowSize.heights.length,
            "Current row length",
            trans.data.length
          ),
          trans.grid &&
            trans.localStorage.set(
              trans.getSelectedId() + "?rowHeights",
              trans.grid.autoRowSize.heights
            ),
          trans.localStorage.set(trans.getSelectedId() + "?hiderDimension", {
            width: trans.grid.view.wt.wtTable.hider.style.width,
            height: trans.grid.view.wt.wtTable.hider.style.height,
          })));
    }
    (trans.grid.loadRowHeightsCache = async function (e) {
      if (
        trans.grid.getSettings().autoRowSize &&
        !trans.grid.isFixedHeight &&
        !(trans.data?.length < 1e3) &&
        (console.log("start counting rows height on colRange", e),
        trans?.localStorage)
      ) {
        e = await trans.localStorage.get(trans.getSelectedId() + "?rowHeights");
        if ((console.log("Cache row height is", e), e?.length))
          return (
            (trans.grid.autoRowSize.heights = await trans.localStorage.get(
              trans.getSelectedId() + "?rowHeights"
            )),
            (trans.grid.autoRowSize.inProgress = !1),
            (trans.grid.cachedDimension = await trans.localStorage.get(
              trans.getSelectedId() + "?hiderDimension"
            )),
            !0
          );
      }
    }),
      (trans.grid.onCalculateAllRowsHeightStart = async function () {
        ui.tableCornerShowLoading(
          "Counting total rows height. The grid may jumpy while in counting process."
        );
      }),
      (trans.grid.onCalculateAllRowsHeightEnd = async function () {
        trans.data?.length < 1e3 || (ui.tableCornerHideLoading(), r());
      }),
      trans.off("beforeSelectFile"),
      trans.on("beforeSelectFile", function (e, t) {
        console.log("%cbeforeSelectFile", "color:pink", t),
          t?.[0] && t[0] != t[1] && r(t[0]);
      }),
      (trans.grid.setFixedTableHeightByData = async function (e = []) {
        var t, n;
        trans.grid.isFixedHeight &&
          e?.length &&
          ((n = 22 * e.length * 10),
          (t = trans.getSelectedId()),
          trans.grid.setFixedTableHeight(n),
          (n = await trans.calculateTableHeights(e)),
          trans.getSelectedId() === t) &&
          (console.log("Setting actual height", n),
          trans.grid.setFixedTableHeight(n));
      }),
      (trans.grid.setFixedTableHeight = function (e) {
        if (trans.grid.isFixedHeight)
          return (
            "string" == typeof e && e.includes("px")
              ? ((trans.grid.view.wt.wtTable.hider.style.height = e),
                (trans.grid.view.wt.ignoreAdjustElementSize = !0))
              : "number" == typeof e
              ? ((trans.grid.view.wt.wtTable.hider.style.height = e + "px"),
                (trans.grid.view.wt.ignoreAdjustElementSize = !0))
              : "boolean" == typeof e &&
                !1 === e &&
                (trans.grid.view.wt.ignoreAdjustElementSize = !1),
            trans.grid.view.wt.wtTable.hider.style.height
          );
      }),
      (trans.grid.addHeight = function (e = 0) {
        var t = parseInt(trans.grid.view.wt.wtTable.hider.style.height);
        return (
          (trans.grid.view.wt.wtTable.hider.style.height = t + e + "px"),
          trans.grid.view.wt.wtTable.hider.style.height
        );
      }),
      (trans.grid.getTableHeight = function () {
        return trans.grid.view.wt.wtTable.hider.style.height;
      }),
      (trans.grid.isColumnHeaderSelected = function () {
        return Boolean($(".htCore thead th.ht__active_highlight").length);
      }),
      (trans.grid.isRowHeaderSelected = function () {
        return Boolean($(".htCore tr th.ht__active_highlight").length);
      }),
      (trans.grid.insertColumnRight = function (e, n) {
        var r;
        trans.columns.length >= Trans.maxCols
          ? alert(
              t(
                "The maximum number of columns for this project has been reached, so you cannot add any more."
              )
            )
          : ((e = e || "New Col"),
            (n = n || trans.grid.getSelected()[0][1]),
            (r = trans.columns.length),
            trans.columns.push({}),
            common.arrayExchange(trans.columns, r, n + 1),
            common.arrayInsert(trans.colHeaders, n + 1, e),
            console.log(trans.columns),
            trans.insertCell(n + 1, null),
            trans.grid.updateSettings({ colHeaders: trans.colHeaders }));
      }),
      (trans.grid.setColWidth = function (e, t) {
        trans.columns[e] && ((trans.columns[e].width = t), trans.refreshGrid());
      });
  }),
  (Trans.prototype.findAndInsertWithIndexes = function (t = "", n, r, e, o) {
    (r = r || 1),
      (t ||= ""),
      ((o = o || {}).overwrite = o.overwrite || !1),
      (o.files = o.files || []),
      (o.keyColumn = o.keyColumn || this.keyColumn || 0),
      (o.insensitive = o.insensitive || !1),
      (o.lineByLine = o.lineByLine || !1),
      (e = e || this._tempIndexes),
      void 0 === o.ignoreNewLine && (o.ignoreNewLine = !0),
      0 == o.files.length && (o.files = this.getAllFiles());
    var a = { keyword: t, count: 0, executionTime: 0, files: {} },
      i = this.getFromIndexes(t, e, o.customFilter);
    if (
      (!i &&
        t.includes("\r") &&
        ((t = t.replaceAll("\r", "")),
        (a.find = t),
        (i = this.getFromIndexes(t, e, o.customFilter))),
      i)
    )
      for (let e = 0; e < i.length; e++) {
        var s = i[e],
          l = s.file,
          c = s.row;
        if (
          (o.ignoreNewLine &&
            !1 !== Boolean(this.project.files[l].lineBreak) &&
            (t = common.replaceNewLine(t, this.project.files[l].lineBreak)),
          "number" == typeof c)
        ) {
          var d = this.getData(l)[c];
          if (d) {
            if ("blacklist" == o.filterTagMode) {
              if (this.hasTags(o.filterTag, c, l)) continue;
            } else if (
              "whitelist" == o.filterTagMode &&
              !this.hasTags(o.filterTag, c, l)
            )
              continue;
            if (o.lineByLine) {
              var g = (d[r] || "").replaceAll("\r", "").split("\n");
              if (0 == o.overwrite && 1 == Boolean(g[s.line])) continue;
              (g[s.line] = n), (d[r] = g.join("\n"));
            } else {
              if (0 == o.overwrite && 1 == Boolean(d[r])) continue;
              d[r] = n;
            }
            (a.files[l] = a.files[l] || []),
              a.files[l].push({
                fullString: d[r],
                row: c,
                col: r,
                type: "cell",
                lineIndex: null,
              }),
              a.count++;
          }
        }
      }
    return a;
  }),
  (Trans.prototype.findAndInsert = function (t, n, r, o) {
    (r = r || 1),
      ((o = o || {}).overwrite = o.overwrite || !1),
      (o.files = o.files || []),
      (o.keyColumn = o.keyColumn || this.keyColumn || 0),
      (o.insensitive = o.insensitive || !1),
      void 0 === o.ignoreNewLine && (o.ignoreNewLine = !0),
      0 == o.files.length && (o.files = this.getAllFiles());
    var a = { keyword: t, count: 0, executionTime: 0, files: {} };
    for (let e = 0; e < o.files.length; e++) {
      var i,
        s = o.files[e];
      if (
        (o.ignoreNewLine &&
          !1 !== Boolean(this.project.files[s].lineBreak) &&
          (t = common.replaceNewLine(t, this.project.files[s].lineBreak)),
        "number" ==
          typeof (i = o.insensitive
            ? this.getRowIdByTextInsensitive(t, s)
            : this.findIdByIndex(t, s)))
      ) {
        var l = this.getData(s)[i];
        if (l) {
          if ("blacklist" == o.filterTagMode) {
            if (this.hasTags(o.filterTag, i, s)) continue;
          } else if (
            "whitelist" == o.filterTagMode &&
            !this.hasTags(o.filterTag, i, s)
          )
            continue;
          (0 == o.overwrite && 1 == Boolean(l[r])) ||
            ((l[r] = n),
            (a.files[s] = a.files[s] || []),
            a.files[s].push({
              fullString: l[r],
              row: i,
              col: r,
              type: "cell",
              lineIndex: null,
            }),
            a.count++);
        }
      }
    }
    return a;
  }),
  (Trans.prototype.findAndInsertLine = function (t, n, r, o) {
    if (
      ((r = r || 1),
      ((o = o || {}).overwrite = o.overwrite || !1),
      (o.files = o.files || []),
      (o.keyColumn = o.keyColumn || 0),
      (o.newLine = o.newLine || void 0),
      (o.stripCarriageReturn = o.stripCarriageReturn || !1),
      o.stripCarriageReturn && (t = common.stripCarriageReturn(t)),
      0 == o.files.length)
    )
      if (void 0 !== trans.allFiles) o.files = trans.allFiles;
      else {
        for (var a in trans.project.files) o.files.push(a);
        trans.allFiles = o.files;
      }
    for (var e = 0; e < o.files.length; e++)
      for (
        var i,
          a = o.files[e],
          s = trans.project.files[a].data,
          l = o.newLine || trans.project.files[a].lineBreak || "\n",
          c = 0;
        c < s.length;
        c++
      ) {
        let e;
        if (s[c][o.keyColumn]) {
          if ("blacklist" == o.filterTagMode) {
            if (this.hasTags(o.filterTag, c, a)) continue;
          } else if (
            "whitelist" == o.filterTagMode &&
            !this.hasTags(o.filterTag, c, a)
          )
            continue;
          (s[c][o.keyColumn] = s[c][o.keyColumn] || ""),
            0 !=
              (e = (
                o.stripCarriageReturn
                  ? s[c][o.keyColumn].replaceAll("\r", "")
                  : s[c][o.keyColumn]
              ).split("\n")).includes(t) &&
              ((s[c][r] = s[c][r] || ""),
              (i = s[c][r].replaceAll("\r", "").split("\n")),
              (i = common.searchReplaceArray(e, i, t, n, {
                overwrite: o.overwrite,
              })),
              (s[c][r] = i.join(l)));
        }
      }
  }),
  (Trans.prototype.findAndInsertByContext = function (t, n, r, o) {
    (r = r || 1),
      ((o = o || {}).overwrite = o.overwrite || !1),
      (o.files = o.files || []),
      (o.ignoreNewLine = o.ignoreNewLine || !1),
      0 == o.files.length && (o.files = this.getAllFiles());
    for (let e = 0; e < o.files.length; e++) {
      var a = o.files[e],
        i = this.getObjectById(a);
      if (0 != Boolean(i) && 0 != Boolean(i.context))
        for (var s = 0; s < i.context.length; s++) {
          var l = i.context[s];
          if (
            0 != Array.isArray(l) &&
            !(l.length < 1) &&
            0 != Array.isArray(i.data[s])
          )
            for (var c = 0; c < l.length; c++)
              t !== l[c] ||
                (0 == o.overwrite && 1 == Boolean(i.data[s][r])) ||
                (i.data[s][r] = n);
        }
    }
  }),
  (Trans.prototype.translateTextByLine = function (e, t, n) {
    if ("string" != typeof e) return e;
    if (e.length < 1) return e;
    for (
      var r = [], o = e.replace(/(\r\n)/gm, "\n").split("\n"), a = 0;
      a < o.length;
      a++
    ) {
      var i = o[a];
      t[i] ? r.push(t[i]) : r.push("");
    }
    return r.join("\n");
  }),
  (Trans.prototype.translateFromArray = function (e, t, n) {
    if (
      (console.log("insert trans.translateFromArray", arguments),
      (t = t || 1),
      ((n = n || {}).sourceColumn = n.sourceColumn || "auto"),
      (n.overwrite = n.overwrite || !1),
      (n.files = n.files || []),
      (n.sourceKeyColumn = n.sourceKeyColumn || 0),
      (n.keyColumn = n.keyColumn || 0),
      (n.newLine = n.newLine || void 0),
      (n.stripCarriageReturn = n.stripCarriageReturn || !1),
      (n.ignoreNewLine = !0),
      0 == (e = e || []).length)
    )
      return !1;
    n.indexes ||
      (console.log("%cbuilding index", "color:salmon;"),
      0 == n.files?.length && (n.files = this.getAllFiles()),
      (n.indexes = this.buildIndexes(n.files, !1))),
      console.log("options.indexes", n.indexes);
    for (var r = 0; r < e.length; r++) {
      var o,
        a = e[r];
      0 != Boolean(a[n.sourceKeyColumn]) &&
        ((o = a[n.sourceKeyColumn]),
        (a =
          "auto" == n.sourceColumn
            ? trans.getTranslationFromRow(a, n.sourceKeyColumn)
            : a[n.sourceColumn]),
        trans.findAndInsertWithIndexes(o, a, t, n.indexes, {
          overwrite: n.overwrite,
          files: n.files,
        }));
    }
  }),
  (Trans.prototype.abortTranslation = function () {
    (trans.translator = trans.translator || []),
      void 0 !== trans.translationTimer && clearTimeout(trans.translationTimer);
    for (var e = 0; e < trans.translator.length; e++) {
      var t = trans.translator[e],
        t = trans.getTranslatorEngine(t);
      if (t) {
        if ("function" == typeof t.abort)
          try {
            t.abort();
          } catch (e) {
            ui.log("Failed to abort with message", e.toString());
          }
        (t.job = t.job || {}), (t.job.wordcache = {}), (t.job.batch = []);
      }
    }
    ui.hideLoading(), trans.refreshGrid(), trans.evalTranslationProgress();
  }),
  (Trans.prototype.translateStringByPair = function (e, t, n) {
    if (((n = n || !1), "string" == typeof e && "object" == typeof t))
      for (var r in t) e = e.replaces(r, t[r], n);
    return e;
  }),
  (Trans.prototype.translateFromTrans = function (e, r = [], t = this) {
    if (!e) return "";
    "string" == typeof r && (r = [r]);
    var t = t?.project?.files || {},
      n =
        (r?.length || (r = this.getAllFiles(t)),
        (e) => {
          for (var t in r) {
            var t = r[t],
              n = this.getIndexByKey(t, e);
            if (void 0 !== n) {
              t = this.getData(t);
              if (empty(t[n])) return "";
              t = this.getTranslationFromRow(t[n]);
              if (t) return t;
            }
          }
        });
    if (Array.isArray(e)) {
      var o,
        a = [];
      for (o in e) a[o] = n(e[o]) || "";
      return a;
    }
    return n(e);
  }),
  (Trans.prototype.getReference = function (e, t = "Common Reference") {
    return (
      (e &&
        void 0 !== (e = this.getIndexByKey(t, e)) &&
        ((t = this.getData(t)), !empty(t[e])) &&
        this.getTranslationFromRow(t[e])) ||
      ""
    );
  }),
  (Trans.prototype.translateByReference = function (
    e,
    t,
    n = "Common Reference"
  ) {
    if (((t = t || !1), trans.project.files[n])) {
      var r;
      if (
        ((trans.project.files[n].cacheResetOnChange =
          trans.project.files[n].cacheResetOnChange || {}),
        !1 !== Boolean(trans.project.files[n].cacheResetOnChange.transPair)
          ? (r = trans.project.files[n].cacheResetOnChange.transPair)
          : ((r = trans.generateTranslationPair(trans.project.files[n].data)),
            (trans.project.files[n].cacheResetOnChange.transPair = r)),
        "string" == typeof e)
      )
        return (o = trans.translateStringByPair(e, r, t));
      if (Array.isArray(e)) {
        for (var o = [], a = 0; a < e.length; a++)
          o[a] = trans.translateStringByPair(e[a], r, t);
        return o;
      }
    }
    return e;
  }),
  (Trans.prototype.rowHasTranslation = function (
    t = [],
    n = this.keyColumn,
    r
  ) {
    if (t && t.length)
      if (((n = this.keyColumn || 0), null == r)) {
        for (let e = 0; e < t.length; e++) if (e != n && t[e]) return !0;
      } else {
        Array.isArray(r) || (r = [r]);
        for (let e = 0; e < r.length; e++) if (r[e] != n && t[r[e]]) return !0;
      }
    return !1;
  }),
  (Trans.prototype.translateAll = async function (e, t) {
    var n = this.getTranslatorEngine(e);
    return (
      this.buildIndex("Common Reference", !0),
      "function" == n.translateAll
        ? n.translateAll(t)
        : "v2" == n.translatorType
        ? this.batchTranslate(n, t)
        : void ("rowByRow" == n.mode
            ? trans.translateAllByRows(e, t)
            : trans.translateAllByLines(e, t))
    );
  }),
  (Trans.prototype.batchTranslate = async function (e, n) {
    let r = new BatchTranslate(e, n);
    await ui.log.start({
      buttons: [
        {
          text: "Abort",
          onClick: function (e) {
            confirm(t("Are you sure want to abort this process?")) && r.abort();
          },
        },
        {
          text: "Pause",
          onClick: function (e) {
            alert(t("Process paused!\nPress OK to continue!"));
          },
        },
      ],
    }),
      await r.translateAll(),
      await ui.log.end(),
      await this.onBatchTranslationDone(n);
  }),
  (Trans.prototype.translateAllByRows = async function (e, i) {
    console.log("Running trans.translateAll", i),
      ui.loadingProgress(0, "Running trans.translateAll");
    var s = this.getTranslatorEngine(e);
    if (void 0 === trans.project)
      return trans.alert(t("Unable to process, project not found"));
    if (void 0 === trans.project.files)
      return trans.alert(t("Unable to process, data not found"));
    if (void 0 === s) return trans.alert(t("Translation engine not found"));
    if (s.isDisabled)
      return trans.alert(t("Translation engine ") + e + t(" is disabled!"));
    trans.getSelectedId() ||
      trans.selectFile($(".fileList .data-selector").eq(0)),
      ((i = i || {}).onFinished = i.onFinished || function () {}),
      (i.keyColumn = i.keyColumn || 0),
      (i.translateOther = i.translateOther || !1),
      (i.ignoreTranslated = i.ignoreTranslated || !1),
      (i.overwrite = i.overwrite || !1),
      (i.saveOnEachBatch = i.saveOnEachBatch || !1),
      (s.job = s.job || {}),
      (s.job.wordcache = {}),
      (s.job.batch = []),
      (s.batchDelay = s.batchDelay || trans.config.batchDelay);
    var n,
      r = trans.config.maxRequestLength,
      o =
        (s.maxRequestLength < r && (r = s.maxRequestLength),
        ui.showLoading({
          buttons: [
            {
              text: "Abort",
              onClick: function (e) {
                confirm(t("Are you sure want to abort this process?")) &&
                  trans.abortTranslation();
              },
            },
            {
              text: "Pause",
              onClick: function (e) {
                alert(t("Process paused!\nPress OK to continue!"));
              },
            },
          ],
        }),
        ui.log("Start batch translation in Row by Row mode, with options:", i),
        ui.log("Translator is: " + e),
        console.log("Current maximum request length : " + r),
        console.log("Start collecting data!"),
        ui.loadingProgress(0, "Start collecting data!"),
        0),
      a = 0,
      l = {},
      c = trans.getCheckedFiles();
    for (n in (ui.loadingProgress(void 0, t("Selected files :") + c.join(", ")),
    (c = 0 == c.length ? this.getAllFiles() : c))) {
      var d = c[n];
      ui.loadingProgress(void 0, t("Collecting data from :") + d);
      try {
        var g = trans.project.files[d].data;
      } catch (e) {
        console.warn("Can not access", d, "in trans.project.files");
        continue;
      }
      void 0 === s.job.batch[o] && (s.job.batch[o] = []);
      for (var f = 0; f < g.length; f++)
        if (g[f][0]) {
          var u = g[f][i.keyColumn],
            p = str_ireplace(
              $DV.config.lineSeparator,
              s.lineSubstitute,
              s.escapeCharacter(u)
            );
          if (u) {
            if ("blacklist" == i.filterTagMode) {
              if (this.hasTags(i.filterTag, f, d)) continue;
            } else if (
              "whitelist" == i.filterTagMode &&
              !this.hasTags(i.filterTag, f, d)
            )
              continue;
            (i.ignoreTranslated && this.rowHasTranslation(g[f], i.keyColumn)) ||
              (0 == i.overwrite && g[f][s.targetColumn]
                ? console.log(
                    "Ignored because overwite options",
                    i.overwrite,
                    g[f][s.targetColumn]
                  )
                : 0 != u.trim().length &&
                  ((l[u] = g[f][0]),
                  p.length > r
                    ? (console.log(
                        "current sentence is bigger than maxRequestLength!"
                      ),
                      o++,
                      (s.job.batch[o] = s.job.batch[o] || []),
                      s.job.batch[o].push(u),
                      o++,
                      (a = 0))
                    : p.length + a > r
                    ? (o++,
                      (s.job.batch[o] = s.job.batch[o] || []),
                      s.job.batch[o].push(u),
                      (a = 0))
                    : void 0 === s.job.wordcache[u] &&
                      ((s.job.wordcache[u] = !0),
                      (s.job.batch[o] = s.job.batch[o] || []),
                      s.job.batch[o].push(u),
                      (a += p.length))));
          }
        }
    }
    await ui.log("Generating indexes");
    var h = this.buildIndexes(c),
      m =
        ((s.job.batchLength = s.job.batch.length),
        console.log("current batch:", s.job.batch),
        ui.loadingProgress(0, "Data collection is done!"),
        console.log("Data collection is done!"),
        console.log("We have " + s.job.batch.length + " batch totals!"),
        console.log("=========================================="),
        console.log("Begin translating using " + e + "!"),
        async function () {
          if (void 0 === s.job.batch) return "batch job undefined, quiting!";
          if (s.job.batch.length < 1)
            return (
              console.log("Batch job is finished"),
              trans.refreshGrid(),
              trans.evalTranslationProgress(),
              "function" == typeof i.onFinished && i.onFinished.call(this),
              ui.loadingProgress(100, t("Translation finished")),
              ui.loadingClearButton(),
              ui.loadingEnd(),
              trans.onBatchTranslationDone(i),
              (trans.translationTimer = void 0),
              "batch job is finished!"
            );
          console.log("running processPart");
          var e,
            a = s.job.batch.pop();
          console.log("current data : "),
            console.log(a),
            (e = s.skipReferencePair ? a : trans.translateByReference(a)),
            s.translate(e, {
              mode: "rowByRow",
              onAfterLoading: async function (e) {
                if ((console.log(e), void 0 !== e.translation)) {
                  console.log("applying translation to table !"),
                    console.log("calculating progress");
                  var n,
                    r = 100 - (s.job.batch.length / s.job.batchLength) * 100,
                    o =
                      (ui.loadingProgress(
                        r,
                        t("applying translation to table!")
                      ),
                      c);
                  for (n in (i.translateOther && (o = trans.getAllFiles()),
                  trans.trigger("batchTranslationResult", {
                    original: a,
                    translation: e.translation,
                    translator: s,
                  }),
                  e.translation))
                    trans.findAndInsertWithIndexes(
                      l[a[n]],
                      e.translation[n],
                      s.targetColumn,
                      h,
                      {
                        filterTag: i.filterTag || [],
                        filterTagMode: i.filterTagMode,
                        keyColumn: i.keyColumn,
                        overwrite: i.overwrite,
                        files: o,
                      }
                    );
                  i.saveOnEachBatch &&
                    (ui.log("Saving your project"), await trans.save()),
                    ui.loadingProgress(
                      void 0,
                      s.job.batchLength -
                        s.job.batch.length +
                        "/" +
                        s.job.batchLength +
                        " batch done, waiting " +
                        s.batchDelay +
                        " ms..."
                    ),
                    (trans.translationTimer = setTimeout(function () {
                      m();
                    }, s.batchDelay));
                }
              },
              onError: function (e, n, r) {
                console.log("ERROR on transling data");
                var o = 100 - (s.job.batch.length / s.job.batchLength) * 100;
                ui.loadingProgress(
                  o,
                  t("Error when translating data!") +
                    "\r\n" +
                    t("\tHTTP Status : ") +
                    e.status +
                    "\r\n" +
                    t("\tError Type : ") +
                    r +
                    "\r\n" +
                    t(
                      "You are probably temporarily banned by your translation service!\r\nPlease use online translation service in moderation\r\nThis usualy fixed by itself within a day or two.\r\n"
                    )
                ),
                  ui.loadingProgress(
                    void 0,
                    s.job.batchLength -
                      s.job.batch.length +
                      "/" +
                      s.job.batchLength +
                      t(" batch done, ") +
                      t("waiting ") +
                      s.batchDelay +
                      t(" ms...")
                  ),
                  (trans.translationTimer = setTimeout(function () {
                    m();
                  }, s.batchDelay));
              },
            });
        });
    m();
  }),
  (Trans.prototype.translateAllByLines = async function (e, i) {
    console.log("Running trans.translateAllByLines", arguments),
      ui.loadingProgress(0, t("Running trans.translateAll"));
    var s = this.getTranslatorEngine(e);
    if (void 0 === trans.project)
      return trans.alert(t("Unable to process, project not found"));
    if (void 0 === trans.project.files)
      return trans.alert(t("Unable to process, data not found"));
    if (void 0 === s) return trans.alert(t("Translation engine not found"));
    if (s.isDisabled)
      return trans.alert(t("Translation engine ") + e + t(" is disabled!"));
    trans.getSelectedId() ||
      trans.selectFile($(".fileList .data-selector").eq(0)),
      ((i = i || {}).onFinished = i.onFinished || function () {}),
      (i.keyColumn = i.keyColumn || 0),
      (i.translateOther = i.translateOther || !1),
      (i.ignoreTranslated = i.ignoreTranslated || !1),
      (i.overwrite = i.overwrite || !1),
      (i.saveOnEachBatch = i.saveOnEachBatch || !1);
    var n,
      r = i.ignoreTranslated ? "untranslated" : "both",
      o =
        ((s.job = s.job || {}),
        (s.job.wordcache = {}),
        (s.job.batch = []),
        (s.batchDelay = s.batchDelay || trans.config.batchDelay),
        trans.config.maxRequestLength),
      a =
        (s.maxRequestLength < o && (o = s.maxRequestLength),
        ui.showLoading({
          buttons: [
            {
              text: "Abort",
              onClick: function (e) {
                confirm(t("Are you sure want to abort this process?")) &&
                  trans.abortTranslation();
              },
            },
            {
              text: "Pause",
              onClick: function (e) {
                alert(t("Process paused!\nPress OK to continue!"));
              },
            },
          ],
        }),
        ui.log(
          "Start batch translation in Line by Line mode, with options:",
          i
        ),
        ui.log("Translator is: " + e),
        console.log("Current maximum request length : " + o),
        console.log("Start collecting data!"),
        ui.loadingProgress(0, t("Start collecting data!")),
        0),
      l = 0,
      c = trans.getCheckedFiles(),
      d =
        (ui.loadingProgress(void 0, t("Selected files :") + c.join(", ")),
        trans.generateTranslationTableLine(trans.project, {
          files: c,
          mode: "lineByLine",
          fetch: r,
          keyColumn: i.keyColumn,
          filterLanguage: this.getSl(),
          filterTag: i.filterTag || [],
          filterTagMode: i.filterTagMode,
          ignoreTranslated: i.ignoreTranslated,
          targetColumn: s.targetColumn,
          overwrite: i.overwrite,
          ignoreWhitespace: s.ignoreWhitespace,
          collectAddress: !0,
        })),
      g = d.pairs;
    for (n in (console.log("Fetch mode : ", r),
    console.log("Translatable : ", g),
    (l = a = 0),
    g)) {
      s.job.batch[a] = s.job.batch[a] || [];
      var f = n,
        u = str_ireplace(
          $DV.config.lineSeparator,
          s.lineSubstitute,
          s.escapeCharacter(f)
        );
      0 != Boolean(f) &&
        "string" == typeof f &&
        0 != f.trim().length &&
        (u.length > o
          ? (console.log("current sentence is bigger than maxRequestLength!"),
            a++,
            (s.job.batch[a] = s.job.batch[a] || []),
            s.job.batch[a].push(f),
            a++,
            (l = 0))
          : u.length + l > o
          ? (a++,
            (s.job.batch[a] = s.job.batch[a] || []),
            s.job.batch[a].push(f),
            (l = 0))
          : ((s.job.batch[a] = s.job.batch[a] || []),
            s.job.batch[a].push(f),
            (l += u.length)));
    }
    (s.job.batchLength = s.job.batch.length),
      ui.loadingProgress(0, t("Data collection is done!")),
      console.log("Data collection is done!"),
      console.log("We have " + s.job.batch.length + " batch totals!"),
      console.log("=========================================="),
      console.log("Begin translating using " + e + "!"),
      await ui.log("Generating indexes");
    var r = this.buildIndexes(c, !0),
      p =
        (console.log("indexes:", r),
        async function () {
          var e, n;
          return void 0 === s.job.batch
            ? "batch job undefined, quiting!"
            : s.job.batch.length < 1
            ? (console.log("Batch job is finished"),
              (e = []),
              0 == i.translateOther && (e = trans.getCheckedFiles()),
              trans.fillEmptyLine(e, [], s.targetColumn, i.keyColumn, {
                lineFilter: function (e) {
                  return !common.isInLanguage(e, trans.getSl());
                },
                fromKeyOnly: i.ignoreTranslated,
                filterTag: i.filterTag || [],
                filterTagMode: i.filterTagMode,
                overwrite: i.overwrite,
              }),
              trans.refreshGrid(),
              trans.evalTranslationProgress(),
              "function" == typeof i.onFinished && i.onFinished.call(this),
              ui.loadingProgress(100, t("Translation finished")),
              ui.loadingClearButton(),
              ui.loadingEnd(),
              trans.onBatchTranslationDone(i),
              (trans.translationTimer = void 0),
              "batch job is finished!")
            : ((n = async function () {
                console.log("running processPart");
                var e,
                  o = [],
                  a =
                    (0 == i.translateOther && (o = trans.getCheckedFiles()),
                    trans.fillEmptyLine(o, [], s.targetColumn, i.keyColumn, {
                      lineFilter: function (e) {
                        return !common.isInLanguage(e, trans.getSl());
                      },
                      fromKeyOnly: i.ignoreTranslated,
                      filterTag: i.filterTag || [],
                      filterTagMode: i.filterTagMode,
                      overwrite: i.overwrite,
                    }),
                    s.job.batch.pop());
                console.log("current data : "),
                  console.log(a),
                  (e = s.skipReferencePair ? a : trans.translateByReference(a)),
                  s.translate(e, {
                    onAfterLoading: async function (e) {
                      if (
                        (console.log("onAfterLoading translation result:", e),
                        void 0 !== e.translation)
                      ) {
                        console.log("applying translation to table !");
                        var n,
                          r =
                            100 -
                            (s.job.batch.length / s.job.batchLength) * 100;
                        for (n in (ui.loadingProgress(
                          r,
                          t("applying translation to table!")
                        ),
                        trans.trigger("batchTranslationResult", {
                          original: a,
                          translation: e.translation,
                          translator: s,
                        }),
                        e.translation))
                          trans.findAndInsertWithIndexes(
                            a[n],
                            e.translation[n],
                            s.targetColumn,
                            d.addresses,
                            {
                              files: o,
                              keyColumn: i.keyColumn,
                              stripCarriageReturn: !0,
                              filterTag: i.filterTag || [],
                              filterTagMode: i.filterTagMode,
                              overwrite: i.overwrite,
                              lineByLine: !0,
                            }
                          );
                        i.saveOnEachBatch &&
                          (ui.log("Saving your project"), await trans.save()),
                          ui.loadingProgress(
                            void 0,
                            s.job.batchLength -
                              s.job.batch.length +
                              "/" +
                              s.job.batchLength +
                              " batch done!"
                          ),
                          p();
                      }
                    },
                    onError: function (e, n, r) {
                      console.log("ERROR on transling data");
                      var o =
                        100 - (s.job.batch.length / s.job.batchLength) * 100;
                      ui.loadingProgress(
                        o,
                        t("Error when translating data!") +
                          "\r\n" +
                          t("\tHTTP Status : ") +
                          e.status +
                          "\r\n" +
                          t("\tError Type : ") +
                          r +
                          "\r\n" +
                          t(
                            "You are probably temporarily banned by your translation service!\r\nPlease use online translation service in moderation\r\nThis usualy fixed by itself within a day or two.\r\n"
                          )
                      ),
                        ui.loadingProgress(
                          void 0,
                          s.job.batchLength -
                            s.job.batch.length +
                            "/" +
                            s.job.batchLength +
                            " batch done!"
                        ),
                        p();
                    },
                  });
              }),
              void (s.job.batchLength == s.job.batch.length
                ? n()
                : (ui.loadingProgress(
                    void 0,
                    "Waiting " + s.batchDelay + " ms..."
                  ),
                  (trans.translationTimer = setTimeout(function () {
                    n();
                  }, s.batchDelay)))));
        });
    p();
  }),
  (Trans.prototype.onBatchTranslationDone = function (e) {
    var t;
    e.playSoundOnComplete &&
      (t = new Audio("/www/audio/done.mp3")).addEventListener(
        "canplay",
        (e) => {
          t.play();
        }
      );
  }),
  (Trans.prototype.getTranslatorEngine = function (e) {
    return (
      TranslatorEngine.translators[e] ||
      (this[e] instanceof TranslatorEngine
        ? this[e]
        : e instanceof TranslatorEngine
        ? e
        : void console.warn(e, " is not a translator engine"))
    );
  }),
  (Trans.prototype.getActiveTranslatorEngine = function () {
    return this.getTranslatorEngine(this.getActiveTranslator());
  }),
  (Trans.prototype.setActiveTranslator = function (e) {
    (e = "string" == typeof e ? this.getTranslatorEngine(e) : e)?.id &&
      this.setOption("translator", e.id);
  }),
  (Trans.prototype.translateSelection = async function (n, r = {}) {
    this.buildIndex("Common Reference", !0);
    var o = this;
    if (void 0 === (n = n || o.grid.getSelectedRange() || [[]]))
      return alert(t("nothing is selected")), !1;
    if (void 0 === o.translator || o.translator.length < 1)
      return alert(t("no translator loaded")), !1;
    var a = r.translatorEngine || this.getActiveTranslatorEngine();
    if (
      ((r.mode ||= a.mode),
      (r.ignoreWhitespace ||= a.ignoreWhitespace),
      console.log("translating selection ", r.mode),
      1 == a.isDisabled)
    )
      return alert(a.id + " is disabled!");
    ui.tableCornerShowLoading();
    for (
      var i = [],
        e = o.grid.getData(),
        s = common.gridSelectedCells() || [],
        l = [],
        c = 0;
      c < s.length;
      c++
    )
      s[c].col != this.keyColumn && l.push(e[s[c].row][this.keyColumn]);
    if (l) {
      console.log("Text pool", l);
      var d,
        g,
        f = o.generateTranslationTableFromStrings(l, a, r);
      for (d in (console.log(
        "Translation table:",
        JSON.stringify(f, void 0, 2)
      ),
      (f = (await this.processWith("translationTableFilter", f, a)) || f),
      console.warn("Filtered translationTable", JSON.stringify(f, void 0, 2)),
      f.include))
        i.push(d);
      console.log(i),
        console.log(s),
        s.length < 1
          ? ui.tableCornerHideLoading()
          : ((g = a.skipReferencePair ? i : o.translateByReference(i)),
            console.log("Translate using : ", a.id),
            a.translate(g, {
              onAfterLoading: async function (e) {
                console.log("Translation result:"),
                  console.log(e),
                  console.log("text pool :"),
                  console.log(i),
                  console.log("rowpool:"),
                  console.log(s),
                  console.log("translation result : "),
                  o.trigger("batchTranslationResult", {
                    original: i,
                    translation: e.translation,
                    translator: a,
                  });
                e = o.generateTranslationTableFromResult(
                  i,
                  e.translation,
                  f.exclude
                );
                console.log("translation table : "),
                  console.log(e),
                  o.applyTransTableToSelectedCell(e, n, void 0, r),
                  ui.tableCornerHideLoading(),
                  o.grid.render(),
                  o.evalTranslationProgress(),
                  o.textEditorSetValue(o.getTextFromLastSelected());
              },
            }));
    }
  }),
  (Trans.prototype.translateSelectionByRow = async function (e, t = {}) {
    return (t.mode = "rowByRow"), this.translateSelection(e, (t = {}));
  }),
  (Trans.prototype.translateSelectionByLine = async function (e, t = {}) {
    return (t.mode = "lineByLine"), this.translateSelection(e, (t = {}));
  }),
  (Trans.prototype.translateSelectionAsOneLine = async function (o, e = {}) {
    if (
      (console.log("Merge to one line then translate"),
      void 0 === (o = o || trans.grid.getSelectedRange() || [[]]))
    )
      return alert(t("nothing is selected")), !1;
    if (void 0 === trans.translator || trans.translator.length < 1)
      return alert(t("no translator loaded")), !1;
    for (
      var e = e.translatorEngine || this.getActiveTranslatorEngine(),
        a = this.getSelectedOriginalTexts(o),
        n = this.getSelectedOriginalTextsAsOneLine(o),
        r = common.gridSelectedRows(o),
        i = {},
        s = 0;
      s < r.length;
      s++
    )
      i[r[s]] = s;
    console.log("Row index:", i);
    var l = this.getData();
    console.log("Original text:", a),
      ui.tableCornerShowLoading(),
      (n = e.skipReferencePair ? n : trans.translateByReference(n)),
      console.log("Translating", n),
      e.translate(n, {
        mode: "rowByRow",
        onAfterLoading: (e) => {
          if (void 0 !== e.translation) {
            console.log("result translation:", e.translation);
            for (
              var t = common.cloneFormatting(a, e.translation.join(" ")),
                n =
                  (console.log("Formatted result:", t),
                  console.log(
                    "Write back the translated result according to the row"
                  ),
                  common.gridSelectedCells(o)),
                r = 0;
              r < n.length;
              r++
            )
              n[r].col != this.keyColumn &&
                (l[n[r].row][n[r].col] = t[i[n[r].row]]);
          }
          ui.tableCornerHideLoading(),
            trans.grid.render(),
            trans.evalTranslationProgress(),
            trans.textEditorSetValue(trans.getTextFromLastSelected());
        },
      });
  }),
  (Trans.prototype.translateSelectionIntoDef = function (e) {
    if (
      (console.log("translating selection into default coloumn"),
      void 0 === (e = e || trans.grid.getSelected() || [[]]))
    )
      return alert(t("nothing is selected")), !1;
    if (void 0 === trans.translator || trans.translator.length < 1)
      return alert(t("no translator loaded")), !1;
    for (var n = [], r = trans.grid.getData(), o = [], a = 0; a < e.length; a++)
      for (var i = e[a][0]; i <= e[a][2]; i++) o.push(i), n.push(r[i][0]);
    var s = n;
    console.log(s), console.log(o);
    for (var l = 0; l < trans.translator.length; l++) {
      console.log(l);
      var c = trans.translator[l],
        d = this.getTranslatorEngine(c);
      1 != d.isDisabled &&
        (void 0 === d.targetColumn
          ? console.warn(
              "Skipping. Reason : TargetColumn property is not set for engine ",
              c
            )
          : ((c = trans.translateByReference(s)),
            d.translate(c, {
              onAfterLoading: function (e) {
                if (void 0 !== e.translation)
                  for (var t in e.translation)
                    trans.data[o[t]][d.targetColumn] = e.translation[t];
                trans.grid.render(), trans.evalTranslationProgress();
              },
            })));
    }
  }),
  (Trans.prototype.applyTransTableToSelectedCell = function (n, e, r, o) {
    if (
      ((r = r || trans.data),
      (e = e || trans.grid.getSelected() || [[]]),
      ((o = o || {}).indexKey = o.indexKey || 0),
      void 0 === e)
    )
      return alert(t("nothing is selected")), !1;
    var a = common.gridSelectedCells(e) || [];
    if ("rowByRow" == o.mode)
      for (let e = 0; e < a.length; e++) {
        var i = a[e].col,
          s = a[e].row;
        i != this.keyColumn &&
          0 != Array.isArray(r[s]) &&
          (r[s][i] = n[r[s][o.indexKey]]);
      }
    else
      for (let e = 0; e < a.length; e++) {
        var l = a[e].col,
          c = a[e].row;
        l != this.keyColumn &&
          0 != Array.isArray(r[c]) &&
          (r[c][l] = this.translateTextByLine(r[c][o.indexKey], n));
      }
  }),
  (Trans.prototype.translateSelectedRow = function (e, n) {
    return (
      void 0 !== e &&
      0 != trans.config.autoTranslate &&
      !!(e = trans.data[e][(n = n || 0)]) &&
      ((n = $("#translationPane")[0].contentWindow),
      (n = ui.windows.translator ? ui.windows.translator : n).translator
        ? (n.translator.translateAll(e), !0)
        : t("unable to load translator window"))
    );
  }),
  (Trans.prototype.getTranslationByIndex = function (e) {
    var t;
    return (
      void 0 !== e &&
      ((t = $("#translationPane")[0].contentWindow),
      (t = ui.windows.translator ? ui.windows.translator : t)
        .$(".mainPane .portlet")
        .eq(e)
        .find(".portlet-content")
        .text())
    );
  }),
  (Trans.prototype.importTranslation = async function (r, f) {
    if ((console.log("importTranslation", arguments), void 0 === r))
      return trans.alert(t("Reference path cannot empty!"));
    ((f = f || {}).targetColumn = f.targetColumn || 1),
      (f.overwrite = f.overwrite || !1),
      (f.files = f.files || []),
      (f.destination = f.destination || []),
      (f.compareMode = f.compareMode || 0),
      (f.ignoreLangCheck = !0),
      (f.destinationMode = f.destinationMode || "selected"),
      (f.caseInsensitive ||= !1),
      console.log("refPath & options : "),
      console.log(arguments),
      trans.getSelectedId() ||
        trans.selectFile($(".panel-left .fileList .data-selector").eq(0));
    var u = void 0,
      o =
        (f.caseInsensitive &&
          (u = function (e) {
            return e.toLowerCase().replaceAll("\r", "");
          }),
        async (n) => {
          console.log("Applying translation"),
            ui.loadingProgress(30, t("Collecting translation refference")),
            await ui.log("Collecting translation refference");
          var r,
            o = {};
          if ("lineByLine" == f.compareMode) {
            o = trans.generateTranslationTableLine(n.project.files, f);
            let e;
            "selected" == f.destinationMode && (e = this.getCheckedFiles()),
              (r = this.buildIndexes(e, !0, { customFilter: u }));
          } else if ("rowByRow" == f.compareMode) {
            o = trans.generateTranslationTable(n.project.files, f);
            let e;
            "selected" == f.destinationMode && (e = this.getCheckedFiles()),
              (r = this.buildIndexes(e, !1, { customFilter: u }));
          } else
            "contextTrans" == f.compareMode &&
              (o = trans.generateContextTranslationPair(n.project.files, f));
          n = trans.mergeReference(n);
          var e = Object.keys(o).length,
            a =
              (await ui.log(`Processing ${e} reference(s)`),
              ui.loadingProgress(50, t("Applying translation!")),
              0),
            i = 50;
          if ("lineByLine" == f.compareMode)
            for (var s in o) {
              var l = s;
              f.caseInsensitive && (s = u(s)),
                trans.findAndInsertWithIndexes(s, o[l], f.targetColumn, r, {
                  overwrite: f.overwrite,
                  files: f.destination,
                  lineByLine: !0,
                  customFilter: u,
                }),
                ui.loadingProgress(50 + (a / e) * 50),
                a++;
            }
          else if ("rowByRow" == f.compareMode)
            for (var c in (console.log("Row by Row translation"), o)) {
              var d = c,
                c =
                  (f.caseInsensitive && (c = u(c)),
                  trans.findAndInsertWithIndexes(c, o[d], f.targetColumn, r, {
                    overwrite: f.overwrite,
                    files: f.destination,
                    insensitive: !0,
                    customFilter: u,
                  }),
                  Math.round(50 + (a / e) * 50));
              i < c &&
                (ui.loadingProgress(50 + (a / e) * 50),
                await ui.log(`Handled: ${a}/` + e),
                (i = c)),
                a++;
            }
          else if ("contextTrans" == f.compareMode)
            for (var g in (console.log("Translation by context"), o))
              trans.findAndInsertByContext(g, o[g], f.targetColumn, {
                overwrite: f.overwrite,
                files: f.destination,
              }),
                ui.loadingProgress(50 + (a / e) * 50),
                a++;
          else
            "copyByRow" == f.compareMode &&
              this.copyTranslationToRow(n.project.files, f.targetColumn, f);
          trans.trigger("onAfterImportTranslations", {
            options: f,
            loadedData: n,
            refTranslation: o,
          }),
            await common.wait(20),
            trans.evalTranslationProgress(),
            trans.refreshGrid(),
            ui.loadingProgress(100, "Done!"),
            ui.loadingEnd();
        });
    if (
      (ui.showLoading(),
      ui.loadingProgress(0, t("Importing translation")),
      await common.wait(200),
      "object" == typeof r && void 0 !== r.project)
    )
      return console.log("refPath is an object : "), await o(r), !0;
    console.log("Opening " + r),
      fs.readFile(r, async function (e, n) {
        if (e)
          throw (
            (console.log("error opening file : " + r),
            (n = n.toString()),
            "function" == typeof f.onFailed && f.onFailed.call(trans, n),
            e)
          );
        ui.loadingProgress(20, t("Parsing data")),
          await ui.log("Parsing data"),
          await common.wait(200),
          (n = n.toString());
        e = JSON.parse(n);
        console.log("Result data : "),
          console.log(e),
          o(e),
          console.log("Done!"),
          "function" == typeof f.onSuccess && f.onSuccess.call(trans, e),
          (trans.isOpeningFile = !1);
      });
  }),
  (Trans.prototype.translateAllBySelectedCells = async function (e, t, n) {
    (e = e || this.grid.getSelectedRange() || [[]]),
      (t = t || this.getSelectedId()),
      (n = n || {}),
      ui.showBusyOverlay(),
      await common.wait(100);
    var r,
      o = this.getAllFilesExcept([t]),
      a = this.generateSelectedTranslationTable(e, t, n),
      i = (console.log("Selected transtable", a), this.buildIndexes(o)),
      s = [];
    for (r in a) {
      var l = this.getFromIndexes(r, i);
      if (l)
        for (var c = 0; c < l.length; c++)
          for (
            var d = l[c], g = this.getData(d.file), f = 0;
            f < a[r].length;
            f++
          ) {
            var u = a[r][f],
              p = g[d.row][u.col];
            u.col != this.keyColumn &&
              ((g[d.row][u.col] = u.value),
              s.push({
                file: d.file,
                row: d.row,
                col: u.col,
                oldValue: p,
                newValue: u.value,
              }));
          }
    }
    return ui.hideBusyOverlay(), s;
  }),
  (Trans.prototype.getSelectedTexts = function (e, t) {
    (e = e || this.grid.getSelectedRange() || [[]]),
      (t = t || this.getSelectedId());
    for (
      var n = this.getData(t), r = common.gridSelectedCells(e), o = [], a = 0;
      a < r.length;
      a++
    )
      o.push(n[r[a].row][r[a].col] || "");
    return o;
  }),
  (Trans.prototype.getText = function (e, t, n) {
    return (n ? trans.getObjectById(n) : this.data)?.[e]?.[t];
  }),
  (Trans.prototype.getCellComment = function (e, t, n) {
    let r;
    if ((r = n ? this.getObjectById(n) : this.getSelectedObject()).comments)
      return r.comments?.[e]?.[t];
  }),
  (Trans.prototype.getSelectedOriginalTexts = function (e, t) {
    (e = e || this.grid.getSelectedRange() || [[]]),
      (t = t || this.getSelectedId());
    for (
      var n = this.getData(t), r = common.gridSelectedCells(e), o = [], a = 0;
      a < r.length;
      a++
    )
      o.push(n[r[a].row][this.keyColumn] || "");
    return o;
  }),
  (Trans.prototype.getSelectedTextsAsOneLine = function (e, t) {
    return (this.getSelectedTexts(e, t) || [])
      .join(" ")
      .replaceAll("\r", "")
      .replaceAll("\n", " ");
  }),
  (Trans.prototype.getSelectedOriginalTextsAsOneLine = function (e, t) {
    (e = e || this.grid.getSelectedRange() || [[]]),
      (t = t || this.getSelectedId());
    for (
      var n = this.getData(t), r = common.gridSelectedRows(), o = [], a = 0;
      a < r.length;
      a++
    )
      o.push(n[r[a]][this.keyColumn] || "");
    return o.join(" ");
  }),
  (Trans.prototype.getSelectedId = function () {
    return !!trans.project && trans.project?.selectedId;
  }),
  (Trans.prototype.getSelectedContext = function (t) {
    t = t || trans.lastSelectedCell[0];
    var n = trans.getSelectedObject().context;
    try {
      return n[t];
    } catch (e) {
      return (n[t] = []), n[t];
    }
  }),
  (Trans.prototype.getSelectedParameters = function () {
    var e, t;
    if (trans.lastSelectedCell)
      return (
        (e = trans.lastSelectedCell[0]),
        ((t = trans.getSelectedObject()).parameters = t.parameters || []),
        (t.parameters[e] = t.parameters[e] || []),
        t.parameters[e]
      );
  }),
  (Trans.prototype.getParamatersByRow = function (e, t) {
    return (
      (t = t || this.getSelectedId()),
      "number" == typeof e &&
        !!(t = trans.getObjectById(t))?.parameters &&
        t.parameters[e]
    );
  }),
  (Trans.prototype.setParametersByRow = function (e, t, n) {
    n = n || this.getSelectedId();
    n = this.getObjectById(n);
    (n.parameters = n.parameters || []), (n.parameters[e] = t);
  }),
  (Trans.prototype.getRowInfoText = function (e, t = !1, n = "", r = !1) {
    n = n || this.getSelectedId();
    var o = this.getParamatersByRow(e, n);
    if (!o) return "";
    var a,
      i,
      s = (this.getOption("gridInfo") || {}).referenceName || "Actor Reference";
    if (t) {
      for (var l in ((a = []), o))
        o[l] &&
          "object" == typeof o[l] &&
          (r
            ? o[l].rowInfoText && a.push(o[l].rowInfoText)
            : o[l].rowInfoText &&
              a.push(this.translateByReference(o[l].rowInfoText, !1, s)));
      return [...new Set(a)].join(", ");
    }
    for (i in ((a = ""), o))
      if (o[i] && "object" == typeof o[i]) {
        if (a) return a + "++";
        r
          ? o[i].rowInfoText && (a = o[i].rowInfoText)
          : o[i].rowInfoText &&
            (a = this.translateByReference(o[i].rowInfoText, !1, s));
      }
    return a;
  }),
  (Trans.prototype.setRowInfoText = function (e, t, n) {
    n = n || this.getSelectedId();
    e = this.getParamatersByRow(e, n);
    return !!e && ((e[0] ||= {}), (e[0].rowInfoText = t), !0);
  }),
  (Trans.prototype.getSelectedKeyText = function (e) {
    e = e || trans.lastSelectedCell[0];
    try {
      return trans.getSelectedObject().data[e][trans.keyColumn];
    } catch (e) {}
  }),
  (Trans.prototype.getSelectedObject = function () {
    var e;
    return (
      0 != $(".fileList .selected").length &&
      ((e = trans.getSelectedId()), trans.project.files[e])
    );
  }),
  (Trans.prototype.getObjectById = function (e) {
    if (e)
      try {
        return trans.project?.files?.[e];
      } catch (e) {
        console.warn(e);
      }
  }),
  (Trans.prototype.getCheckedFiles = function () {
    for (
      var e = [],
        t = $(".fileList .data-selector .fileCheckbox:checked"),
        n = 0;
      n < t.length;
      n++
    )
      e.push(t.eq(n).attr("value"));
    return e;
  }),
  (Trans.prototype.getCheckedObjects = function () {
    for (
      var e = {},
        t = $(".fileList .data-selector .fileCheckbox:checked"),
        n = 0;
      n < t.length;
      n++
    ) {
      var r = t.eq(n).attr("value");
      e[r] = this.getObjectById(r);
    }
    return e;
  }),
  (Trans.prototype.getAllFiles = function (e, t) {
    var n = [];
    if (void 0 !== (e = e || trans?.project?.files))
      if ((e?.project?.files && (e = e?.project?.files), t))
        for (var r in e) "*" != e[r]?.dirname && n.push(r);
      else for (var o in e) n.push(o);
    return n;
  }),
  (Trans.prototype.getAllFilesExcept = function (e, t) {
    e = (e = "string" == typeof e ? [e] : e) || [];
    var n,
      r = [];
    for (n in (t = t || trans.project.files)) e.includes(n) || r.push(n);
    return r;
  }),
  (Trans.prototype.getAllCompletedFiles = function (e) {
    var t = [];
    if (void 0 !== (e = e || this.project.files))
      for (var n in e)
        "object" == typeof e[n] &&
          "object" == typeof e[n].progress &&
          100 == e[n].progress.percent &&
          t.push(n);
    return t;
  }),
  (Trans.prototype.getAllIncompletedFiles = function (e) {
    var t = [];
    if (void 0 !== (e = e || this.project.files))
      for (var n in e)
        "object" == typeof e[n] &&
          "object" == typeof e[n].progress &&
          e[n].progress.percent < 100 &&
          t.push(n);
    return t;
  }),
  (Trans.prototype.getAllMarkedAsCompleted = function (e) {
    var t = [];
    if (void 0 !== (e = e || this.project.files))
      for (var n in e)
        "object" == typeof e[n] &&
          "object" == typeof e[n].progress &&
          e[n].isCompleted &&
          t.push(n);
    return t;
  }),
  (Trans.prototype.getAttachmentContent = function (e) {
    if (e && trans.project?.attachments?.[e])
      return trans.project.attachments[e].data;
  }),
  (Trans.prototype.scrollHToCol = function (e) {
    var t = $("#table .ht_master .wtHolder");
    if (!e) return (t[0].scrollLeft = 0);
    for (
      var n = $("#table .ht_master .wtHolder colgroup col"), r = 0, o = 1;
      o < e;
      o++
    )
      r += n.eq(o + 1).outerWidth();
    console.log(r), (t[0].scrollLeft = r);
  }),
  (Trans.prototype.goTo = function (e, t, n) {
    console.log(arguments),
      (n = n || this.getSelectedId()),
      this.grid.deselectCell(),
      n !== this.getSelectedId() &&
        ((n = this.selectFile(n)), $(n)[0].scrollIntoView({ block: "center" })),
      this.grid.selectCell(e, t, e, t),
      this.grid.scrollViewportTo(e, t),
      this.scrollHToCol(t);
  }),
  (Trans.prototype.getLastSelectedCell = function () {
    return this.lastSelectedCell;
  }),
  (Trans.prototype.goToNextUntranslated = function () {
    for (
      var e = this.getLastSelectedCell(),
        t = this.getCurrentData(),
        n = e[0] + 1,
        r = (n = n >= t.length ? 0 : n);
      r < t.length && this.rowHasTranslation(t[r]);
      r++
    );
    return t.length <= r && (r = t.length - 1), this.goTo(r, e[1]);
  }),
  (Trans.prototype.goToPreviousUntranslated = function () {
    var e = this.getLastSelectedCell(),
      t = this.getCurrentData(),
      n = e[0] - 1;
    n <= 0 && (n = t.length - 1), console.log("starting", n);
    for (var r = n; 0 <= r && this.rowHasTranslation(t[r]); r--);
    return console.log("Move to row", r), this.goTo((r = r < 0 ? 0 : r), e[1]);
  }),
  (Trans.prototype.search = function (n, r) {
    var e = require("glob-to-regexp");
    if ((console.log("entering trans.search", arguments), void 0 === n))
      return null;
    if (typeof n.length <= 1) return "Keyword too short!";
    if (void 0 === trans.project) return null;
    if (void 0 === trans.project.files) return null;
    if (
      (((r = r || {}).caseSensitive = r.caseSensitive || !1),
      (r.lineMatch = r.lineMatch || !1),
      (r.isRegexp = r.isRegexp || !1),
      (r.searchLocations = r.searchLocations || []),
      0 == r.searchLocations.length && (r.searchLocations = ["grid"]),
      r.lineMatch && (r.searchInContext = !1),
      0 == Array.isArray(r.files))
    )
      for (var o in ((r.files = []), trans.project.files)) r.files.push(o);
    0 == r.caseSensitive && 0 == r.isRegexp && (n = n.toLowerCase());
    var a = new Date().getTime(),
      i = {
        keyword: n,
        count: 0,
        isRegexp: r.isRegexp,
        executionTime: 0,
        files: {},
      };
    if (r.isRegexp) {
      if (0 == (l = common.evalRegExpStr(n)))
        return (
          alert(
            n +
              t(
                " is not a valid javascript's regexp!\r\nFind out more about Javascipt's Regular Expression at :\r\nhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions"
              )
          ),
          i
        );
    } else if (n.includes("*"))
      try {
        var s = e(n)
            .toString()
            .replace(/\/\^(.*?)\$\//, "$1"),
          l = new RegExp(s, "i");
        console.log("Glob style keyword detected", l);
      } catch (e) {
        console.warn("Error when converting glob pattern to RegExp");
      }
    if (r.lineMatch) {
      for (var c in r.files) {
        var d = r.files[c];
        if (0 != Array.isArray(trans.project.files[d].data)) {
          var g = trans.project.files[d].data;
          for (let t = 0; t < g.length; t++)
            if (0 != g[t].length)
              for (let e = 0; e < g[t].length; e++)
                if ("string" == typeof g[t][e])
                  if (l) {
                    if (l.test(g[t][e])) {
                      var f = common.lineIndexRegExp(g[t][e], l);
                      (i.files[d] = i.files[d] || []),
                        i.files[d].push({
                          fullString: g[t][e],
                          row: t,
                          col: e,
                          type: "cell",
                          lineIndex: f,
                        }),
                        i.count++;
                      break;
                    }
                  } else {
                    if (r.caseSensitive) {
                      if (-1 == g[t][e].indexOf(n)) continue;
                    } else if (-1 == g[t][e].toLowerCase().indexOf(n)) continue;
                    f = common.lineIndex(g[t][e], n, r.caseSensitive);
                    if (-1 != f) {
                      (i.files[d] = i.files[d] || []),
                        i.files[d].push({
                          fullString: g[t][e],
                          row: t,
                          col: e,
                          type: "cell",
                          lineIndex: f,
                        }),
                        i.count++;
                      break;
                    }
                  }
        }
      }
      e = new Date().getTime();
      i.executionTime = e - a;
    } else {
      if (
        (console.log("Search location:", r.searchLocations),
        r.searchLocations.includes("grid"))
      )
        for (var u in r.files) {
          var p = r.files[u];
          if (0 != Array.isArray(trans.project.files[p].data)) {
            var h = trans.project.files[p].data;
            for (let t = 0; t < h.length; t++)
              if (0 != h[t].length)
                for (let e = 0; e < h[t].length; e++)
                  if ("string" == typeof h[t][e])
                    if (l) {
                      if (l.test(h[t][e])) {
                        (i.files[p] = i.files[p] || []),
                          i.files[p].push({
                            fullString: h[t][e],
                            row: t,
                            col: e,
                            type: "cell",
                          }),
                          i.count++;
                        break;
                      }
                    } else {
                      if (r.caseSensitive) {
                        if (-1 == h[t][e].indexOf(n)) continue;
                      } else if (-1 == h[t][e].toLowerCase().indexOf(n))
                        continue;
                      (i.files[p] = i.files[p] || []),
                        i.files[p].push({
                          fullString: h[t][e],
                          row: t,
                          col: e,
                          type: "cell",
                        }),
                        i.count++;
                    }
          }
        }
      if (r.searchLocations.includes("context"))
        for (var m in r.files) {
          var y = r.files[m];
          if (0 != Array.isArray(trans.project.files[y].context)) {
            var v = trans.project.files[y].context;
            for (let t = 0; t < v.length; t++)
              if (0 != Array.isArray(v[t]) && 0 != v[t].length)
                for (let e = 0; e < v[t].length; e++)
                  if ("string" == typeof v[t][e]) {
                    if (l) {
                      if (0 == l.test(v[t][e])) continue;
                    } else if (r.caseSensitive) {
                      if (-1 == v[t][e].indexOf(n)) continue;
                    } else if (-1 == v[t][e].toLowerCase().indexOf(n)) continue;
                    (i.files[y] = i.files[y] || []),
                      i.files[y].push({
                        fullString: v[t][e],
                        row: t,
                        col: 0,
                        type: "context",
                      }),
                      i.count++;
                  }
          }
        }
      if (r.searchLocations.includes("tag"))
        for (var T in r.files) {
          var w = r.files[T],
            j = n.split(" "),
            b = trans.project.files[w].data;
          for (let e = 0; e < b.length; e++)
            0 != trans.hasTags(j, e, w) &&
              ((i.files[w] = i.files[w] || []),
              i.files[w].push({
                fullString: b[e][this.keyColumn],
                row: e,
                col: 0,
                type: "cell",
              }),
              i.count++);
        }
      if (r.searchLocations.includes("comment"))
        for (var C in (console.log("searching comment"), r.files)) {
          var x = r.files[C];
          if (0 != Boolean(trans.project.files[x].comments)) {
            var S,
              I = trans.project.files[x].comments;
            for (S in (console.log("processing", x), I))
              if (0 != Boolean(I[S]))
                for (var k in I[S])
                  if ("string" == typeof I[S][k]) {
                    if (l) {
                      if (0 == l.test(I[S][k])) continue;
                    } else if (r.caseSensitive) {
                      if (-1 == I[S][k].indexOf(n)) continue;
                    } else if (-1 == I[S][k].toLowerCase().indexOf(n)) continue;
                    (i.files[x] = i.files[x] || []),
                      i.files[x].push({
                        fullString: I[S][k],
                        row: S,
                        col: k,
                        type: "comment",
                      }),
                      i.count++;
                  }
          }
        }
      s = new Date().getTime();
      i.executionTime = s - a;
    }
    return i;
  }),
  (Trans.prototype.replace = function (n, r, o) {
    if ((console.log("entering trans.search"), void 0 === n)) return null;
    if (typeof n.length <= 1) return t("Keyword too short!");
    if (void 0 === trans.project) return null;
    if (void 0 === trans.project.files) return null;
    if (
      ((r = r || ""),
      ((o = o || {}).caseSensitive = o.caseSensitive || !1),
      (o.isRegexp = o.isRegexp || !1),
      0 == Array.isArray(o.files))
    )
      for (var e in ((o.files = []), trans.project.files)) o.files.push(e);
    0 == o.caseSensitive && 0 == o.isRegexp && (n = n.toLowerCase());
    var a,
      i = new Date().getTime(),
      s = {
        keyword: n,
        count: 0,
        isRegexp: o.isRegexp,
        executionTime: 0,
        files: {},
      };
    if (o.isRegexp) {
      var l = common.evalRegExpStr(n);
      if (0 == l)
        return (
          alert(
            n +
              t(
                " is not a valid javascript's regexp!\r\nFind out more about Javascipt's Regular Expression at :\r\nhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions"
              )
          ),
          s
        );
    }
    for (a in o.files) {
      var c = o.files[a];
      if (0 != Array.isArray(trans.project.files[c].data)) {
        var d = trans.project.files[c].data;
        for (let t = 0; t < d.length; t++)
          if (0 != d[t].length)
            for (let e = 1; e < d[t].length; e++)
              if ("string" == typeof d[t][e])
                if (o.isRegexp) {
                  if (l.test(d[t][e])) {
                    var g = trans.project.files[c].data[t][e];
                    (trans.project.files[c].data[t][e] = d[t][e].replace(l, r)),
                      (s.files[c] = s.files[c] || []),
                      s.files[c].push({
                        fullString: trans.project.files[c].data[t][e],
                        row: t,
                        col: e,
                        originalString: g,
                      }),
                      s.count++;
                    break;
                  }
                } else {
                  if (o.caseSensitive) {
                    if (-1 == d[t][e].indexOf(n)) continue;
                  } else if (-1 == d[t][e].toLowerCase().indexOf(n)) continue;
                  g = trans.project.files[c].data[t][e];
                  (trans.project.files[c].data[t][e] = d[t][e].replaces(
                    n,
                    r,
                    !o.caseSensitive
                  )),
                    (s.files[c] = s.files[c] || []),
                    s.files[c].push({
                      fullString: trans.project.files[c].data[t][e],
                      row: t,
                      col: e,
                      originalString: g,
                    }),
                    s.count++;
                }
      }
    }
    var f = new Date().getTime();
    return (s.executionTime = f - i), trans.refreshGrid(), s;
  }),
  (Trans.prototype.findPut = function (n, r, o, a) {
    if ((console.log("entering trans.search"), void 0 === n)) return null;
    if (typeof n.length <= 1) return t("Keyword too short!");
    if (void 0 === trans.project) return null;
    if (void 0 === trans.project.files) return null;
    if (o < 1) return !1;
    if (
      (((a = a || {}).caseSensitive = a.caseSensitive || !1),
      (a.lineMatch = a.lineMatch || !1),
      void 0 === a.overwrite && (a.overwrite = !0),
      0 == Array.isArray(a.files))
    )
      for (var e in ((a.files = []), trans.project.files)) a.files.push(e);
    0 == a.caseSensitive && (n = n.toLowerCase());
    var i = new Date().getTime(),
      s = { keyword: n, count: 0, executionTime: 0, files: {} };
    if (n.includes("\n") || "rowByRow" == a.mode)
      console.log("Entering row by row search"),
        (s = this.findAndInsert(n, r, o, {
          insensitive: !a.caseSensitive,
          overwrite: a.overwrite,
        }));
    else
      for (var l in a.files) {
        var c = a.files[l];
        if (0 != Array.isArray(trans.project.files[c].data)) {
          var d = trans.project.files[c].data;
          for (let t = 0; t < d.length; t++)
            if (0 != d[t].length)
              for (let e = 0; e < d[t].length; e++)
                if ("string" == typeof d[t][e]) {
                  if (a.caseSensitive) {
                    if (-1 == d[t][e].indexOf(n)) continue;
                  } else if (-1 == d[t][e].toLowerCase().indexOf(n)) continue;
                  var g = common.lineIndex(d[t][e], n, a.caseSensitive);
                  if (-1 != g) {
                    var f = common.insertLineAt(d[t][o], r, g, {
                      lineBreak: trans.project.files[c].lineBreak || "\n",
                    });
                    (d[t][o] = f),
                      (s.files[c] = s.files[c] || []),
                      s.files[c].push({
                        fullString: d[t][e],
                        row: t,
                        col: e,
                        type: "cell",
                        lineIndex: g,
                      }),
                      s.count++;
                    break;
                  }
                }
        }
      }
    var u = new Date().getTime();
    return (s.executionTime = u - i), trans.refreshGrid(), s;
  });
class TransProjectHook {
  constructor() {
    this.hooks = {};
  }
}
(TransProjectHook.prototype.defineHook = function (e, t) {
  if ("string" != typeof e)
    throw new Error(`hookName must be a string ${typeof e} given`);
  if ("function" != typeof t)
    throw new Error(`hookName must be a function ${typeof t} given`);
  this.hooks[e] = t;
}),
  (TransProjectHook.prototype.getHook = function (e) {
    return this.hooks[e];
  }),
  (TransProjectHook.prototype.run = async function (e, ...t) {
    "function" == typeof this.hooks[e] &&
      (await this.hooks[e].apply(window.trans, t));
    e = trans.getOption("hooks");
    if (e && "string" == typeof e?.afterExport && (await ui.confirmRunScript()))
      return new (Object.getPrototypeOf(async function () {}).constructor)(
        e.afterExport
      ).apply(trans, t);
  });
var trans = new Trans();
((window.trans = trans).cellInfo = new Trans.CellInfo()),
  (trans.projectHook = new TransProjectHook()),
  (trans.gridContextMenu = {
    commentsAddEdit: {
      name: t("Add comment"),
      hidden: function () {
        return (
          !!trans.grid.isColumnHeaderSelected() ||
          !!trans.grid.isRowHeaderSelected()
        );
      },
    },
    commentsRemove: {
      name: t("Delete comment"),
      hidden: function () {
        return (
          !!trans.grid.isColumnHeaderSelected() ||
          !!trans.grid.isRowHeaderSelected()
        );
      },
    },
    sepx: "---------",
    translateThisCell: {
      name: function () {
        var e =
          "<span class='HOTMenuTranslateHere'>" +
          t("Translate here") +
          " <kbd>ctrl+g</kbd></span>";
        if (void 0 === trans.project) return e;
        trans.project.options = trans.project.options || {};
        var n,
          r,
          o = trans.getActiveTranslator();
        return (
          console.log("thisTrans", o),
          void 0 !== o &&
          ((n = trans.getSl() || "??"),
          (r = trans.getTl() || "??"),
          (o = trans.getTranslatorEngine(o)?.name))
            ? t("Translate here using ") +
              o +
              " (" +
              n +
              "<i class='icon-right-bold'></i>" +
              r +
              ") <kbd>ctrl+g</kbd>"
            : e
        );
      },
      callback: function () {
        trans.translateSelection();
      },
      hidden: function () {
        return (
          !!trans.grid.isColumnHeaderSelected() ||
          !!trans.grid.isRowHeaderSelected() ||
          !trans.getActiveTranslator()
        );
      },
    },
    translateUsing: {
      name: function () {
        return trans.drawGridTranslatorMenu(), t("Translate using...");
      },
      submenu: { items: [] },
      hidden: function () {
        return !!trans.grid.isRowHeaderSelected();
      },
    },
    mergeThenTranslate: {
      name: "<span>Merge then translate <kbd>ctrl+shift+g</kbd></span>",
      hidden: function () {
        return !!trans.grid.isRowHeaderSelected();
      },
      callback: async function () {
        trans.translateSelectionAsOneLine();
      },
    },
    translateSimiliar: {
      name: "<span>Translate like this <kbd>ctrl+l</kbd></span>",
      hidden: function () {
        return !!trans.grid.isRowHeaderSelected();
      },
      callback: async function () {
        var e;
        confirm(
          t(
            "Do you want to translate all the same texts found across this project with the translation on the selected cell(s)?"
          )
        ) &&
          ((e = await trans.translateAllBySelectedCells()),
          alert(e.length + t(" cell(s) has been written!")));
      },
    },
    "---------": {},
    columnWidth: {
      name: t("Column width"),
      callback: function (e, n, r) {
        console.log("column width : ", arguments);
        var o = common.gridSelectedCols(),
          a = prompt("Enter new width", this.getColWidth(o[0]));
        if ((a = parseInt(a)) < 1) return alert(t("Width must greater than 0"));
        for (var i = 0; i < o.length; i++) this.setColWidth(o[i], a);
      },
      hidden: function () {
        return (
          !this.isColumnHeaderSelected() && (this.isRowHeaderSelected(), !0)
        );
      },
    },
    sepn: {
      name: "---------",
      hidden: function () {
        return (
          !this.isColumnHeaderSelected() && (this.isRowHeaderSelected(), !0)
        );
      },
    },
    "col-right": {
      name: t("Insert column right"),
      callback: function () {
        trans.grid.insertColumnRight();
      },
      hidden: function () {
        return (
          !trans.grid.isColumnHeaderSelected() &&
          (trans.grid.isRowHeaderSelected(), !0)
        );
      },
    },
    duplicateCol: {
      name: t("Duplicate column"),
      callback: function () {
        var e = trans.grid.getSelected()[0][1],
          t = trans.columns.length,
          n = trans.colHeaders[e] || "New Col";
        trans.columns.push({}),
          common.arrayExchange(trans.columns, t, e + 1),
          common.arrayInsert(trans.colHeaders, e + 1, n),
          console.log(trans.columns),
          trans.insertCell(e + 1, null),
          trans.copyCol(e, e + 1),
          trans.grid.updateSettings({ colHeaders: trans.colHeaders });
      },
      hidden: function () {
        return (
          !trans.grid.isColumnHeaderSelected() ||
          trans.grid.getSelected()[0][1] != trans.grid.getSelected()[0][3] ||
          1 < trans.grid.getSelected().length
        );
      },
    },
    removeColumn: {
      name: t("Remove this column"),
      callback: function (e, n, r) {
        console.log(arguments),
          confirm(t("Remove selected column?\nThis can not be undone!")) &&
            trans.removeColumn(n[0].start.col, { refreshGrid: !0 });
      },
      hidden: function () {
        return (
          !trans.grid.isColumnHeaderSelected() &&
          (trans.grid.isRowHeaderSelected(), !0)
        );
      },
    },
    renameColumn: {
      name: t("Rename this column"),
      callback: function (e, n, r) {
        console.log(arguments);
        var n = n[0].start.col,
          o = trans.colHeaders[n],
          o = prompt(t("Please enter new name"), o);
        o && trans.renameColumn(n, o, { refreshGrid: !0 });
      },
      hidden: function () {
        return (
          !trans.grid.isColumnHeaderSelected() &&
          (trans.grid.isRowHeaderSelected(), !0)
        );
      },
    },
    sep0: "---------",
    tags: {
      name: "Tags",
      submenu: {
        items: [
          {
            key: "tags:red",
            name: '<i class="tag red icon-circle"></i> ' + t("Red"),
            callback: function (e, t, n) {
              trans.setTagForSelectedRow("red", t);
            },
          },
          {
            key: "tags:yellow",
            name: '<i class="tag yellow icon-circle"></i> ' + t("Yellow"),
            callback: function (e, t, n) {
              trans.setTagForSelectedRow("yellow", t);
            },
          },
          {
            key: "tags:green",
            name: '<i class="tag green icon-circle"></i> ' + t("Green"),
            callback: function (e, t, n) {
              trans.setTagForSelectedRow("green", t);
            },
          },
          {
            key: "tags:blue",
            name: '<i class="tag blue icon-circle"></i> ' + t("Blue"),
            callback: function (e, t, n) {
              trans.setTagForSelectedRow("blue", t);
            },
          },
          {
            key: "tags:gold",
            name: '<i class="tag gold icon-circle"></i> ' + t("Gold"),
            callback: function (e, t, n) {
              trans.setTagForSelectedRow("gold", t);
            },
          },
          {
            key: "tags:more",
            name:
              '<i class="tag icon-tags"></i> ' +
              t("More tags...") +
              " <kbd>ctrl+t</kbd>",
            callback: function (e, t, n) {
              ui.taggingDialog(t);
            },
          },
          {
            key: "tags:clear",
            name: '<i class="tag icon-blank"></i> ' + t("Clear tags"),
            callback: function (e, t, n) {
              trans.clearTags(void 0, t), trans.grid.render();
            },
          },
        ],
      },
    },
    sep1: "---------",
    deleteRow: {
      name: function () {
        return t("Delete Row") + " <kbd>shift+del</kbd>";
      },
      callback: function (e, n, r) {
        confirm(t("Do you want to remove the currently selected row(s)?")) &&
          (trans.removeRow(trans.getSelectedId(), common.gridSelectedRows()),
          trans.refreshGrid(),
          trans.grid.deselectCell());
      },
      hidden: function () {
        return (
          !!trans.grid.isColumnHeaderSelected() ||
          (trans.grid.isRowHeaderSelected(), !1)
        );
      },
    },
    clearContextTranslation: {
      name: t("Clear Context Translation") + " <kbd>alt+del</kbd>",
      callback: function (e, t, n) {
        trans.trigger("clearContextTranslationByRow", {
          file: trans.getSelectedId(),
          row: trans.grid.getSelectedRange(),
          type: "range",
        });
      },
      hidden: function () {
        return (
          !!trans.grid.isColumnHeaderSelected() ||
          (trans.grid.isRowHeaderSelected(), !1)
        );
      },
    },
    sep2: "---------",
    createAutomation: {
      name: t("Create Automation"),
      callback: function (e, t, n) {
        console.log(arguments);
        var r = {
          workspace: "gridSelection",
          cellRange: trans.grid.getSelectedRange(),
        };
        ui.openAutomationEditor("codeEditor_gridSelection", r);
      },
    },
    runAutomation: {
      name: () => (trans.updateRunScriptGridMenu(), t("Run Automation")),
    },
    clearAutomation: {
      name: t("Clear Automation"),
      callback: function () {
        confirm(t("Are you sure want to clear all quick launch scripts?")) &&
          (sys.setConfig("codeEditor/gridSelection", { quickLaunch: [] }),
          sys.saveConfig());
      },
    },
    sep3: "---------",
    appendToReference: {
      name: t("Append rows to reference") + " <kbd>ctrl+shift+d</kbd>",
      callback: function (e, t, n) {
        trans.appendSelectedRowToReference();
      },
      hidden: function () {
        return !!trans.grid.isColumnHeaderSelected();
      },
    },
    properties: {
      name: t("Row properties"),
      callback: function (e, t, n) {
        console.log(arguments), ui.openRowProperties();
      },
      hidden: function () {
        return (
          !!trans.grid.isColumnHeaderSelected() ||
          (trans.grid.isRowHeaderSelected(), !1)
        );
      },
    },
  }),
  (trans.fileLoader = new FileLoader()),
  trans.fileLoader.add("json", function (e) {
    trans.open(e);
  }),
  trans.fileLoader.add("trans", function (e) {
    trans.open(e);
  }),
  trans.fileLoader.add("tpp", function (e) {
    trans.importTpp(e);
  }),
  (window.Attachment = function (e) {
    (e = e || {}), Object.assign(this, e);
  }),
  $(document).ready(function () {
    0 != $("body").is('[data-window="trans"]') &&
      (trans.fileSelectorContextMenuInit(),
      $(window).resize(
        debounce(function () {
          $(document).trigger("windowResizeStop"),
            trans.grid.render(),
            ui.fixCellInfoSize();
        }, 100)
      ),
      trans.initTable(),
      (trans.isLoaded = !0),
      trans.on("transLoaded", async () => {
        console.warn("Trans loaded"),
          $(".menu-button > .button-gridInfo.gridInfo").removeClass("checked"),
          trans.getOption("gridInfo")?.isRuleActive &&
            $(".menu-button > .button-gridInfo.gridInfo").addClass("checked");
      }));
  });
update: this new version you mentioned also works in the way I described
Can you at least highlight the suspicious code? To much code and from my superficial inspection i didn't see any malicious external code execution
 
Last edited:

jaden_yuki

Well-Known Member
Jul 11, 2017
1,056
896
Can you at least highlight the suspicious code? To much code and from my superficial inspection i didn't see any malicious external code execution
All the code I shared is executed via eval after being downloaded from a REST API endpoint and then decrypted. it's indeed a lot of code, probably better to just run it in a sandbox. but the thing is: even if there isn't anything malicious now, it can be inserted at any moment, it can be inserted for a brief period of time as well. maybe I'm just being paranoid
 

Hero_Protagonist

New Member
Apr 6, 2024
3
1
All the code I shared is executed via eval after being downloaded from a REST API endpoint and then decrypted. it's indeed a lot of code, probably better to just run it in a sandbox. but the thing is: even if there isn't anything malicious now, it can be inserted at any moment, it can be inserted for a brief period of time as well. maybe I'm just being paranoid
this code is some abridged version (7140 rows then in the original 11423 rows) of the file that exist in the program's folder: www/js/trans.js. I don't know why it don't use existing file and instead downloads this one. Maybe it can't find it for some reason or it was renamed, probably I don't understand how this app loads those scripts. But for some reason it didn't use the existing file.
I am not a javascript developer but I know it is a very bad language for big applications. My textractor++ lags quite often and I even fixed some bugs in earlier versions. Usually modern developers use typescript, javascript for small tasks.
Anyway I think it is just bad infrastructure and nothing malicious is going on behind the scene. If you think it can insert some malicious code then you can block this app from accessing the internet.
 
Last edited:
  • Like
Reactions: jaden_yuki

jaden_yuki

Well-Known Member
Jul 11, 2017
1,056
896
this code is some abridged version (7140 rows then in the original 11423 rows) of the file that exist in the program's folder: www/js/trans.js. I don't know why it don't use existing file and instead downloads this one. Maybe it can't find it for some reason or it was renamed, probably I don't understand how this app loads those scripts. But for some reason it didn't use the existing file.
I am not a javascript developer but I know it is a very bad language for big applications. My textractor++ lags quite often and I even fixed some bugs in earlier versions. Usually modern developers use typescript, javascript for small tasks.
Anyway I think it is just bad infrastructure and nothing malicious is going on behind the scene. If you think it can insert some malicious code then you can block this app from accessing the internet.
here, the original trans.js (~384Kb) gets replaced by a new version (~12Kb), this new version downloads and then execute the code I shared.
 
5.00 star(s) 2 Votes