[
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) [year] [fullname]\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE."
  },
  {
    "path": "README-zh.md",
    "content": "# 标注工具操作文档\n\n## 文件结构\n\n```\n.\n├── input 标注所需文件（可参考示例文件进行自定义）\n├──── video 截帧图片文件夹\n├────── $urlId（以frame.txt内的urlId命名）\n├──────── $frame （以frame.txt内的对应$urlId的frame命名）\n├──── frame.txt (urlId,frame,time)\n├──── label.txt (tagId,tag)\n├──── video.txt (urlId,url)\n├── lib 源码\n└── index.html  软件入口\n```\n\n## 操作\n\n### 一、准备标注文件\n\n> 1、video.txt\n\n```\nurlId,url\n自定义且唯一,youtobe视频id+.mp4\n```\n\n> 2、label.txt\n\n```\ntagId,tag\n自定义且唯一,标签名\n```\n\n> 3、frame.txt\n\n```\nurlId,frame,time\n自定义且唯一与video.txt内的urlId对应,截帧图片名,截帧时间\n```\n\n> 4、video 文件夹\n\n```\nvideo 下的文件夹以 frame.txt 内的 urlId 命名，\n\burlId 内存放截帧图片，并以 frame.txt 内的对应 urlId 的 frame 命名\n```\n\n`注意：`video文件夹 必须放在input文件夹内\n\n### 二、导入标注文件\n\n![](./images/upload.png)\n\n> 1、打开 `index.html`\n\n> 2、依次点击 `upload video file`、`upload label file`、`upload frame file`上传 对应的`video.txt` ，`label.txt`，`frame.txt`文件\n\n> 3、点击 `input` 导入文件（若文件格式错误，将会报错，上传失败）\n\n### 三、开始标注\n\n#### 1）状态列表\n\n![](./images/states.png)\n\n| videoID | videoName | time     | operation |\n| ------- | --------- | -------- | --------- |\n| urldId  | url       | 标注次数 | 操作按钮  |\n\n> 1、unlabeled 未标注\n\n点击 `label` 打开标注页面\n\n点击 `delete` 删除该视频\n\n> 2、labeled 已标注\n\n点击 `checkout` 打开标注页面，进行检查\n\n点击 `delete` 删除该视频\n\n> 3、checked 已检查\n\n点击 `cancle` 取消 checked 状态，视频恢复 `labeled` 状态\n\n> 4、deleted 已检查\n\n点击 `restore` 取消 `deleted` 状态，若 `time>1` 视频恢复 `unlabeled` 状态，若 `time=0` 视频恢复 `labeled` 状态\n\n#### 2）标注页面\n\n##### 图片标注\n\n![](./images/imageLabel.png)\n\n> 操作按钮\n\n1、`setting` 按钮\n\n可配置 `行数` 以及 `截帧间隔`\n\n`注意：`该操作将清空未保存标注信息，请及时保存 \n\n2、`save` 按钮\n\n可保存当前标注信息\n\n3、`delete` 按钮\n\n删除当前视频\n\n> 标注方法\n\n1、选中截帧图片（可跨选：点击 `开始时间` 与 `结束时间` 的两张图片，即可选中该时间段内所有截帧图片）\n\n2、选择并点击 `tags` 部分的标签\n\n3、删除已标注信息：选中已标注的某个图片 或 `labels` 部分的对应信息，点击 `delete tag` 按钮，进行删除\n\n4、结果展示：\n\n    1) 每个截帧图片上方将展示其选中的标签\n    2) 标注结果统一展示在 `labels` 部分\n\n##### 视频标注\n\n![](./images/videoLabel.png)\n\n> 操作按钮\n\n1、`save` 按钮\n\n可保存当前标注信息\n\n2、`delete` 按钮\n\n删除当前视频\n\n> 标注方法\n\n1、点击 上方视频名（video(check to play)： CQcWjWkaSfA.mp4），打开视频标注页面\n\n2、鼠标点击标注条，选中 `开始时间` 与 `结束时间`（对应视频进度条）\n\n3、选择并点击 `tags` 部分的标签\n\n4、删除已标注信息：选中已标注的某段标注条 或 labels部分的对应信息，点击 `delete tag` 按钮，进行删除\n\n5、结果展示：\n\n    1) 当鼠标放在标注条已标注的某段上时，将展示其选中的标签\n    2) 标注结果统一展示在 `labels` 部分\n\n### 四、导出标注文件\n\n点击 `output` 可导出文件（导出文件可作为导入文件进行标注检查）"
  },
  {
    "path": "README.md",
    "content": "# Annotation Tool Usage\n\n## Documents\n\n```\n.\n├── input (Input files)\n├──── video (Extrated frames)\n├────── URLID\n├──────── frame (Check example)\n├──── frame.txt (URLID,Frame,Time)\n├──── label.txt (TagID,Tag)\n├──── video.txt (URLID,URL)\n├── lib (Source code)\n└── coin_annotation_tool.html (Click to label)\n```\n\n## Usage\n\n\n### Load Files \n\n![](./images/Load.png)\n\n> 1. Click `coin_annotation_tool.html`\n\n> 2. Click `Load video file`, `Load label file`, `Load frame file` to load `video.txt` ,`label.txt`, `frame.txt`\n\n> 3. Click `Load` to load files\n\n---\n\n### Start Labeling\n\n#### Frame Mode\n\n![](./images/FrameMode.jpeg)\n\n> Operations\n\n1. `Setting`: Set `Row` and `Interval`\n\n2. `Save`: Save current results\n\n3. `Delete`: Delete current video\n\n> Usage\n\n1. Select images by clicking start and end frame\n\n2. Click and select `Tags`\n\n3. Clear labeled results by `Clear`\n\n---\n\n#### Video Mode\n\n![](./images/VideoMode.jpeg)\n\n> Operations\n\n1. `Save`: Save current results\n\n2. `Delete`: Delete current video\n\n> Usage\n\n1. Click video name on the top to enter video mode\n\n2. Click the bar at the bottom, select start and end frame\n\n3. Click and select `Tags`\n\n4. Clear labeled results by `Clear`\n\n---\n\n### Download results\n\nClick `Download` to download results \n"
  },
  {
    "path": "coin_annotation_tool.html",
    "content": "<!DOCTYPE HTML>\n<html>\n\n<head>\n  <meta charset=\"utf-8\" />\n\n  <link href=\"./lib/css/bootstrap.min.css\" rel=\"stylesheet\">\n  <script src=\"./lib/js/jquery.min.js\"></script>\n  <script src=\"./lib/js/bootstrap.min.js\"></script>\n  <link href=\"./lib/css/style.css\" rel=\"stylesheet\">\n  <link rel=\"shortcut icon\" type=\"image/x-icon\" href=\"./lib/img/favicon.ico\">\n  <title>Coin</title>\n</head>\n\n<body>\n  <div class=\"modal fade\" id=\"imageTag\" tabindex=\"-1\" role=\"dialog\" aria-labelledby=\"myModalLabel\" aria-hidden=\"true\">\n    <div class=\"modal-dialog\">\n      <div class=\"modal-content\">\n        <div class=\"modal-body\">\n          <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-hidden=\"true\">\n            &times;\n          </button>\n          <iframe id=\"openUrl\" width=\"100%;\" height=\"100%\"></iframe>\n        </div>\n      </div>\n    </div>\n  </div>\n  <div class=\"sidebar\" id=\"list_left\">\n    <div class=\"sideTitle\">\n      <button class=\"btn btn-danger\" onclick=\"closeVideo()\">Close</button>\n      <p>URLID:&nbsp;&nbsp;\n        <span id=\"currentUrlId\"></span>\n      </p>\n      <p>URL:&nbsp;&nbsp;\n        <span id=\"currentUrl\"></span>\n      </p>\n    </div>\n    <iframe src=\"about:blank\" width=\"400\" height=\"100%\"></iframe>\n  </div>\n  <div class=\"container\">\n    <div id=\"tip\"></div>\n    <div class=\"header\">\n      <div class=\"title\">\n        <img src=\"./lib/img/logo.png\">\n      </div>\n      <form class=\"form-inline\">\n        <div class=\"import\">\n          <div class=\"form-group\">\n            <input type='text' name='urlFile' id='urlFile' disabled class='form-control' placeholder=\"Load video file\" />\n            <input type=\"file\" name=\"urls\" class=\"file form-control\" id=\"urls\" size=\"28\" onchange=\"changeFile(this,'urlFile')\" />\n          </div>\n          <span>&nbsp;-&nbsp;</span>\n          <div class=\"form-group\">\n            <input type='text' name='tagFile' id='tagFile' disabled class='form-control' placeholder=\"Load label file\" />\n            <input type=\"file\" name=\"tags\" class=\"file form-control\" id=\"tags\" size=\"28\" onchange=\"changeFile(this, 'tagFile')\" />\n          </div>\n          <span>&nbsp;-&nbsp;</span>\n          <div class=\"form-group\">\n            <input type='text' name='File' id='frameFile' disabled class='form-control' placeholder=\"Load frame file\" />\n            <input type=\"file\" name=\"frames\" class=\"file form-control\" id=\"tags\" size=\"28\" onchange=\"changeFile(this, 'frameFile')\" />\n          </div>\n          <button type=\"button\" onclick=\"handleImport()\" class=\"btn btn-primary\">Load</button>\n        </div>\n      </form>\n    </div>\n    <ul id=\"myTab\" class=\"nav nav-tabs\">\n      <li class=\"active\">\n        <a class=\"tab\" href=\"#unTag\">\n          Unlabeled&nbsp;<span class=\"badge\" id=\"unTagTotal\">0</span>\n        </a>\n      </li>\n      <li>\n        <a class=\"tab\" href=\"#taged\">\n          Labeled&nbsp;<span class=\"badge\" id=\"tagedTotal\">0</span>\n        </a>\n      </li>\n      <li>\n        <a class=\"tab\" href=\"#checked\">\n          Checked&nbsp;<span class=\"badge\" id=\"checkedTotal\">0</span>\n        </a>\n      </li>\n      <li>\n        <a class=\"tab\" href=\"#delTag\">\n          Deleted&nbsp;<span class=\"badge\" id=\"delTagTotal\">0</span>\n        </a>\n      </li>\n      <li id=\"export\">\n        <div>\n          <a role=\"button\" class=\"btn btn-primary\" onclick=\"handleExport(this)\" download=\"download.csv\" href=\"#\">Download</a>\n        </div>\n      </li>\n    </ul>\n    <div id=\"myTabContent\" class=\"tab-content\">\n      <div class=\"tab-pane fade in active\" id=\"unTag\">\n        <p>No Data</p>\n      </div>\n      <div class=\"tab-pane fade\" id=\"taged\">\n        <p>No Data</p>\n      </div>\n      <div class=\"tab-pane fade\" id=\"checked\">\n        <p>No Data</p>\n      </div>\n      <div class=\"tab-pane fade\" id=\"delTag\">\n        <p>No Data</p>\n      </div>\n    </div>\n  </div>\n</body>\n\n<script src=\"./lib/js/config.js\"></script>\n<script src=\"./lib/js/index.js\"></script>\n</html>"
  },
  {
    "path": "input/frame.txt",
    "content": "URLID,Frame,Time\n1144,00000.jpg,0.0\n1144,00001.jpg,0.5\n1144,00002.jpg,1.0\n1144,00003.jpg,1.5\n1144,00004.jpg,2.0\n1144,00005.jpg,2.5\n1144,00006.jpg,3.0\n1144,00007.jpg,3.5\n1144,00008.jpg,4.0\n1144,00009.jpg,4.5\n1144,00010.jpg,5.0\n1144,00011.jpg,5.5\n1144,00012.jpg,6.0\n1144,00013.jpg,6.5\n1144,00014.jpg,7.0\n1144,00015.jpg,7.5\n1144,00016.jpg,8.0\n1144,00017.jpg,8.5\n1144,00018.jpg,9.0\n1144,00019.jpg,9.5\n1144,00020.jpg,10.0\n1144,00021.jpg,10.5\n1144,00022.jpg,11.0\n1144,00023.jpg,11.5\n1144,00024.jpg,12.0\n1144,00025.jpg,12.5\n1144,00026.jpg,13.0\n1144,00027.jpg,13.5\n1144,00028.jpg,14.0\n1144,00029.jpg,14.5\n1144,00030.jpg,15.0\n1144,00031.jpg,15.5\n1144,00032.jpg,16.0\n1144,00033.jpg,16.5\n1144,00034.jpg,17.0\n1144,00035.jpg,17.5\n1144,00036.jpg,18.0\n1144,00037.jpg,18.5\n1144,00038.jpg,19.0\n1144,00039.jpg,19.5\n1144,00040.jpg,20.0\n1144,00041.jpg,20.5\n1144,00042.jpg,21.0\n1144,00043.jpg,21.5\n1144,00044.jpg,22.0\n1144,00045.jpg,22.5\n1144,00046.jpg,23.0\n1144,00047.jpg,23.5\n1144,00048.jpg,24.0\n1144,00049.jpg,24.5\n1144,00050.jpg,25.0"
  },
  {
    "path": "input/label.txt",
    "content": "TagID,Tag\r\n1,unscrew the screw\r\n2,jack up the car\r\n3,remove the tire\r\n4,put on the tire\r\n5,tighten the screws\r\n"
  },
  {
    "path": "input/video.txt",
    "content": "URLID,URL\n1144,CQcWjWkaSfA.mp4"
  },
  {
    "path": "lib/css/style.css",
    "content": "html body {\n  height: 100%;\n  font-size: 14px;\n}\nul,\nli {\n  list-style: none;\n}\na {\n  cursor: pointer;\n  text-decoration: none;\n}\n.sidebar {\n  position: fixed;\n  top: 0;\n  bottom: 0;\n  left: 0;\n  z-index: 1000;\n  display: block;\n  background-color: #f5f5f5;\n  margin-left: -400px;\n  width: 400px;\n  height: 100%;\n  overflow: hidden;\n  overflow-y: auto;\n  -webkit-box-shadow: #ccc 0 0 10px;\n  box-shadow: #ccc 0 0 10px;\n  box-sizing: border-box;\n}\n.sideTitle {\n  background: #fff;\n  padding: 5px;\n}\n.sidebar p {\n  line-height: 14px;\n  width: 300px;\n  overflow: hidden;\n  margin: 0;\n}\n.sideTitle button {\n  font-size: 14px;\n  height: 28px;\n  position: absolute;\n  right: 3px;\n  padding: 4px 10px;\n}\niframe {\n  border: none;\n}\n.sidebar > .closeMenu > button {\n  position: absolute;\n  left: -10px;\n  top: 0;\n}\n\n.file.form-control {\n  position: absolute;\n  top: 0;\n  left: 0;\n  opacity: 0;\n  width: 172px;\n  padding: 6px 12px;\n  height: 34px;\n}\n\n.container {\n  padding-top: 30px;\n  min-width: 1200px;\n}\n\n.form-group {\n  position: relative;\n}\n\n.form-inline {\n  display: flex;\n  flex-direction: row;\n  justify-content: center;\n}\n\n.import {\n  display: flex;\n  align-items: center;\n}\n\nbutton {\n  margin-left: 10px;\n}\n\n#myTab {\n  display: none;\n  position: relative;\n}\n\n#export {\n  position: absolute;\n  top: 0px;\n  right: 0px;\n  display: none;\n}\n#myTabContent {\n  display: none;\n}\n\n.tab-content > .tab-pane {\n  border: 1px solid #ddd;\n  border-top: 0px;\n  padding: 20px 10px 0 10px;\n}\n\n#tip {\n  position: absolute;\n  padding: 10px 15px;\n  left: 50%;\n  z-index: 10000;\n  top: 80px;\n  /* display: none; */\n  min-width: 200px;\n  text-align: center;\n}\n.table th,\n.table td {\n  text-align: center;\n  vertical-align: middle !important;\n}\n.table > thead > tr > th {\n  border: none;\n}\n\nselect {\n  min-width: 100px;\n}\n\n.header {\n  min-width: 1200px;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  position: relative;\n  margin-bottom: 30px;\n}\n.title {\n  position: absolute;\n  left: 50px;\n  text-align: center;\n}\n.title > img {\n  width: 200px;\n}\n.table tr {\n  cursor: pointer;\n}\n"
  },
  {
    "path": "lib/css/tag.css",
    "content": "html, body{\n  height: 100%;\n}\n.todo button{\n  width: 100px;\n}\n.box {\n  width: 100%;\n  height: 100%;\n  padding: 0px 10px 10px 10px;\n  min-width: 1200px;\n  overflow: hidden;\n  display: none;\n}\n.boxTop {\n  width: 100%;\n  min-width: 1200px;\n  height: 60px;\n  line-height: 60px;\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  position: relative;\n}\n.modal-header {\n  position: relative;\n}\n.logo {\n  width: 150px;\n  position: absolute;\n  margin: 0 auto;\n  top:0;\n  bottom: 0;\n  left: 0;\n  right: 0;\n  display: flex;\n  align-items: center;\n}\n.logo img {\n  width: 150px;\n}\n.todo{\n  height: 34px;\n  display: flex;\n  justify-content: space-between;\n}\n.red-line {\n  position: relative;\n  top: 2px;\n  display: inline-block;\n  width: 8px;\n  height: 16px;\n  border-left: 3px solid #e63636;\n}\n\n.main {\n  min-width: 1200px;\n  display: flex;\n  height: calc(100% - 60px);\n  overflow: auto;\n}\n\n.tagLeft {\n  flex: 1;\n  background: #fff;\n  min-width: 900px;\n  height: calc(100% - 2px);\n  border: 1px solid #dcdfe6;\n  margin-right: 10px;\n  overflow: auto;\n}\n.row {\n  padding: 0;\n  margin: 0 !important;\n  padding-top: 5px;\n  width: 100%;\n  overflow: auto;\n  display: flex;\n  flex-direction: row;\n  justify-content: flex-start;\n  flex-wrap: wrap;\n}\n.fileDiv {\n  list-style: none;\n  padding:5px 5px;\n  position: relative;\n}\n.grid-content {\n  width: 100%;\n  height: 100%;\n  background: #fff;\n  overflow: hidden;\n  display: flex;\n  justify-content: center;\n  /* align-items: center; */\n  border: solid 2px #fff;\n  border-radius: 4px;\n  box-shadow: 0 2px 12px 0 rgba(0,0,0,.1);\n}\n.grid-content.active {\n  border: solid 2px #43e2c1;\n}\n.el-card {\n  width: 100%;\n  padding:5px;\n  position:relative; \n  cursor:pointer;\n}\n.icon {\n  position: absolute;\n  right: 5px;\n  top: 5px;\n  width: 20px;\n  cursor: pointer;\n  z-index: 100;\n}\n.img-box {\n  position: relative;\n}\n.miniImg {\n  max-width: 100%;\n}\n.card-info {\n  width: 100%;\n  overflow: hidden;\n  position: relative;\n  padding: 5px;\n  margin-bottom: 5px;\n  background: #f4f4f4;\n  border-radius: 5px;\n  display: flex;\n}\n\n.tagRight {\n  border: 1px solid #dcdfe6;\n  width:300px;\n  overflow: auto;\n  position: relative;\n  display: flex;\n  flex-direction: column;\n}\n.info {\n  width: 300px;\n  padding: 20px;\n  background: #fff;\n}\n  button {\n    margin-bottom: 10px;\n  }\n  h3 {\n    margin-bottom: 10px;\n  }\n.radioBox {\n  display: flex;\n  flex-direction: column;\n}\n\nlabel {\n  margin-bottom: 10px;\n}\n\n.el-radio.is-bordered + .el-radio.is-bordered {\n  margin-left: 0;\n}\n\n.item {\n  height: 25px;\n  line-height: 25px;\n}\n.imgBox {\n  width: 100%;\n  height: 100%;\n  overflow: auto;\n  text-align: center;\n}\n.infoIcon {\n  position: absolute;\n  color: #000;\n  top: 10px;\n  left: 10px;\n  font-size: 16px;\n}\n.el-dialog div {\n  background: #000;\n}\n\n\n.imgBox {\n  width: 100%;\n  height: 100%;\n  overflow: auto;\n  text-align: center;\n}\n.imgBox img {\n  max-width:100%\"\n}\n.delTagBtn{\n  display: none;\n}\n#urlId:hover{\n  color: #43e2c1\n}\n#mp4Loaded{\n  width:100%;\n  height:488px;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  position: absolute;\n  top: 0;\n  left: 0;\n  z-index: 10;\n}\n.my-progress {\n  position: relative;\n  width: 826px;\n  left: 11px;\n  height:30px;\n  overflow: hidden;\n  background-color: #f5f5f5;\n  border-radius: 4px;\n  -webkit-box-shadow: inset 0 1px 2px rgba(0,0,0,.1);\n  box-shadow: inset 0 1px 2px rgba(0,0,0,.1);\n  z-index: 100;\n  cursor: crosshair;\n}\n.my-progress-bar {\n  position: absolute;\n  height:30px;\n  cursor: pointer;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  color: #fff;\n}\n.progress {\n  position: relative;\n  width: 826px;\n  left: 11px;\n  height:5px;\n  margin-bottom: 0!important;\n  /* cursor: pointer; */\n  cursor: crosshair;\n}\n#progressbar {\n  background: red;\n}\n\n.modelLeft {\n  background: #fff;\n  border: 1px solid #dcdfe6;\n  margin-right: 10px;\n  overflow: auto;\n  padding: 10px;\n}\n.modelRight {\n  border: 1px solid #dcdfe6;\n  height: 570px;\n  width:300px;\n  overflow: auto;\n  position: relative;\n  display: flex;\n  flex-direction: column;\n  padding-top: 10px;\n}\n.modelTodo button{\n  width:80px;\n}\n.my-progress-bar{\n  z-index: 100;\n}"
  },
  {
    "path": "lib/imageTag.html",
    "content": "<!DOCTYPE HTML>\n<html>\n\n<head>\n  <meta charset=\"utf-8\" />\n  <meta http-equiv=\"Access-Control-Allow-Origin\" content=\"*\" />\n  <meta name=\"referrer\" content=\"never\">\n\n  <link href=\"./css/bootstrap.min.css\" rel=\"stylesheet\">\n  <script src=\"./js/jquery.min.js\"></script>\n  <script src=\"./js/bootstrap.min.js\"></script>\n  <link href=\"./css/style.css\" rel=\"stylesheet\">\n  <link href=\"./css/tag.css\" rel=\"stylesheet\">\n  <link rel=\"shortcut icon\" type=\"image/x-icon\" href=\"./img/favicon.ico\">\n  <title>Coin</title>\n</head>\n\n<body>\n  <div style=\"height: 100%\">\n    <div id=\"tip\"></div>\n    <div class=\"modal fade\" id=\"bigImg\" tabindex=\"-1\" role=\"dialog\" aria-labelledby=\"myModalLabel\" aria-hidden=\"true\">\n      <div class=\"modal-dialog\">\n        <div class=\"modal-content\">\n          <div class=\"modal-body\">\n            <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-hidden=\"true\">\n              &times;\n            </button>\n            <div style=\"background:#fff\" class=\"imgBox\" id=\"bigImgBox\">\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n    <div class=\"modal fade\" id=\"myModal\" tabindex=\"-1\" role=\"dialog\" aria-labelledby=\"myModalLabel\" aria-hidden=\"true\">\n      <div class=\"modal-dialog\">\n        <div class=\"modal-content\">\n          <div class=\"modal-header\">\n            <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-hidden=\"true\">\n              &times;\n            </button>\n            <h4 class=\"modal-title\" id=\"myModalLabel\">\n              Setting\n            </h4>\n          </div>\n          <div class=\"modal-body\">\n            <form class=\"form-horizontal\" role=\"form\" id=\"myForm\">\n              <div class=\"form-group\">\n                <label for=\"firstname\" class=\"col-sm-3 control-label\">Column</label>\n                <div class=\"col-sm-9\">\n                  <input type=\"text\" name=\"column\" class=\"form-control\" id=\"column\" placeholder=\"Please enter the number of images per line\">\n                </div>\n              </div>\n              <div class=\"form-group\">\n                <label for=\"firstname\" class=\"col-sm-3 control-label\">Frame interval(s)</label>\n                <div class=\"col-sm-9\">\n                  <input type=\"text\" name=\"frame\" class=\"form-control\" id=\"frame\" placeholder=\"Please enter frame interval\">\n                </div>\n              </div>\n            </form>\n          </div>\n          <div class=\"modal-footer\">\n            <button type=\"button\" class=\"btn btn-default\" data-dismiss=\"modal\">Close\n            </button>\n            <button type=\"button\" class=\"btn btn-primary\" onclick=\"setting(this)\">\n              Submit\n            </button>\n          </div>\n        </div>\n      </div>\n    </div>\n    <div class=\"modal fade\" id=\"videoModal\" tabindex=\"-1\" role=\"dialog\" aria-labelledby=\"src\" aria-hidden=\"true\">\n      <div class=\"modal-dialog modal-lg\" style=\"width: 1200px;\">\n        <div class=\"modal-content\">\n          <div class=\"modal-header\">\n            <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-hidden=\"true\">×</button>\n            <a class=\"modal-title\" id=\"modalTitle\" target=\"_blank\"></a>\n            <div class=\"logo\"><img src=\"./img/logo.png\" style=\"width:150px;\"></div>\n          </div>\n          <div class=\"modal-body\">\n            <div class=\"main\">\n              <div class=\"modelLeft\">\n                <div id=\"mp4Loaded\"><img src=\"../lib/img/loading.gif\"></div>\n                <div id=\"player\" style=\"width:848px;height:488px\"></div>\n                <div class=\"progress\" id=\"progress\" data-container=\"body\" data-toggle=\"popover\">\n                  <div class=\"progress-bar\" id=\"progressbar\" role=\"progressbar\" aria-valuemin=\"0\" aria-valuemax=\"100\"\n                    style=\"width: 0%;\">\n                  </div>\n                </div>\n\n                <div class=\"my-progress\" id=\"myProgress\" style=\"display: none\">\n                </div>\n                <div style=\"margin-left: 12px;\">\n                  <span id=\"current\">0</span>\n                  <span id=\"duration\"></span> (s)\n                </div>\n              </div>\n              <div class=\"modelRight\">\n                <div class=\"modelTodo\">\n                  <button class=\"delTagBtn btn btn-danger\" onclick=\"delTag(this)\">Clear</button>\n                  <button class=\"btn btn-success\" onclick=\"saveTimeInfo(true)\">Save</button>\n                  <button class=\"btn btn-danger\" onclick=\"delVideo(true)\">Delete</button>\n                </div>\n\n                <div class=\"info\">\n                  <h4>Tags</h4>\n                  <div class=\"radioBox\">\n                  </div>\n                </div>\n                <div class=\"info\">\n                  <h4>Labels</h4>\n                  <div class=\"result\">\n                  </div>\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n    <div class=\"box\">\n      <div class=\"boxTop\">\n        <div class=\"logo\">\n          <img src=\"./img/logo.png\">\n        </div>\n        <div>\n          <a href=\"../coin_annotation_tool.html\" style=\"margin-right: 5px;color: #000; text-decoration: none;\">\n            <img src=\"./img/left.png\" height=\"15px;\" style=\"position: relative;top: -1px;\" />Back</a>\n          <span class=\"red-line\"></span>\n          <span href=\"#\">Video(check to play)：\n            <b id=\"urlId\" style=\"cursor: pointer;\"></b>\n          </span>\n        </div>\n        <div class=\"todo\">\n          <button class=\"delTagBtn btn btn-danger\" onclick=\"delTag(this)\">Clear</button>\n          <button class=\"btn btn-info\" onclick=\"openSet(this)\">Setting</button>\n          <button class=\"btn btn-success\" onclick=\"saveInfo(true)\">Save</button>\n          <button class=\"btn btn-danger\" onclick=\"delVideo(true)\">Delete</button>\n        </div>\n      </div>\n      <div class=\"main\">\n        <div class=\"tagLeft\">\n          <ul class=\"row\" id=\"row\">\n          </ul>\n        </div>\n        <div class=\"tagRight\">\n          <div class=\"info\">\n            <h4>Tags</h4>\n            <div class=\"radioBox\">\n            </div>\n          </div>\n          <div class=\"info\">\n            <h4>Labels</h4>\n            <div class=\"result\">\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n  </div>\n</body>\n<script src=\"./js/config.js\"></script>\n<script src=\"./js/imageTag.js\"></script>\n</html>"
  },
  {
    "path": "lib/js/config.js",
    "content": "$.fn.csv2arr = function(callback) {\n  var files = $(this)[0].files;\n  if (files.length != 0) {\n    if (typeof FileReader !== \"undefined\") {\n      var reader = new FileReader();\n      reader.readAsText(files[0]);\n      reader.onload = function(evt) {\n        var data = evt.target.result;\n        var arr = data.trim().split(\"\\n\");\n        var newArr = [];\n        for (var i in arr) {\n          newArr[i] = arr[i].split(\",\");\n        }\n        callback && callback(newArr);\n      };\n    } else {\n      showTip(\"Please Use Chrome or Firefox\", \"warning\", \"500\");\n    }\n  } else {\n    showTip(\"Please load all files\", \"warning\", \"500\");\n    $(\"#tip\").fadeOut(100);\n  }\n};\n\nfunction getUrlParam(paraName) {\n  var url = decodeURI(document.location.toString());\n  var arrObj = url.split(\"?\");\n  if (arrObj.length > 1) {\n    var arrPara = arrObj[1].split(\"&\");\n    var arr;\n    for (var i = 0; i < arrPara.length; i++) {\n      arr = arrPara[i].split(\"=\");\n      if (arr != null && arr[0] == paraName) {\n        return arr[1];\n      }\n    }\n    return \"\";\n  } else {\n    return \"\";\n  }\n}\nDate.prototype.format = function(fmt) {\n  var o = {\n    \"M+\": this.getMonth() + 1,\n    \"d+\": this.getDate(),\n    \"h+\": this.getHours(),\n    \"m+\": this.getMinutes(),\n    \"s+\": this.getSeconds(),\n    \"q+\": Math.floor((this.getMonth() + 3) / 3),\n    S: this.getMilliseconds()\n  };\n  if (/(y+)/.test(fmt)) {\n    fmt = fmt.replace(\n      RegExp.$1,\n      (this.getFullYear() + \"\").substr(4 - RegExp.$1.length)\n    );\n  }\n  for (var k in o) {\n    if (new RegExp(\"(\" + k + \")\").test(fmt)) {\n      fmt = fmt.replace(\n        RegExp.$1,\n        RegExp.$1.length == 1 ? o[k] : (\"00\" + o[k]).substr((\"\" + o[k]).length)\n      );\n    }\n  }\n  return fmt;\n};\nfunction showTip(tip, type, delay) {\n  var $tip = $(\"#tip\");\n  $tip\n    .stop(true)\n    .prop(\"class\", \"alert alert-\" + type)\n    .text(tip)\n    .css(\"margin-left\", -$tip.outerWidth() / 2)\n    .fadeIn(200)\n    .delay(delay ? delay : \"300\")\n    .fadeOut(200);\n}\nfunction addUrlArr(arr) {\n  var obj = {\n    urlId: arr[0],\n    url: arr[1],\n    tagInfo: addTagInfo([], arr),\n    times: arr[6] || 0,\n    state: parseInt(arr[7]) || 0\n  };\n  return obj;\n}\nfunction unique(arr) {\n  var urlsArr = [];\n  urlsArr.push(addUrlArr(arr[0]));\n  for (var i = 1; i < arr.length; i++) {\n    var repeat = false;\n    for (var j = 0; j < urlsArr.length; j++) {\n      if (arr[i][0] == urlsArr[j].urlId) {\n        repeat = true;\n        urlsArr[j].tagInfo = addTagInfo(urlsArr[j].tagInfo, arr[i]);\n        break;\n      }\n    }\n    if (!repeat) {\n      urlsArr.push(addUrlArr(arr[i]));\n    }\n  }\n  return urlsArr;\n}\n\nfunction handleCancel(e) {\n  var frameData = {\n    url: \"\",\n    urlId: \"\",\n    image: [],\n    tagInfo: []\n  };\n  var tr = $(e)[0].parentNode.parentNode;\n  var urlId = $(tr).find(\"td\")[0].innerText;\n  var url = $(tr).find(\"td\")[1].innerText;\n  for (var i = 0; i < result.length; i++) {\n    if (result[i].urlId == urlId) {\n      $(\"#checkedTotal\").html(parseInt($(\"#checkedTotal\")[0].innerText) - 1);\n      $(\"#tagedTotal\").html(parseInt($(\"#tagedTotal\")[0].innerText) + 1);\n      result[i].times++;\n      result[i].checked = false;\n      localStorage.setItem(\n        \"checkedTotal\",\n        parseInt(localStorage.getItem(\"checkedTotal\")) - 1\n      );\n      localStorage.setItem(\n        \"tagedTotal\",\n        parseInt(localStorage.getItem(\"tagedTotal\")) + 1\n      );\n      localStorage.setItem(\"result\", JSON.stringify(result));\n\n      $(tr).remove();\n      var tr = initTr(result[i]);\n      if ($(\"#taged:has(tbody)\").length == 0) {\n        $(\"#taged table\").append(\"<tbody>\" + tr + \"</tbody>\");\n      } else {\n        $(\"#taged tbody\").prepend(tr);\n      }\n      return;\n    }\n  }\n}\n\nfunction goTag(e) {\n  var frameData = {\n    url: \"\",\n    urlId: \"\",\n    image: [],\n    tagInfo: []\n  };\n  var tr = $(e)[0].parentNode.parentNode;\n  var urlId = $(tr).find(\"td\")[0].innerText;\n  var url = $(tr).find(\"td\")[1].innerText;\n  var tagInfo = $(tr).find(\"td\")[2].innerText;\n  var openUrl = \"./lib/imageTag.html?urlId=\" + urlId;\n  window.location.href = openUrl;\n}\nfunction addTagInfo(old, newArr) {\n  if (newArr[2] && newArr[3] && newArr[4] && newArr[5]) {\n    var obj = {\n      tagId: newArr[2],\n      tag: newArr[3],\n      start: newArr[4],\n      end: newArr[5]\n    };\n    old.push(obj);\n  }\n  return old;\n}\nfunction tagInfoToBe(tagInfo) {\n  var table = \"\";\n  if (tagInfo.length > 0) {\n    table +=\n      \"<table class='table'><thead><th>TagID</th><th>Tag</th><th>Start</th><th>End</th>\";\n    for (var i in tagInfo) {\n      table += \"<tr>\";\n      for (var key in tagInfo[i]) {\n        table += \"<td>\" + tagInfo[i][key] + \"</td>\";\n      }\n      table += \"</tr>\";\n    }\n    table += \"<table>\";\n  }\n  return table;\n}\nfunction initTr(item) {\n  var content = \"\";\n  content += \"<tr>\";\n  content += \"<td>\" + item.urlId + \"</td>\";\n  content += \"<td>\" + item.url + \"</td>\";\n  content +=\n    \"<td style='width:50%;text-align:left;display:none'>\" +\n    JSON.stringify(item.tagInfo) +\n    \"</td>\";\n  // content += \"<td>\" + tagInfoToBe(item.tagInfo) + \"</td>\"\n  content += \"<td>\" + item.times + \"</td>\";\n  if (item.checked) {\n    content +=\n      \"<td><button onclick='handleCancel(this)' class='btn btn-danger' type='button'>Cancel</button></td>\";\n  } else if (item.state == 2) {\n    content +=\n      \"<td><button onclick='handleReturn(this)' class='btn btn-danger' type='button'>Restore</button></td>\";\n  } else if (item.state == 1) {\n    content +=\n      \"<td><button onclick='goTag(this)' class='btn btn-info'>Checkout</button><button onclick='handleDelete(this)' class='btn btn-danger' type='button'>Delete</button></td>\";\n  } else {\n    content +=\n      \"<td><button onclick='goTag(this)' class='btn btn-info'>Label</button><button onclick='handleDelete(this)' class='btn btn-danger' type='button'>Delete</button></td>\";\n  }\n  content += \"</tr>\";\n  return content;\n}\nfunction createTable(urlsArr) {\n  var result = [];\n  $(\"#myTab\").show();\n  $(\"#myTabContent\").show();\n  $(\"#export\").show();\n  var tempTh = \"<table class='table'>\";\n  tempTh += \"<thead><tr>\";\n  tempTh += \"<th>URLID</th>\";\n  tempTh += \"<th>URL</th>\";\n  tempTh += \"<th style='display:none'>TagInfo</th>\";\n  tempTh += \"<th>Time</th>\";\n  tempTh += \"<th>Operation</th>\";\n  tempTh += \"</tr></thead>\";\n  var unTag = tempTh;\n  var unTagTotal = 0;\n  var taged = tempTh;\n  var tagedTotal = 0;\n  var checked = tempTh;\n  var checkedTotal = 0;\n  var delTag = tempTh;\n  var delTagTotal = 0;\n  for (var i = 0; i < urlsArr.length; i++) {\n    result.push(urlsArr[i]);\n    var tr = initTr(urlsArr[i]);\n    if (urlsArr[i].checked) {\n      checked += tr;\n      checkedTotal++;\n    } else if (urlsArr[i].state == 0) {\n      unTag += tr;\n      unTagTotal++;\n    } else if (urlsArr[i].state == 1) {\n      taged += tr;\n      tagedTotal++;\n    } else if (urlsArr[i].state == 2) {\n      delTag += tr;\n      delTagTotal++;\n    }\n  }\n  unTag += \"</table>\";\n  taged += \"</table>\";\n  checked += \"</table>\";\n  delTag += \"</table>\";\n  $(\"#unTag\").html(unTag);\n  $(\"#taged\").html(taged);\n  $(\"#checked\").html(checked);\n  $(\"#delTag\").html(delTag);\n  localStorage.setItem(\"unTagTotal\", unTagTotal);\n  localStorage.setItem(\"tagedTotal\", tagedTotal);\n  localStorage.setItem(\"checkedTotal\", checkedTotal);\n  localStorage.setItem(\"delTagTotal\", delTagTotal);\n  $(\"#unTagTotal\").html(unTagTotal);\n  $(\"#tagedTotal\").html(tagedTotal);\n  $(\"#checkedTotal\").html(checkedTotal);\n  $(\"#delTagTotal\").html(delTagTotal);\n  showTip(\"Data load successful\", \"success\");\n  setTimeout(function() {\n    $(\"#tip\").fadeOut(100);\n  }, 500);\n  return result;\n}\n"
  },
  {
    "path": "lib/js/imageTag.js",
    "content": "var result = JSON.parse(localStorage.getItem(\"result\"));\nvar tagsArr = JSON.parse(localStorage.getItem(\"tag\"));\nvar framesArr = JSON.parse(localStorage.getItem(\"frame\"));\nvar frameData = {};\nvar urlIndex = 0;\nvar column = 4;\nvar oldSpace = 0.5;\nvar newSpace = 0.5;\nvar colors = [];\nvar player;\nvar duration = 0;\nvar width = 0;\nvar height = 0;\nvar done = false;\nif (localStorage.getItem(\"column\")) {\n  column = localStorage.getItem(\"column\");\n} else {\n  localStorage.setItem(\"column\", column);\n}\nif (localStorage.getItem(\"newSpace\")) {\n  newSpace = localStorage.getItem(\"newSpace\");\n} else {\n  localStorage.setItem(\"newSpace\", newSpace);\n}\nvar activeTimeId = \"\";\nvar int;\nvar color = [\n  \"#E14A63\",\n  \"#F3AA4D\",\n  \"#C4C400\",\n  \"#99CC99\",\n  \"#2891DB\",\n  \"#003366\",\n  \"#996699\",\n  \"#996633\",\n  \"#999999\",\n  \"#FF9999\"\n];\nfunction randomColor(index) {\n  if (index < 10) {\n    return color[index];\n  }\n  var hex = Math.floor(Math.random() * 0xffffff).toString(16);\n  while (hex.length < 6) {\n    hex = \"0\" + hex;\n  }\n  return `#${hex}`;\n}\n\nvar ratio = 1;\nvar bigImgUrl = \"\";\nvar urlId = getUrlParam(\"urlId\");\nif (!urlId) {\n  $(\".box\").hide();\n  window.location.href = \"../coin_annotation_tool.html\";\n} else {\n  var clientWidth =\n    document.documentElement.clientWidth || document.body.clientWidth;\n  var clientHeight =\n    document.documentElement.clientHeight || document.body.clientHeight;\n  var activeImg = [];\n  var activeTime = [];\n  $(\".box\").show();\n  getFrame();\n  for (let i in tagsArr) {\n    tagsArr[i].push(randomColor(i));\n  }\n  var tagInfo = result[urlIndex].tagInfo.sort(compare(\"start\"));\n}\n\n$(function() {\n  if (urlId) {\n    $(\"[data-toggle='tooltip']\").tooltip();\n    $(\"#column\").val(column);\n    $(\"#frame\").val(newSpace);\n    $(\"#urlId\")[0].innerText = frameData.url;\n\n    var table = tagInfoToBe(result[urlIndex].tagInfo);\n    $(\".result\").append(table);\n    getData();\n    initTagInfo();\n\n    $(\"#urlId\").click(function() {\n      $(\"#modalTitle\").attr(\n        \"href\",\n        \"https://www.youtube.com/embed/\" +\n          frameData.url.slice(0, frameData.url.length - 4)\n      );\n      $(\"#modalTitle\")[0].innerText =\n        \"https://www.youtube.com/embed/\" +\n        frameData.url.slice(0, frameData.url.length - 4);\n      $(\"#videoModal\").modal();\n      width = $(\"#progress\").width();\n      if (duration) {\n        player.playVideo();\n      }\n      activeImg = [];\n      loadProgress();\n    });\n    $(\"#videoModal\").on(\"hide.bs.modal\", function() {\n      window.clearInterval(int);\n      initTagInfo();\n      if (player) {\n        player.pauseVideo();\n        player.clearVideo();\n      }\n    });\n    $(\"#videoModal\").on(\"hidden.bs.modal\", function() {\n      $(\".delTagBtn\").hide();\n      activeTime = [];\n    });\n    var left = 0,\n      bgleft = 0;\n    $(\"#progress\").click(function(e) {\n      player.pauseVideo();\n      bgleft = $(\"#progress\").offset().left;\n      left = e.pageX - bgleft;\n      $(\"#progressbar\").width(left);\n      var seekTo = (left / width) * duration;\n      if (parseInt((left / width) * duration) >= duration) {\n        seekTo = duration;\n      }\n      player.seekTo(seekTo, true);\n      $(\"#current\")[0].innerText = parseFloat(seekTo).toFixed(1);\n    });\n    $(\"#progress\").mousemove(function(e) {\n      player.pauseVideo();\n      bgleft = $(\"#progress\").offset().left;\n      left = e.pageX - bgleft;\n      $(\"[data-toggle='popover']\").popover();\n      $(\"#progressbar\").width(left);\n      var seekTo = (left / width) * duration;\n      if (parseInt((left / width) * duration) >= duration) {\n        seekTo = duration;\n      }\n      player.seekTo(seekTo, true);\n      $(\"#current\")[0].innerText = parseFloat(seekTo).toFixed(1);\n    });\n    $(\"#myProgress\").mousemove(function(e) {\n      player.pauseVideo();\n      bgleft = $(\"#progress\").offset().left;\n      left = e.pageX - bgleft;\n      $(\"[data-toggle='popover']\").popover();\n      $(\"#progressbar\").width(left);\n      var seekTo = (left / width) * duration;\n      if (parseInt((left / width) * duration) >= duration) {\n        seekTo = duration;\n      }\n      player.seekTo(seekTo, true);\n      $(\"#current\")[0].innerText = parseFloat(seekTo).toFixed(1);\n    });\n    $(\"#myProgress\").click(function(e) {\n      player.pauseVideo();\n      bgleft = $(\"#myProgress\").offset().left;\n      left = e.pageX - bgleft;\n      $(\"#progressbar\").width(left);\n\n      var seekTo = parseFloat((left / width) * duration).toFixed(1);\n      if (left > width) {\n        seekTo = duration;\n      }\n      player.seekTo(seekTo, true);\n      $(\"#current\")[0].innerText = parseFloat(seekTo).toFixed(1);\n\n      var flag = false;\n      for (var i = 0; i < tagInfo.length; i++) {\n        if (\n          seekTo >= parseFloat(tagInfo[i].start) &&\n          seekTo <= parseFloat(tagInfo[i].end)\n        ) {\n          flag = true;\n          activeTime = [];\n          break;\n        }\n      }\n      if (!flag) {\n        changeActiveTime(seekTo);\n      }\n    });\n  }\n});\nfunction toActiveTime(flag) {\n  if (flag) {\n    $(\".delTagBtn\").show();\n    enableRadio();\n  } else {\n    if (activeTime.length == 0 || activeTime.length == 1) {\n      $(\".delTagBtn\").hide();\n      disableRadio();\n    } else if (activeTime.length == 2) {\n      $(\".delTagBtn\").show();\n      enableRadio();\n      var start = parseFloat(activeTime[0]);\n      var end = parseFloat(activeTime[1]);\n      var item = start;\n      if (start > end) {\n        start = end;\n        end = item;\n      }\n      var background = \"#ccc\";\n      addProgress(start, end, background);\n    }\n  }\n}\nfunction addProgress(start, end, background) {\n  var progress = $(\"#myProgress\");\n  var percent = (end - start) / duration;\n  var id = $(\".my-progress-bar\").length + 1;\n  var progress_bar =\n    '<div id=\"' +\n    id +\n    '\" class=\"my-progress-bar\"' +\n    'style=\"background:' +\n    background +\n    \";width:\" +\n    percent * width +\n    \"px;left:\" +\n    (start / duration) * width +\n    'px;\"' +\n    ' role=\"progressbar\" aria-valuemin=\"0\" aria-valuemax=\"100\"' +\n    ' data-toggle=\"popover\" rel=\"popover\"' +\n    '\" data-original-title=\"' +\n    start +\n    \"s-\" +\n    end +\n    's\">' +\n    \"</div>\";\n  progress.append(progress_bar);\n  $(\"[data-toggle='popover']\").popover({\n    trigger: \"hover\",\n    placement: \"top\",\n    container: \"body\"\n  });\n}\nfunction changeActiveTime(time) {\n  var length = activeTime.length;\n  if (length == 0) {\n    activeTime.push(time);\n  } else if (length == 1) {\n    if (parseFloat(time) - parseFloat(activeTime[0]).toFixed(1) == 0) {\n      console.log(\"Repeat\");\n    } else {\n      activeTimeId = \"\";\n      activeTime.push(time);\n      var start = 0;\n      var end = 0;\n      start = parseFloat(activeTime[0]);\n      end = parseFloat(activeTime[1]);\n      var item = start;\n      if (start > end) {\n        start = end;\n        end = item;\n      }\n      var flag = false;\n      for (var i = 0; i < tagInfo.length; i++) {\n        if (\n          start <= parseFloat(tagInfo[i].start) &&\n          end >= parseFloat(tagInfo[i].end)\n        ) {\n          flag = true;\n          break;\n        }\n      }\n      if (!flag) {\n        activeTime = [start, end];\n      } else {\n        showTip(\"No coverage\", \"warning\", \"500\");\n        loadProgress();\n        activeTime = [];\n      }\n    }\n  } else {\n    loadProgress();\n    activeTime = [];\n    activeTime.push(time);\n  }\n  toActiveTime();\n  if (activeTime.length == 1) {\n    var start = activeTime[0];\n    var progress = $(\"#myProgress\");\n    var id = $(\".my-progress-bar\").length + 1;\n    var progress_bar =\n      '<div id=\"' +\n      id +\n      '\" class=\"my-progress-bar\"' +\n      'style=\"background:black;width:2px;' +\n      \"left:\" +\n      (start / duration) * width +\n      'px;\">' +\n      \"</div>\";\n    progress.append(progress_bar);\n  }\n}\nif (urlId) {\n  var tag = document.createElement(\"script\");\n  tag.src = \"https://www.youtube.com/iframe_api\";\n  var firstScriptTag = document.getElementsByTagName(\"script\")[0];\n  firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);\n}\n\nfunction onYouTubeIframeAPIReady() {\n  player = new YT.Player(\"player\", {\n    videoId: frameData.url.slice(0, frameData.url.length - 4),\n    playerVars: { controls: 1, showinfo: 0 },\n    events: {\n      onReady: onPlayerReady,\n      onStateChange: onPlayerStateChange\n    }\n  });\n}\n\nfunction onPlayerReady(event) {\n  duration = player.getDuration();\n  $(\"#duration\")[0].innerText = \" / \" + (duration - 1);\n  $(\"#mp4Loaded\").hide();\n  $(\"#myProgress\").show();\n  loadProgress();\n  $(\"#progress-bar\").width((player.getCurrentTime() / duration) * 100 + \"%\");\n}\nfunction onPlayerStateChange(data) {\n  if (data.data == 1) {\n    int = window.setInterval(\"load()\", 100);\n  } else {\n    window.clearInterval(int);\n    $(\"#current\")[0].innerText = parseInt(player.getCurrentTime());\n    $(\"#progressbar\").width((player.getCurrentTime() / duration) * width);\n  }\n}\nfunction load() {\n  $(\"#current\")[0].innerText = parseInt(player.getCurrentTime());\n  $(\"#progressbar\").width((player.getCurrentTime() / duration) * width);\n  if (player.getCurrentTime() >= duration - 1) {\n    window.clearInterval(int);\n  }\n}\nfunction loadProgress() {\n  $(\"[data-toggle='popover']\").popover(\"hide\");\n  tagInfo = result[urlIndex].tagInfo.sort(compare(\"start\"));\n  var progress = $(\"#myProgress\");\n  progress.html(\"\");\n  for (let i in tagInfo) {\n    var item = parseFloat(tagInfo[i].end) - parseFloat(tagInfo[i].start);\n    var background = \"\";\n    for (var j = 0; j < tagsArr.length; j++) {\n      if (tagsArr[j][0] == tagInfo[i].tagId) {\n        background = tagsArr[j][2];\n      }\n    }\n    var percent = item / duration;\n    var type = i % 2 == 0 ? \"warning\" : \"danger\";\n    var id = $(\".my-progress-bar\").length + 1;\n    var progress_bar =\n      '<div id=\"' +\n      id +\n      '\" onclick=\"changeSeek(' +\n      tagInfo[i].start +\n      \",\" +\n      tagInfo[i].end +\n      \",\" +\n      id +\n      ')\"class=\"my-progress-bar\"' +\n      'style=\"background:' +\n      background +\n      \";width:\" +\n      percent * width +\n      \"px;left:\" +\n      (tagInfo[i].start / duration) * width +\n      'px;\"' +\n      ' role=\"progressbar\" aria-valuemin=\"0\" aria-valuemax=\"100\"' +\n      ' data-toggle=\"popover\" rel=\"popover\" data-content=\"' +\n      tagInfo[i].tag +\n      '\" data-tagid=\"' +\n      tagInfo[i].tagId +\n      '\" data-original-title=\"' +\n      tagInfo[i].start +\n      \"s-\" +\n      tagInfo[i].end +\n      's\">' +\n      \"<span>\" +\n      tagInfo[i].tagId;\n    \"</span>\" + \"</div>\";\n    progress.append(progress_bar);\n  }\n  $(\"[data-toggle='popover']\").popover({\n    trigger: \"hover\",\n    placement: \"top\",\n    container: \"body\"\n  });\n}\nfunction changeSeek(start, end, id, flag) {\n  window.event.stopPropagation();\n  player.seekTo(start, true);\n  player.playVideo();\n  $(\"#current\")[0].innerText = parseFloat(start).toFixed(1);\n  $(\"#progressbar\").width((start / duration) * width);\n  activeTimeId = id;\n  activeTime = [start, end];\n  toActiveTime(true);\n}\nfunction getFrame() {\n  for (var i in result) {\n    if (result[i].urlId == urlId) {\n      frameData = cloneObj(result[i]);\n      frameData.url = frameData.url.trim();\n      urlIndex = i;\n      break;\n    }\n  }\n  frameData.image = [];\n  var multiple = parseFloat(newSpace / oldSpace);\n  var newImg = [];\n  for (var j = 0; j < framesArr.length; j++) {\n    if (frameData.urlId == framesArr[j][0]) {\n      newImg.push({\n        urlId: framesArr[j][0],\n        url: framesArr[j][1],\n        time: framesArr[j][2]\n      });\n    }\n  }\n  for (var k = 0; k < newImg.length; k += multiple) {\n    frameData.image.push({\n      url: newImg[k].url,\n      time: newImg[k].time\n    });\n  }\n}\nfunction getData() {\n  $(\"#row\").html(\"\");\n  $(\".radioBox\").html(\"\");\n  for (var i = 0; i < tagsArr.length; i++) {\n    var radio = \"<div class='radio'><label>\";\n    radio +=\n      \"<input type='radio' disabled name='tag' onchange='changeTag(this)' value='\" +\n      tagsArr[i][0] +\n      \"'>\" +\n      \"<span>\" +\n      tagsArr[i][1];\n    radio +=\n      \"</span><p style='position:absolute;top:0;right:0;width:10px;height:10px;border-radio:10px;background:\" +\n      tagsArr[i][2] +\n      \"'></p></label></div>\";\n    $(\".radioBox\").append(radio);\n  }\n  for (var i = 0; i < frameData.image.length; i++) {\n    var li =\n      \"<li class='fileDiv' style='width:\" +\n      (1 / column) * 100 +\n      \"%' id='\" +\n      i +\n      \"'>\";\n    li += \"<div class='grid-content'>\";\n    li += \" <div class='el-card' onclick='changeActiveImg(this)' >\";\n    li += \"   <div class='card-info' style='overflow:hidden'>\";\n    li += \"    <img class='icon' onclick='bigImg(this)' src='./img/big.svg'>\";\n    li +=\n      \"    <div style='margin-right:5px'><span class='time'>\" +\n      frameData.image[i].time +\n      \"</span>s</div>\";\n    li +=\n      \"    <div><span class='tag label label-info' style='margin:0 0 5px 0;'></span></div>\";\n    li += \"   </div>\";\n    li += \"   <div class='img-box'>\";\n    li +=\n      \"     <img id='\" +\n      i +\n      \"' class='miniImg' src='\" +\n      getImgSrc(frameData.image[i].url) +\n      \"'\";\n    li += \"     />\";\n    li += \"   </div>\";\n    li += \"  </div>\";\n    li += \" </div>\";\n    li += \"</li>\";\n    $(\"#row\").append(li);\n  }\n}\nfunction initTagInfo() {\n  var lis = $(\"#row li.fileDiv\");\n  for (var i = 0; i < lis.length; i++) {\n    $(lis[i]).find(\"span.tag\")[0].id = \"\";\n    $(lis[i]).find(\"span.tag\")[0].innerText = \"\";\n    var id = parseFloat($(\".time\")[i].innerText);\n    for (var j in tagInfo) {\n      if (\n        id <= parseFloat(tagInfo[j].end) &&\n        id >= parseFloat(tagInfo[j].start)\n      ) {\n        $(lis[i]).find(\"span.tag\")[0].id = tagInfo[j].tagId;\n        $(lis[i]).find(\"span.tag\")[0].innerText = tagInfo[j].tag;\n        for (var k = 0; k < tagsArr.length; k++) {\n          if (tagsArr[k][0] == tagInfo[j].tagId) {\n            $(lis[i]).find(\"span.tag\")[0].style.background = tagsArr[k][2];\n            break;\n          }\n        }\n        break;\n      }\n    }\n  }\n}\nfunction openSet() {\n  var answer = confirm(\n    \"This action clears the currently unsaved information\\nWhether to save the current information\"\n  );\n  if (answer == true) {\n    saveInfo(false);\n  } else {\n    result = JSON.parse(localStorage.getItem(\"result\"));\n    tagInfo = result[urlIndex].tagInfo;\n    var table = tagInfoToBe(tagInfo);\n    $(\".result\").html(\"\");\n    $(\".result\").append(table);\n    loadProgress();\n  }\n  $(\"#myModal\").modal();\n}\nfunction setting() {\n  var x = $(\"#myForm\").serializeArray();\n  column = parseFloat(x[0].value) ? parseFloat(x[0].value) : 0;\n  newSpace = parseFloat(x[1].value) ? parseFloat(x[1].value) : 0;\n  var yu = newSpace % oldSpace;\n  if (yu) {\n    showTip(\n      \"Frame interval must be \" + oldSpace + \" integer times\",\n      \"warning\",\n      \"800\"\n    );\n  } else {\n    if (column && newSpace) {\n      localStorage.setItem(\"column\", column);\n      localStorage.setItem(\"newSpace\", newSpace);\n      var lis = $(\"#row li.fileDiv\");\n      for (var i = 0; i < lis.length; i++) {\n        lis[i].style.width = (1 / column) * 100 + \"%\";\n      }\n      getFrame();\n      getData();\n      initTagInfo();\n      $(\"#myModal\").modal(\"hide\");\n    }\n  }\n}\n\nfunction getImgSrc(image) {\n  return \"../input/video/\" + frameData.urlId + \"/\" + image;\n}\nfunction bigImg(icon) {\n  event.preventDefault();\n  $(\"#bigImgBox\").html(\"\");\n  var img = $(icon)\n    .parent()\n    .parent()[0].children[1].children[0];\n  var width = img.width;\n  var height = img.height;\n  ratio = width / height;\n  bigImgUrl = img.src;\n\n  var realWidth = (clientHeight - 110) * ratio + \"px\";\n  var realHeight = (clientHeight - 110) * ratio + \"px\";\n  var bigImg =\n    \"<img src='\" +\n    bigImgUrl +\n    \"' height='\" +\n    (clientHeight - 110) +\n    \"px'\" +\n    \"' width='\" +\n    (clientHeight - 110) * ratio +\n    \"px'/>\";\n  $(\".modal-dialog\").width((clientHeight - 110) * ratio + 30 + \"px\");\n  $(\"#bigImgBox\").append(bigImg);\n  $(\"#bigImg\").modal(\"show\");\n  return false;\n}\n\nfunction delTag() {\n  if (activeImg.length > 0) {\n    for (var i = 0; i < activeImg.length; i++) {\n      var img = $('img[id=\"' + activeImg[i] + '\"]');\n      var label = $('img[id=\"' + activeImg[i] + '\"]')\n        .parent()\n        .parent()[0].children[0].children[2].children[0];\n      label.innerText = \"\";\n      label.id = \"\";\n    }\n    activeImg = [];\n    toActive();\n    saveInfo(false);\n  } else if (activeTime.length > 0) {\n    activeTimeId = \"\";\n    var my_progress_bar = $(\".my-progress-bar\");\n    loadProgress();\n    for (let i = 0; i < my_progress_bar.length; i++) {\n      if (my_progress_bar[i].dataset.tagid) {\n        var arr = my_progress_bar[i].dataset.originalTitle.split(\"-\");\n        var start = arr[0].slice(0, -1);\n        var end = arr[1].slice(0, -1);\n        if (activeTime[0] == start && activeTime[1] == end) {\n          $(\".my-progress-bar\")[i].remove();\n          break;\n        }\n      }\n    }\n    activeTime = [];\n    toActiveTime();\n    saveTimeInfo();\n  }\n}\nfunction enableRadio() {\n  var radios = $('input[type=\"radio\"]');\n  for (var i = 0; i < radios.length; i++) {\n    $(radios[i])[0].disabled = false;\n  }\n}\nfunction disableRadio() {\n  var radios = $('input[type=\"radio\"]');\n  for (var i = 0; i < radios.length; i++) {\n    radios[i].disabled = true;\n    radios[i].checked = false;\n  }\n}\nfunction toActive() {\n  if (activeImg.length > 0) {\n    enableRadio();\n    $(\".delTagBtn\").show();\n  } else {\n    $(\".delTagBtn\").hide();\n  }\n  var imgDivs = $(\".grid-content\");\n  for (var i = 0; i < imgDivs.length; i++) {\n    imgDivs[i].className = \"grid-content\";\n  }\n  for (var j = 0; j < activeImg.length; j++) {\n    for (var i = 0; i < imgDivs.length; i++) {\n      var imgId = imgDivs[i].children[0].children[1].children[0].id;\n      var icon = imgDivs[i].children[0];\n      if (imgId == activeImg[j]) {\n        imgDivs[i].className = \"grid-content active\";\n      }\n    }\n  }\n}\n\nfunction changeActiveImg(e) {\n  var src = $(e)[0].children[1].children[0].id;\n  if (src) {\n    src = parseFloat(src);\n    var length = activeImg.length;\n    if (length == 0) {\n      activeImg.push(src);\n    } else if (length == 1) {\n      activeImg.push(src);\n      var start = 0;\n      var end = 0;\n      start = activeImg[0];\n      end = activeImg[1];\n      var item = start;\n      if (start > end) {\n        start = end;\n        end = item;\n      }\n      var active = [];\n      for (var j = start; j < end + 1; j++) {\n        active.push(j);\n      }\n      activeImg = active;\n    } else {\n      activeImg = [];\n      activeImg.push(src);\n    }\n    toActive();\n  }\n}\nfunction changeTag(item) {\n  if (activeImg.length > 0) {\n    var tag = $(item)[0].nextSibling.innerText;\n    var tagId = $(item)[0].value;\n    for (var i = 0; i < activeImg.length; i++) {\n      var img = $('img[id=\"' + activeImg[i] + '\"]');\n      var label = $('img[id=\"' + activeImg[i] + '\"]')\n        .parent()\n        .parent()[0].children[0].children[2].children[0];\n      label.innerText = tag;\n      label.id = tagId;\n      for (var k = 0; k < tagsArr.length; k++) {\n        if (tagsArr[k][0] == tagId) {\n          label.style.background = tagsArr[k][2];\n          break;\n        }\n      }\n    }\n    activeImg = [];\n    toActive();\n    saveInfo(false);\n  } else if (activeTime.length > 0) {\n    var my_progress_bar = $(\".my-progress-bar\");\n    var tag = $(item)[0].nextSibling.innerText;\n    var tagId = $(item)[0].value;\n    var start = parseFloat(activeTime[0]);\n    var end = parseFloat(activeTime[1]);\n    var id = $(\".my-progress-bar\").length + 1;\n    var flag = false;\n    for (let i = 0; i < my_progress_bar.length; i++) {\n      if (my_progress_bar[i].dataset.tagid) {\n        if ($(\".my-progress-bar\")[i].id == activeTimeId) {\n          id = activeTimeId;\n          $(\".my-progress-bar\")[i].remove();\n          flag = true;\n          activeTimeId = \"\";\n          break;\n        }\n      }\n    }\n    activeTimeId = \"\";\n    if (!flag) {\n      loadProgress();\n    }\n    var progress = $(\"#myProgress\");\n    var item = parseFloat(end) - parseFloat(start);\n    var background;\n    for (var i = 0; i < tagsArr.length; i++) {\n      if (tagsArr[i][0] == tagId) {\n        background = tagsArr[i][2];\n        break;\n      }\n    }\n    var percent = item / duration;\n    var progress_bar =\n      '<div id=\"' +\n      id +\n      '\" onclick=\"changeSeek(' +\n      start.toFixed(0) +\n      \",\" +\n      end.toFixed(0) +\n      \",\" +\n      id +\n      ')\"class=\"my-progress-bar\"' +\n      'style=\"background:' +\n      background +\n      \";width:\" +\n      percent * width +\n      \"px;left:\" +\n      (start / duration) * width +\n      'px;\"' +\n      ' role=\"progressbar\" aria-valuemin=\"0\" aria-valuemax=\"100\"' +\n      ' data-toggle=\"popover\" rel=\"popover\" data-content=\"' +\n      tag +\n      '\" data-tagid=\"' +\n      tagId +\n      '\" data-original-title=\"' +\n      start.toFixed(0) +\n      \"s-\" +\n      end.toFixed(0) +\n      's\">' +\n      \"<span>\" +\n      tagId;\n    \"</span>\" + \"</div>\";\n    progress.append(progress_bar);\n    $(\"[data-toggle='popover']\").popover({\n      trigger: \"hover\",\n      placement: \"top\",\n      container: \"body\"\n    });\n    activeTime = [];\n    toActiveTime();\n    saveTimeInfo();\n  }\n  disableRadio();\n}\nfunction saveTimeInfo(flag) {\n  var oldState = result[urlIndex].state;\n  if (!flag) {\n    var my_progress_bar = $(\".my-progress-bar\");\n    var newTagInfo = [];\n    for (var i = 0; i < my_progress_bar.length; i++) {\n      if (my_progress_bar[i].dataset.originalTitle) {\n        var arr = my_progress_bar[i].dataset.originalTitle.split(\"-\");\n        var obj = {\n          tagId: my_progress_bar[i].dataset.tagid,\n          tag: my_progress_bar[i].dataset.content,\n          start: arr[0].slice(0, -1),\n          end: arr[1].slice(0, -1)\n        };\n        newTagInfo.push(obj);\n      }\n    }\n    result[urlIndex].tagInfo = newTagInfo.sort(compare(\"start\"));\n    tagInfo = result[urlIndex].tagInfo;\n    var table = tagInfoToBe(tagInfo);\n    $(\".result\").html(\"\");\n    $(\".result\").append(table);\n    loadProgress();\n  } else {\n    var answer = confirm(\"Save successfully, return to the home page ?\");\n    if (answer) {\n      result[urlIndex].times++;\n      result[urlIndex].state = 1;\n      if (oldState == 0) {\n        localStorage.setItem(\n          \"unTagTotal\",\n          parseInt(localStorage.getItem(\"unTagTotal\")) - 1\n        );\n        localStorage.setItem(\n          \"tagedTotal\",\n          parseInt(localStorage.getItem(\"tagedTotal\")) + 1\n        );\n        localStorage.setItem(\"result\", JSON.stringify(result));\n        window.location.href = \"../coin_annotation_tool.html?type=unTag\";\n      } else {\n        localStorage.setItem(\n          \"tagedTotal\",\n          parseInt(localStorage.getItem(\"tagedTotal\")) - 1\n        );\n        localStorage.setItem(\n          \"checkedTotal\",\n          parseInt(localStorage.getItem(\"checkedTotal\")) + 1\n        );\n        result[urlIndex].checked = true;\n        localStorage.setItem(\"result\", JSON.stringify(result));\n        window.location.href = \"../coin_annotation_tool.html?type=taged\";\n      }\n    } else {\n      localStorage.setItem(\"result\", JSON.stringify(result));\n    }\n  }\n}\nfunction tagInfoToBe(tagInfo) {\n  var table = \"\";\n  if (tagInfo.length > 0) {\n    table +=\n      \"<table class='table'><thead><th>TagID</th><th>Tag</th><th>Start</th><th>End</th>\";\n    for (var i in tagInfo) {\n      if (tagInfo[i].start == tagInfo[i].end) {\n        table +=\n          \"<tr style='color:red;font-weight:bolder' onclick='goHere(this,\" +\n          JSON.stringify(tagInfo[i]) +\n          \")'>\";\n      } else {\n        table +=\n          \"<tr onclick='goHere(this,\" + JSON.stringify(tagInfo[i]) + \")'>\";\n      }\n      for (var key in tagInfo[i]) {\n        if (key == \"start\" || key == \"end\") {\n          table += \"<td>\" + tagInfo[i][key] + \"s</td>\";\n        } else {\n          table += \"<td>\" + tagInfo[i][key] + \"</td>\";\n        }\n      }\n      table += \"</tr>\";\n    }\n    table += \"<table>\";\n  }\n  return table;\n}\nfunction goHere(self, tagInfo) {\n  var index = $(self)[0].rowIndex;\n  var className = $(self)\n    .parent()\n    .parent()\n    .parent()\n    .parent()\n    .parent()[0].className;\n  if (className == \"modelRight\") {\n    changeSeek(\n      parseFloat(tagInfo.start).toFixed(0),\n      parseFloat(tagInfo.end).toFixed(0),\n      index,\n      true\n    );\n  } else if (className == \"tagRight\") {\n    var start = parseFloat(tagInfo.start);\n    var end = parseFloat(tagInfo.end);\n    var item = start;\n    if (start >= end) {\n      start = end;\n      end = item;\n    }\n    var arr = [];\n    for (var j = start; j < end + 1; j++) {\n      arr.push(j);\n    }\n    var newArr = [];\n    for (var i = 0; i < framesArr.length; i++) {\n      if (framesArr[i][2] >= start && framesArr[i][2] <= end) {\n        newArr.push(i);\n      }\n    }\n    activeImg = newArr;\n    $(\".delTagBtn\").show();\n    $(\".tagLeft\").scrollTop(0);\n    var fileDivs = document.getElementsByClassName(\"fileDiv\");\n    for (var i = 0; i < fileDivs.length; i++) {\n      var id =\n        fileDivs[i].children[0].children[0].children[0].children[1].children[0]\n          .innerText;\n      if (tagInfo.start - id == 0) {\n        var top = $(fileDivs[i]).position().top - 50;\n        $(\".tagLeft\").scrollTop(top);\n      }\n    }\n  }\n}\nfunction saveInfo(flag) {\n  var oldState = result[urlIndex].state;\n  if (!flag) {\n    var time = $(\".time\");\n    var imgs = $(\"img.miniImg\");\n    var tags = $(\".tag\");\n    var newTagInfo = [];\n    for (var i = 0; i < imgs.length; i++) {\n      if (tags[i].id) {\n        var obj = {\n          tagId: tags[i].id,\n          tag: tags[i].innerText,\n          frameData: [parseFloat(time[i].innerText)]\n        };\n        newTagInfo.push(obj);\n      }\n    }\n    result[urlIndex].tagInfo = format(newTagInfo);\n    var table = tagInfoToBe(result[urlIndex].tagInfo);\n    $(\".result\").html(\"\");\n    $(\".result\").append(table);\n  } else {\n    var answer = confirm(\"Save successfully, return to the home page ?\");\n    if (answer) {\n      result[urlIndex].times++;\n      result[urlIndex].state = 1;\n      if (oldState == 0) {\n        localStorage.setItem(\n          \"unTagTotal\",\n          parseInt(localStorage.getItem(\"unTagTotal\")) - 1\n        );\n        localStorage.setItem(\n          \"tagedTotal\",\n          parseInt(localStorage.getItem(\"tagedTotal\")) + 1\n        );\n        localStorage.setItem(\"result\", JSON.stringify(result));\n        window.location.href = \"../coin_annotation_tool.html?type=unTag\";\n      } else {\n        localStorage.setItem(\n          \"tagedTotal\",\n          parseInt(localStorage.getItem(\"tagedTotal\")) - 1\n        );\n        localStorage.setItem(\n          \"checkedTotal\",\n          parseInt(localStorage.getItem(\"checkedTotal\")) + 1\n        );\n        result[urlIndex].checked = true;\n        localStorage.setItem(\"result\", JSON.stringify(result));\n        window.location.href = \"../coin_annotation_tool.html?type=taged\";\n      }\n    } else {\n      localStorage.setItem(\"result\", JSON.stringify(result));\n    }\n  }\n}\n\nfunction format(arr) {\n  var result = [];\n  if (arr.length > 0) {\n    var result = [];\n    var tagInfoArr = [];\n    var obj = {\n      tagId: arr[0].tagId,\n      tag: arr[0].tag,\n      frameData: arr[0].frameData.concat()\n    };\n    tagInfoArr.push(obj);\n    for (var i = 1; i < arr.length; i++) {\n      var repeat = false;\n      for (var j = 0; j < tagInfoArr.length; j++) {\n        if (arr[i].tagId == tagInfoArr[j].tagId) {\n          repeat = true;\n          tagInfoArr[j].frameData.push(arr[i].frameData[0]);\n        }\n      }\n      if (!repeat) {\n        tagInfoArr.push(arr[i]);\n      }\n    }\n    for (var i in tagInfoArr) {\n      var frameData = tagInfoArr[i].frameData.concat();\n      var data = dispart(frameData);\n      var index = 0;\n      for (var j = 0; j < data.length; j++) {\n        var start = index;\n        var end = index;\n        if (data[j] != -1) {\n          end = j;\n        } else {\n          index = parseFloat(j) + 1;\n          end = parseFloat(j) - 1;\n          result.push({\n            tagId: tagInfoArr[i].tagId,\n            tag: tagInfoArr[i].tag,\n            start: data[start],\n            end: data[end]\n          });\n        }\n      }\n      result.push({\n        tagId: tagInfoArr[i].tagId,\n        tag: tagInfoArr[i].tag,\n        start: data[start],\n        end: data[end]\n      });\n    }\n  }\n  return result.sort(compare(\"start\"));\n}\nfunction compare(property) {\n  return function(a, b) {\n    var value1 = a[property];\n    var value2 = b[property];\n    return value1 - value2;\n  };\n}\nfunction dispart(arr) {\n  var cnt = 0;\n  var index = 0;\n  var j = 0,\n    i;\n  var newArr = [arr[0]];\n  var start = arr[0];\n  for (var i = 1; i < arr.length; i++) {\n    if (arr[i] - start != newSpace) {\n      newArr.push(-1);\n    }\n    newArr.push(arr[i]);\n    start = arr[i];\n  }\n  return newArr;\n}\n\nfunction getUrlParam(paraName) {\n  var url = decodeURI(document.location.toString());\n  var arrObj = url.split(\"?\");\n  if (arrObj.length > 1) {\n    var arrPara = arrObj[1].split(\"&\");\n    var arr;\n    for (var i = 0; i < arrPara.length; i++) {\n      arr = arrPara[i].split(\"=\");\n      if (arr != null && arr[0] == paraName) {\n        return arr[1];\n      }\n    }\n    return \"\";\n  } else {\n    return \"\";\n  }\n}\nfunction cloneObj(obj) {\n  var str,\n    newobj = obj.constructor === Array ? [] : {};\n  if (typeof obj !== \"object\") {\n    return;\n  } else if (window.JSON) {\n    (str = JSON.stringify(obj)), (newobj = JSON.parse(str));\n  } else {\n    for (var i in obj) {\n      newobj[i] = typeof obj[i] === \"object\" ? cloneObj(obj[i]) : obj[i];\n    }\n  }\n  return newobj;\n}\nfunction delVideo(e) {\n  var answer = confirm(\"Are you sure to delete the video?\");\n  if (answer == true) {\n    var oldState = result[urlIndex].state;\n    result[urlIndex].times++;\n    result[urlIndex].state = 2;\n    if (oldState == 0) {\n      localStorage.setItem(\n        \"unTagTotal\",\n        parseInt(localStorage.getItem(\"unTagTotal\")) - 1\n      );\n      localStorage.setItem(\n        \"delTagTotal\",\n        parseInt(localStorage.getItem(\"delTagTotal\")) + 1\n      );\n      localStorage.setItem(\"result\", JSON.stringify(result));\n      window.location.href = \"../coin_annotation_tool.html?type=unTag\";\n    } else {\n      localStorage.setItem(\n        \"tagedTotal\",\n        parseInt(localStorage.getItem(\"tagedTotal\")) - 1\n      );\n      localStorage.setItem(\n        \"delTagTotal\",\n        parseInt(localStorage.getItem(\"delTagTotal\")) + 1\n      );\n      localStorage.setItem(\"result\", JSON.stringify(result));\n      window.location.href = \"../coin_annotation_tool.html?type=taged\";\n    }\n  }\n}\n"
  },
  {
    "path": "lib/js/index.js",
    "content": "var urlsArr = [];\nvar tagsArr = [];\nvar framesArr = [];\nvar result = [];\nvar win;\nvar isShow = false;\nvar moveRight = $(\"#list_left\").width();\nvar type = getUrlParam(\"type\");\nvar arr = [\"unTag\", \"taged\", \"checked\", \"delTag\"];\nvar tab = type && arr.indexOf(type) > -1 ? \"#\" + type : \"#unTag\";\n$(\"#myTab a.tab\").click(function(e) {\n  e.preventDefault();\n  $(this).tab(\"show\");\n  tab = $(this)[0].hash;\n});\n\nfunction changeFile(e, id) {\n  result = [];\n  var name = \"\";\n  if (e.files[0]) {\n    name = e.files[0].name;\n  }\n  document.getElementById(id).value = name;\n}\n\nfunction handleExport(a) {\n  var result = JSON.parse(localStorage.getItem(\"result\"));\n  if (result.length == 0) {\n    showTip(\"The data is empty, unable to export\", \"warning\", \"500\");\n    return;\n  }\n  var newResult = [];\n  for (var i in result) {\n    for (var j in result[i].tagInfo) {\n      newResult.push({\n        URLID: result[i].urlId.trim(),\n        URL: result[i].url.trim(),\n        TagID: result[i].tagInfo[j].tagId,\n        Tag: result[i].tagInfo[j].tag,\n        Start: result[i].tagInfo[j].start,\n        End: result[i].tagInfo[j].end,\n        Time: result[i].times,\n        State: result[i].state\n      });\n    }\n  }\n  var thObj = newResult[0];\n  var thArr = [];\n  for (var key in thObj) {\n    thArr.push(key);\n  }\n  var thStr = thArr.join(\",\");\n\n  var outputArr = [];\n  outputArr.push(thStr);\n  for (var i in newResult) {\n    if (newResult[i].URLID && newResult[i].TagID) {\n      var tdObj = newResult[i];\n      var tdArr = [];\n      for (var key in tdObj) {\n        tdArr.push(tdObj[key]);\n      }\n      outputArr.push(tdArr);\n    }\n  }\n  var str = outputArr.join(\"\\n\");\n  str = encodeURIComponent(str);\n  var now = new Date().format(\"yyyy-MM-dd_hh.mm.ss\");\n  a.download = \"instruction_\" + now + \".txt\";\n  a.href = \"data:text/csv;charset=utf-8,\\ufeff\" + str;\n}\n\nfunction handleImport() {\n  result = [];\n  showTip(\"loading\", \"info\");\n  $(\"input[name=urls]\").csv2arr(function(arr) {\n    if (arr[0][0].trim() != \"URLID\" || arr[0][1].trim() != \"URL\") {\n      showTip(\"Video file format error\", \"warning\", \"500\");\n      $(\"#tip\").fadeOut(100);\n      return;\n    }\n    arr.splice(0, 1);\n    urlsArr = unique(arr);\n    if (urlsArr.length > 0) {\n      $(\"input[name=frames]\").csv2arr(function(arr) {\n        if (arr[0][0].trim() != \"URLID\" || arr[0][1].trim() != \"Frame\") {\n          showTip(\"Frame file format error\", \"warning\", \"500\");\n          $(\"#tip\").fadeOut(100);\n          return;\n        }\n        arr.splice(0, 1);\n        framesArr = arr.concat();\n        if (framesArr.length > 0) {\n          $(\"input[name=tags]\").csv2arr(function(arr) {\n            if (arr[0][0].trim() != \"TagID\" || arr[0][1].trim() != \"Tag\") {\n              showTip(\"Label file format error\", \"warning\", \"500\");\n              $(\"#tip\").fadeOut(100);\n              return;\n            } else {\n              arr.splice(0, 1);\n              tagsArr = arr.concat();\n              initTable();\n            }\n          });\n        } else {\n          showTip(\"frame data is null\", \"warning\", \"500\");\n          $(\"#export\").hide();\n        }\n      });\n    } else {\n      showTip(\"video data is null\", \"warning\", \"500\");\n      $(\"#export\").hide();\n    }\n  });\n}\nfunction initTable() {\n  $(\"#unTag\").html(\"\");\n  $(\"#taged\").html(\"\");\n  $(\"#delTag\").html(\"\");\n  result = createTable(urlsArr);\n  localStorage.setItem(\"result\", JSON.stringify(result));\n  localStorage.setItem(\"tag\", JSON.stringify(tagsArr));\n  localStorage.setItem(\"frame\", JSON.stringify(framesArr));\n}\nfunction handleDelete(e) {\n  var tr = $(e)\n    .parent()\n    .parent()\n    .parent().prevObject[0];\n  var urlId = $(tr).find(\"td\")[0].innerText;\n  for (var i in result) {\n    if (result[i].urlId == parseInt(urlId)) {\n      if (tab == \"#unTag\") {\n        localStorage.setItem(\n          \"unTagTotal\",\n          parseInt(localStorage.getItem(\"unTagTotal\")) - 1\n        );\n      } else {\n        localStorage.setItem(\n          \"tagedTotal\",\n          parseInt(localStorage.getItem(\"tagedTotal\")) - 1\n        );\n      }\n      localStorage.setItem(\n        \"delTagTotal\",\n        parseInt(localStorage.getItem(\"delTagTotal\")) + 1\n      );\n      $(\"#unTagTotal\").html(localStorage.getItem(\"unTagTotal\"));\n      $(\"#tagedTotal\").html(localStorage.getItem(\"tagedTotal\"));\n      $(\"#delTagTotal\").html(localStorage.getItem(\"delTagTotal\"));\n      result[i].state = 2;\n      localStorage.setItem(\"result\", JSON.stringify(result));\n      $(tr).remove();\n      var tr = \"<tr><td>\" + result[i].urlId;\n      tr += \"<td>\" + result[i].url + \"</td>\";\n      tr += \"<td>\" + result[i].times + \"</td>\";\n      tr +=\n        \"<td><button onclick='handleReturn(this)' class='btn btn-danger' type='button'>Restore</button></td>\";\n      tr += \"</tr>\";\n\n      if ($(\"#delTag:has(tbody)\").length == 0) {\n        $(\"#delTag table\").append(\"<tbody>\" + tr + \"</tbody>\");\n      } else {\n        $(\"#delTag tbody\").prepend(tr);\n      }\n      return;\n    }\n  }\n}\nfunction handleReturn(e) {\n  var tr = $(e)\n    .parent()\n    .parent()\n    .parent().prevObject[0];\n  var urlId = $(tr).find(\"td\")[0].innerText;\n  for (var i in result) {\n    if (result[i].urlId == parseInt(urlId)) {\n      $(tr).remove();\n      var tr = \"<tr><td>\" + result[i].urlId + \"</td>\";\n      tr += \"<td>\" + result[i].url + \"</td>\";\n      tr += \"<td>\" + result[i].times + \"</td>\";\n\n      if (parseInt(result[i].times) > 0) {\n        tr +=\n          \"<td><button onclick='goTag(this)' class='btn btn-info'>Checkout</button><button onclick='handleDelete(this)' class='btn btn-danger' type='button'>Delete</button></td>\";\n        tr += \"</tr>\";\n        localStorage.setItem(\n          \"tagedTotal\",\n          parseInt(localStorage.getItem(\"tagedTotal\")) + 1\n        );\n        result[i].state = 1;\n        if ($(\"#taged:has(tbody)\").length == 0) {\n          $(\"#taged table\").append(\"<tbody>\" + tr + \"</tbody>\");\n        } else {\n          $(\"#taged tbody\").prepend(tr);\n        }\n      } else {\n        tr +=\n          \"<td><button onclick='goTag(this)' class='btn btn-info'>Label</button><button onclick='handleDelete(this)' class='btn btn-danger' type='button'>Delete</button></td>\";\n        tr += \"</tr>\";\n        localStorage.setItem(\n          \"unTagTotal\",\n          parseInt(localStorage.getItem(\"unTagTotal\")) + 1\n        );\n        result[i].state = 0;\n        if ($(\"#unTag:has(tbody)\").length == 0) {\n          $(\"#unTag table\").append(\"<tbody>\" + tr + \"</tbody>\");\n        } else {\n          $(\"#unTag tbody\").prepend(tr);\n        }\n      }\n\n      localStorage.setItem(\n        \"delTagTotal\",\n        parseInt(localStorage.getItem(\"delTagTotal\")) - 1\n      );\n      $(\"#unTagTotal\").html(localStorage.getItem(\"unTagTotal\"));\n      $(\"#tagedTotal\").html(localStorage.getItem(\"tagedTotal\"));\n      $(\"#delTagTotal\").html(localStorage.getItem(\"delTagTotal\"));\n      localStorage.setItem(\"result\", JSON.stringify(result));\n      return;\n    }\n  }\n}\n\n$(function() {\n  var param = getUrlParam(\"type\");\n  if (param) {\n    $('#myTab a[href=\"#' + param + '\"]').tab(\"show\");\n  }\n  var resultLocal = JSON.parse(localStorage.getItem(\"result\"));\n  var tagsArrLocal = JSON.parse(localStorage.getItem(\"tag\"));\n  var framesArrLocal = JSON.parse(localStorage.getItem(\"frame\"));\n  if (\n    resultLocal &&\n    tagsArrLocal &&\n    framesArrLocal &&\n    resultLocal.length > 0 &&\n    tagsArrLocal.length > 0 &&\n    framesArrLocal.length > 0\n  ) {\n    urlsArr = resultLocal;\n    tagsArr = tagsArrLocal;\n    framesArr = framesArrLocal;\n    initTable();\n  }\n  var unTagTotal = localStorage.getItem(\"unTagTotal\")\n    ? localStorage.getItem(\"unTagTotal\")\n    : 0;\n  var tagedTotal = localStorage.getItem(\"tagedTotal\")\n    ? localStorage.getItem(\"tagedTotal\")\n    : 0;\n  var checkedTotal = localStorage.getItem(\"checkedTotal\")\n    ? localStorage.getItem(\"checkedTotal\")\n    : 0;\n  var delTagTotal = localStorage.getItem(\"delTagTotal\")\n    ? localStorage.getItem(\"delTagTotal\")\n    : 0;\n  $(\"#unTagTotal\").html(unTagTotal);\n  $(\"#checkedTotal\").html(checkedTotal);\n  $(\"#tagedTotal\").html(tagedTotal);\n  $(\"#delTagTotal\").html(delTagTotal);\n});\n"
  }
]