| @@ -95,3 +95,6 @@ prime/ | |||||
| # Make evidence files | # Make evidence files | ||||
| /.make_evidence | /.make_evidence | ||||
| /templates/home_bak.tmpl | |||||
| /==bak | |||||
| @@ -1,3 +1,4 @@ | |||||
| Copyright (c) 2020 The OpenI&Trustie Authors | |||||
| Copyright (c) 2016 The Gitea Authors | Copyright (c) 2016 The Gitea Authors | ||||
| Copyright (c) 2015 The Gogs Authors | Copyright (c) 2015 The Gogs Authors | ||||
| @@ -1,25 +1,48 @@ | |||||
| [English](README.md) | |||||
| <h1><img src="public/img/favicon.png" alt="logo" width="30" height="30"> OpenData - open data project management</h1> | |||||
| [](https://drone.gitea.io/go-gitea/gitea) | |||||
| [](https://discord.gg/Gitea) | |||||
| [](https://microbadger.com/images/gitea/gitea "Get your own image badge on microbadger.com") | |||||
| [](https://codecov.io/gh/go-gitea/gitea) | |||||
| [](https://godoc.org/code.gitea.io/gitea) | |||||
| [](https://github.com/go-gitea/gitea/releases/latest) | |||||
| [](https://www.codetriage.com/go-gitea/gitea) | |||||
| [](https://opencollective.com/gitea) | |||||
| <!--[English](README_EN.md)--> | |||||
| <h1><img src="public/img/favicon.png" alt="logo" width="30" height="30">AiForge - 启智AI开发协作平台</h1> | |||||
| [](https://git.openi.org.cn/OpenI/aiforge/releases/latest) | |||||
| [](https://opensource.org/licenses/MIT) | [](https://opensource.org/licenses/MIT) | ||||
| [](https://crowdin.com/project/gitea) | |||||
| ## 目标 | |||||
| OpenData 的首要目标是提供对开源数据的大存储支持和管理,旨在为国家开源项目的建设贡献力量。为软件行业中的开源项目的发展提供助力。 | |||||
| ## AiForge | |||||
| 启智AI开发协作平台是一个在线Web应用,旨在为人工智能算法、模型开发提供在线协同工作环境,它提供了<b>代码托管、数据集管理与共享、免费云端算力资源支持(GPU/NPU)、共享镜像</b>等功能。 | |||||
| [启智AI开发协作平台](https://git.openi.org.cn) 是使用本项目构建的在线服务,您可以直接点击链接访问试用。 | |||||
| 本项目是基于[Gitea](https://github.com/go-gitea/gitea)发展而来的,我们对其进行了Fork并基于此扩展了人工智能开发中需要的功能,如数据集管理和模型训练等。对于和代码托管相关的功能,您可以参考[Gitea的文档](https://docs.gitea.io/zh-cn/)。 | |||||
| ### 系统总体架构 | |||||
| 下图展示了系统总体架构,本项目分为Web前端和服务后端,Web页面面向算法开发者、应用开发者、科研工作者、学生等用户群体,通过统一的Web页面入口,使用系统提供的系统服务。 | |||||
| 后端服务涵盖了AI模型开发流水线,包括代码协同开发、数据管理、模型调试、训练、推理和部署等(*目前尚未支持模型部署*)。在不同的开发阶段,我们还将提供丰富的开发工具供用户使用,如数据标注、数据筛选、模型转换、模型压缩、代码检测等。我们也欢迎社区提供更多丰富的工具接入,提高利用平台进行开发的效率。 | |||||
|  | |||||
| ## 在线服务使用 | |||||
| 本项目的在线服务平台的详细使用帮助文档,可参阅本项目[百科](https://git.openi.org.cn/OpenI/aiforge/wiki)内容。 | |||||
| - 如何创建账号 | |||||
| - 如何创建组织及管理成员权限 | |||||
| - 如何创建项目仓库 | |||||
| - 如何使用数据集功能 | |||||
| - 如何使用计算资源进行模型调试和训练 | |||||
| - 使用小技巧 | |||||
| - 常见问题(FAQ) | |||||
| ## 安装 | |||||
| 您也可以基于本项目代码,在本地环境安装部署服务。 | |||||
| ### 数据库准备 | |||||
| [数据库准备说明](https://docs.gitea.io/zh-cn/database-prep/) | |||||
| ### 从源代码安装 | |||||
| - node版本 >= v10.13.0 | |||||
| - golang版本 >= 1.13.3 | |||||
| [从源代码安装说明](https://docs.gitea.io/zh-cn/install-from-source/) | |||||
| ## 我们所提供的 | |||||
| ## 授权许可 | |||||
| 本项目采用 MIT 开源授权许可证,完整的授权说明已放置在 [LICENSE](https://git.openi.org.cn/OpenI/aiforge/src/branch/develop/LICENSE) 文件中。 | |||||
| - 项目管理 | |||||
| - git代码管理 | |||||
| - <strong>大数据集存储管理,最高单个数据集限制为1TB</strong> | |||||
| - 初期为社区项目免费提供30PB的算力,后续根据使用情况逐步增加 | |||||
| ## 需要帮助? | |||||
| 如果您在使用或者开发过程中遇到问题,可以在以下渠道咨询: | |||||
| - 点击[这里](https://git.openi.org.cn/OpenI/aiforge/issues)在线提交问题(点击页面右上角绿色按钮**创建任务**) | |||||
| - 加入微信群实时交流,获得进一步的支持 | |||||
| <img src="https://git.openi.org.cn/OpenI/aiforge/wiki/raw/img/wechatgroup.jpg" width=200px /> | |||||
| @@ -0,0 +1,184 @@ | |||||
| .bg-gray{ background-color:#F8F8F8!important;} | |||||
| .am-mb-0{ margin-bottom: 0 !important;} | |||||
| .am-mb-05{ margin-bottom: 0.5rem !important;} | |||||
| .am-mb-10{ margin-bottom: 1.0rem !important;} | |||||
| .am-mb-15{ margin-bottom: 1.5rem !important;} | |||||
| .am-mb-20{ margin-bottom: 2.0rem !important;} | |||||
| .am-mb-30{ margin-bottom: 3.0rem !important;} | |||||
| .am-mt-0{ margin-top: 0 !important;} | |||||
| .am-mt-05{ margin-top: 0.5rem !important;} | |||||
| .am-mt-10{ margin-top: 1.0rem !important;} | |||||
| .am-mt-15{ margin-top: 1.5rem !important;} | |||||
| .am-mt-20{ margin-top: 2.0rem !important;} | |||||
| .am-mt-30{ margin-top: 3.0rem !important;} | |||||
| .am-pb-0{ padding-bottom: 0 !important;} | |||||
| .am-pb-05{ padding-bottom: 0.5rem !important;} | |||||
| .am-pb-10{ padding-bottom: 1.0rem !important;} | |||||
| .am-pb-15{ padding-bottom: 1.5rem !important;} | |||||
| .am-pb-20{ padding-bottom: 2.0rem !important;} | |||||
| .am-pb-30{ padding-bottom: 3.0rem !important;} | |||||
| .am-pt-0{ padding-top: 0 !important;} | |||||
| .am-pt-05{ padding-top: 0.5rem !important;} | |||||
| .am-pt-10{ padding-top: 1.0rem !important;} | |||||
| .am-pt-15{ padding-top: 1.5rem !important;} | |||||
| .am-pt-20{ padding-top: 2.0rem !important;} | |||||
| .am-pt-30{ padding-top: 3.0rem !important;} | |||||
| .am-pl-30{ padding-left: 3.0rem !important;} | |||||
| .am-ml-30{ margin-left: 3.0rem !important;} | |||||
| .am-pr-30{ padding-right: 3.0rem !important;} | |||||
| .am-mr-30{ margin-right: 3.0rem !important;} | |||||
| .am-lh-18{ line-height: 1.8em;} | |||||
| .opacity5{ opacity:0.5;} | |||||
| .radius15{ border-radius:1.5rem !important; } | |||||
| .radius10{ border-radius:1.0rem !important; } | |||||
| .radius5{ border-radius:0.5rem !important; } | |||||
| .am-shadow-1{ | |||||
| -webkit-box-shadow: 0 1px 2px 0 rgba(34,36,38,.15); | |||||
| box-shadow: 0 1px 2px 0 rgba(34,36,38,.15); | |||||
| } | |||||
| .am-shadow-2{ | |||||
| -webkit-box-shadow: 0 2px 4px 0 rgba(34,36,38,.3); | |||||
| box-shadow: 0 2px 4px 0 rgba(34,36,38,.3); | |||||
| } | |||||
| .ui.secondary.hometop.segment{ | |||||
| background: #DFE9F0; | |||||
| padding-top: 0; | |||||
| border: none; | |||||
| margin-bottom: 90px; | |||||
| } | |||||
| .ui.secondary.hometop.segment #navbar{ | |||||
| z-index: 10; | |||||
| } | |||||
| .hometop .ui.secondary.menu .active.item{ | |||||
| color: #000; | |||||
| background:none; | |||||
| border-bottom: 1px solid #000; | |||||
| } | |||||
| .hometop .following.bar #navbar .brand{ | |||||
| padding-top: .78571429em; | |||||
| } | |||||
| .hometop .following.bar .brand .ui.mini.image { | |||||
| height: 50px; | |||||
| } | |||||
| .homebanner{ | |||||
| position: relative; | |||||
| padding: 100px 32px 80px; | |||||
| z-index: 9; | |||||
| } | |||||
| .homebanner .ui.header .sub.header{ | |||||
| color: #3291F8; | |||||
| } | |||||
| .bannerpic{ | |||||
| position: absolute; | |||||
| right: 50px; | |||||
| bottom: -64px; | |||||
| width: 560px; | |||||
| } | |||||
| .ui[class*="very padded"].segment.i-code{ | |||||
| padding-left: 6.0rem; | |||||
| } | |||||
| .i-code > .ui.blue.header{ | |||||
| color: #1678c2!important; | |||||
| } | |||||
| .i-code h2{ | |||||
| position: relative; | |||||
| } | |||||
| .i-code h2::before { | |||||
| content: ""; | |||||
| position: absolute; | |||||
| left: calc(-4.0rem + 6px); | |||||
| top: 0.8rem; | |||||
| width: 18px; | |||||
| height: 18px; | |||||
| border: 2px solid #505559; | |||||
| border-radius: 50%; | |||||
| background: #1b1c1d; | |||||
| z-index: 9; | |||||
| } | |||||
| .i-code h2.am-bw::before{ | |||||
| background: #FFF; | |||||
| } | |||||
| .i-code-pic{ | |||||
| position: relative; | |||||
| } | |||||
| .i-code-pic > img{ | |||||
| margin-bottom: -3.0rem; | |||||
| } | |||||
| .i-env .ui.cards>.card>.image{ | |||||
| background: none; | |||||
| } | |||||
| .i-env .ui.cards>.card>.content{ | |||||
| border-top: none; | |||||
| } | |||||
| .leftline01{ | |||||
| position: absolute; | |||||
| left: 3.0rem; | |||||
| top: 0; | |||||
| bottom: 0; | |||||
| border-left: 2px solid #505559; | |||||
| border-bottom: 2px solid #505559; | |||||
| border-radius: 0 0 0 2.0rem; | |||||
| width: 2.0rem; | |||||
| } | |||||
| .leftline02{ | |||||
| position: absolute; | |||||
| left: 5rem; | |||||
| top: calc(-5.0rem - 2px); | |||||
| border-top: 2px solid #505559; | |||||
| border-right: 2px solid #505559; | |||||
| border-radius: 0 2.0rem 0 0; | |||||
| width: 17.5rem; | |||||
| height: 6.0rem; | |||||
| } | |||||
| @media only screen and (max-width: 767px) { | |||||
| .am-mt-30{ margin-top: 1.5rem !important;} | |||||
| .ui.secondary.hometop.segment{ | |||||
| margin-bottom: 2.0rem; | |||||
| } | |||||
| .bannerpic, .i-code-pic{ | |||||
| display: none; | |||||
| } | |||||
| .i-code h2::before { | |||||
| left: calc(-5.0rem + 6px); | |||||
| } | |||||
| .i-code h2.am-bw::before{ | |||||
| left: calc(-4.0rem + 6px); | |||||
| } | |||||
| .leftline01{ | |||||
| width: calc(50% - 4.0rem); | |||||
| } | |||||
| .leftline02{ | |||||
| left: calc(50% - 1.0rem); | |||||
| top: calc(-3.5rem - 2px); | |||||
| } | |||||
| } | |||||
| @media only screen and (min-width: 768px) and (max-width: 991px) { | |||||
| .bannerpic, .i-code-pic{ | |||||
| display: none; | |||||
| } | |||||
| .i-code h2::before { | |||||
| left: calc(-5.0rem + 6px); | |||||
| } | |||||
| .i-code h2.am-bw::before{ | |||||
| left: calc(-4.0rem + 6px); | |||||
| } | |||||
| } | |||||
| @media only screen and (min-width: 992px) and (max-width: 1199px) { | |||||
| } | |||||
| @media only screen and (min-width: 1200px) and (max-width: 1919px) { | |||||
| } | |||||
| @media only screen and (min-width: 1920px) { | |||||
| } | |||||
| @@ -0,0 +1,711 @@ | |||||
| <?xml version="1.0" encoding="utf-8"?> | |||||
| <!-- Generator: Adobe Illustrator 25.3.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> | |||||
| <svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" | |||||
| viewBox="0 0 1216 416" style="enable-background:new 0 0 1216 416;" xml:space="preserve"> | |||||
| <style type="text/css"> | |||||
| .st0{fill:url(#SVGID_1_);stroke:#CBCFDE;stroke-width:2;stroke-dasharray:3;} | |||||
| .st1{fill:#E5EAF3;stroke:#A5ADC1;stroke-width:0.5;} | |||||
| .st2{fill:url(#SVGID_2_);} | |||||
| .st3{fill:#FFFFFF;stroke:#A5ADC1;stroke-width:0.5;} | |||||
| .st4{opacity:0.6;} | |||||
| .st5{fill:none;stroke:#3A51C6;stroke-width:4;} | |||||
| .st6{fill:#3A51C6;} | |||||
| .st7{opacity:0.6;fill:#3A51C6;enable-background:new ;} | |||||
| .st8{font-family:'MicrosoftYaHeiLight';} | |||||
| .st9{font-size:14px;} | |||||
| .st10{fill-rule:evenodd;clip-rule:evenodd;fill:#FFFFFF;fill-opacity:0.4;stroke:#CBCFDE;} | |||||
| .st11{fill:#252B3A;} | |||||
| .st12{font-family:'MicrosoftYaHei';} | |||||
| .st13{fill:none;} | |||||
| .st14{fill-rule:evenodd;clip-rule:evenodd;fill:#D5E0F3;} | |||||
| .st15{fill-rule:evenodd;clip-rule:evenodd;fill:#F7FAFF;} | |||||
| .st16{fill-rule:evenodd;clip-rule:evenodd;fill:#F1F6FF;} | |||||
| .st17{fill:none;stroke:#A5ADC1;stroke-width:0.5;} | |||||
| .st18{fill:none;stroke:#555A6F;stroke-width:0.6232;} | |||||
| .st19{fill-rule:evenodd;clip-rule:evenodd;fill:#E3EBF9;} | |||||
| .st20{fill-rule:evenodd;clip-rule:evenodd;fill:#E8ECF3;} | |||||
| .st21{fill-rule:evenodd;clip-rule:evenodd;fill:#E5EAF3;stroke:#A5ADC1;stroke-width:0.5;} | |||||
| .st22{fill-rule:evenodd;clip-rule:evenodd;fill:url(#Fill-612_1_);} | |||||
| .st23{fill-rule:evenodd;clip-rule:evenodd;fill:url(#Fill-19_1_);} | |||||
| .st24{fill:none;stroke:#A5ADC1;stroke-width:0.5422;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:2.4994;} | |||||
| .st25{fill-rule:evenodd;clip-rule:evenodd;fill:url(#形状结合_1_);} | |||||
| .st26{fill:none;stroke:#555A6F;stroke-width:1.0843;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:2.4994;} | |||||
| .st27{fill-rule:evenodd;clip-rule:evenodd;fill:url(#形状结合_2_);} | |||||
| .st28{fill:url(#Oval-2_1_);} | |||||
| .st29{fill:url(#Combined-Shape_1_);} | |||||
| .st30{opacity:0.4017;fill:none;stroke:#7D849E;stroke-width:0.7429;enable-background:new ;} | |||||
| .st31{fill:#A5ADC1;} | |||||
| .st32{opacity:0.5012;fill:#A5ADC1;enable-background:new ;} | |||||
| .st33{fill-rule:evenodd;clip-rule:evenodd;fill:url(#Fill-612_6_);} | |||||
| .st34{fill-rule:evenodd;clip-rule:evenodd;fill:#EBEDF2;fill-opacity:0.4;stroke:#CBCFDE;} | |||||
| .st35{fill-rule:evenodd;clip-rule:evenodd;fill:#FFFFFF;} | |||||
| .st36{fill-rule:evenodd;clip-rule:evenodd;fill:url(#Fill-1_3_);} | |||||
| .st37{fill-rule:evenodd;clip-rule:evenodd;fill:url(#Fill-3_3_);} | |||||
| .st38{fill-rule:evenodd;clip-rule:evenodd;fill:url(#Fill-8_1_);} | |||||
| .st39{fill-rule:evenodd;clip-rule:evenodd;fill:url(#Fill-5_1_);} | |||||
| .st40{fill:none;stroke:#555A6F;} | |||||
| .st41{fill-rule:evenodd;clip-rule:evenodd;fill:url(#路径-25_1_);} | |||||
| .st42{fill-rule:evenodd;clip-rule:evenodd;fill:#A5ADC1;} | |||||
| .st43{opacity:0.4319;fill-rule:evenodd;clip-rule:evenodd;fill:#A5ADC1;enable-background:new ;} | |||||
| .st44{fill:none;stroke:#999FB6;stroke-width:0.5;} | |||||
| .st45{fill-rule:evenodd;clip-rule:evenodd;fill:url(#路径-13_1_);} | |||||
| .st46{opacity:0.506;fill-rule:evenodd;clip-rule:evenodd;fill:#7D849E;enable-background:new ;} | |||||
| .st47{fill-rule:evenodd;clip-rule:evenodd;fill:#7D849E;} | |||||
| .st48{fill-rule:evenodd;clip-rule:evenodd;fill:url(#形状结合_3_);} | |||||
| .st49{opacity:0.6;enable-background:new ;} | |||||
| .st50{fill-rule:evenodd;clip-rule:evenodd;fill:url(#Fill-1_4_);} | |||||
| .st51{fill-rule:evenodd;clip-rule:evenodd;fill:url(#Fill-3_4_);} | |||||
| .st52{fill-rule:evenodd;clip-rule:evenodd;fill:url(#Fill-8_6_);} | |||||
| .st53{fill-rule:evenodd;clip-rule:evenodd;fill:url(#Fill-5_6_);} | |||||
| .st54{font-family:'MicrosoftYaHei-Bold';} | |||||
| .st55{fill:none;stroke:#CBCFDE;stroke-width:2;stroke-dasharray:3;} | |||||
| </style> | |||||
| <linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="116.4526" y1="207.6249" x2="1210.4272" y2="207.6249"> | |||||
| <stop offset="0" style="stop-color:#FEFEFF"/> | |||||
| <stop offset="1" style="stop-color:#F1F6FF"/> | |||||
| </linearGradient> | |||||
| <polygon class="st0" points="1210.4,207.6 1156.5,0 1156.5,24.6 116.5,24.6 116.5,390.7 1156.5,390.7 1156.5,415.2 "/> | |||||
| <desc>Created with Sketch.</desc> | |||||
| <g> | |||||
| <circle class="st1" cx="47.3" cy="223.3" r="21.1"/> | |||||
| <linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="29.2261" y1="223.2895" x2="65.3497" y2="223.2895"> | |||||
| <stop offset="0" style="stop-color:#FEFEFF"/> | |||||
| <stop offset="1" style="stop-color:#F1F6FF"/> | |||||
| </linearGradient> | |||||
| <circle class="st2" cx="47.3" cy="223.3" r="18.1"/> | |||||
| <g> | |||||
| <circle class="st3" cx="47.3" cy="218.2" r="6"/> | |||||
| <path class="st3" d="M47.3,224.3c-5.6,0-10.1,4.5-10.1,10.1h20.2C57.4,228.8,52.9,224.3,47.3,224.3z"/> | |||||
| </g> | |||||
| </g> | |||||
| <g> | |||||
| <g class="st4"> | |||||
| <line class="st5" x1="67.9" y1="223.3" x2="126.8" y2="223.3"/> | |||||
| <g> | |||||
| <polygon class="st6" points="118.9,233.1 117.2,231.3 125.9,223.3 117.2,215.2 118.9,213.5 129.4,223.3 "/> | |||||
| </g> | |||||
| </g> | |||||
| </g> | |||||
| <text transform="matrix(1 0 0 1 71.1347 209.8902)" class="st7 st8 st9">用户登录</text> | |||||
| <g> | |||||
| <path id="矩形备份-2_1_" class="st10" d="M272.5,185.6H130.4c-0.3,0-0.5,0.2-0.7,0.4c-0.2,0.3-0.3,0.6-0.3,1.1v76 | |||||
| c0,0.4,0.1,0.8,0.3,1.1c0.2,0.3,0.4,0.4,0.7,0.4h142.2c0.3,0,0.5-0.2,0.7-0.4c0.2-0.3,0.3-0.6,0.3-1.1v-76c0-0.4-0.1-0.8-0.3-1.1 | |||||
| C273,185.7,272.8,185.6,272.5,185.6z"/> | |||||
| <text transform="matrix(1 0 0 1 199.7773 229.2355)" class="st11 st12 st9">创建项目</text> | |||||
| <g id="电脑_2_" transform="translate(33.000000, 32.000000) scale(-1, 1) translate(-33.000000, -32.000000) translate(1.000000, 0.000000)"> | |||||
| <g> | |||||
| <rect id="矩形_16_" x="-133.9" y="257.1" class="st13" width="64" height="-64"/> | |||||
| <g id="电脑复制_1_" transform="translate(11.000000, 2.000000)"> | |||||
| <g id="编组_4_" transform="translate(5.371982, 40.317507)"> | |||||
| <polygon id="矩形_15_" class="st14" points="-120.8,209.4 -102.9,198.5 -102.9,201.4 -120.8,212.2 "/> | |||||
| <polygon id="矩形_14_" class="st15" points="-112.2,193.1 -102.9,198.5 -120.8,209.4 -130.4,203.7 "/> | |||||
| <polygon id="矩形_12_" class="st16" points="-133.4,202 -120.8,209.4 -120.8,212.3 -133.4,204.9 "/> | |||||
| </g> | |||||
| <g id="电脑-2_1_"> | |||||
| <g id="电脑_3_"> | |||||
| <g id="Group-616_1_" transform="translate(2.559524, 37.948718)"> | |||||
| <g id="编组_3_" transform="translate(6.786976, 7.749090)"> | |||||
| <path id="形状结合_4_" class="st17" d="M-124.8,204l17.9-10.9 M-124.8,204v2.6 M-124.8,204l-8.7-5.1"/> | |||||
| </g> | |||||
| <polygon id="路径-6_1_" class="st18" points="-118,214.7 -133.6,205.4 -112.7,193.5 -100.1,200.7 -100.1,203.8 "/> | |||||
| </g> | |||||
| <g id="Group-616-Copy_1_" transform="translate(16.380952, 37.948718)"> | |||||
| <polygon id="Fill-610_1_" class="st16" points="-132,199.1 -132,206.9 -133.5,206.1 -133.5,198.2 "/> | |||||
| <polygon id="Fill-612_3_" class="st19" points="-132,199.1 -121.4,193.1 -121.4,200.7 -132,206.9 "/> | |||||
| <polyline id="Path-3_1_" class="st18" points="-133.5,201.7 -133.5,206 -132,206.9 -121.4,200.7 -121.4,194.6 -132,200.9 | |||||
| -132,206.9 "/> | |||||
| </g> | |||||
| <g id="Group-2_1_"> | |||||
| <path id="Fill-8_2_" class="st20" d="M-92.3,195c0.1,0,0.1,0,0.2-0.1c0,0,0.1,0,0.1,0c0,0,0.1,0,0.1,0c0,0,0.1,0,0.1,0 | |||||
| c0,0,0,0,0.1,0c0,0,0.1,0,0.1,0c0,0,0,0,0,0c0.1,0,0.1,0,0.2,0c0,0,0,0,0,0c0,0,0.1,0,0.1,0c0,0,0,0,0,0c0,0,0.1,0,0.1,0.1 | |||||
| l-2.7-1.6c0,0,0,0,0,0c0,0-0.1,0-0.1-0.1c0,0,0,0,0,0c0,0,0,0,0,0c0,0,0,0-0.1,0c0,0,0,0-0.1,0c0,0,0,0,0,0c0,0,0,0,0,0 | |||||
| c0,0-0.1,0-0.1,0c0,0,0,0,0,0c0,0,0,0,0,0c0,0-0.1,0-0.1,0c0,0,0,0,0,0c0,0,0,0-0.1,0c0,0,0,0-0.1,0c0,0,0,0-0.1,0 | |||||
| c0,0-0.1,0-0.1,0c0,0,0,0,0,0c0,0,0,0,0,0c0,0-0.1,0-0.2,0.1c0,0,0,0-0.1,0c0,0,0,0,0,0c-0.1,0-0.2,0.1-0.3,0.1l-36.2,21.1 | |||||
| c-0.1,0.1-0.2,0.1-0.3,0.2c0,0,0,0-0.1,0c-0.1,0.1-0.2,0.2-0.3,0.3c0,0,0,0,0,0c0,0,0,0,0,0c0,0-0.1,0.1-0.1,0.2c0,0,0,0,0,0 | |||||
| c0,0,0,0,0,0c0,0-0.1,0.1-0.1,0.1c0,0,0,0-0.1,0.1c0,0,0,0,0,0.1c0,0,0,0.1-0.1,0.1c0,0,0,0,0,0.1c0,0,0,0.1-0.1,0.1 | |||||
| c0,0,0,0,0,0.1c0,0,0,0,0,0c0,0.1-0.1,0.1-0.1,0.2c0,0,0,0,0,0c0,0,0,0,0,0c0,0,0,0.1-0.1,0.1c0,0,0,0,0,0.1s0,0,0,0.1 | |||||
| c0,0,0,0,0,0.1c0,0.1,0,0.1-0.1,0.2c0,0,0,0,0,0c0,0,0,0,0,0c0,0.1-0.1,0.1-0.1,0.2c0,0,0,0,0,0c0,0,0,0,0,0.1 | |||||
| c0,0,0,0.1,0,0.1c0,0,0,0.1,0,0.1c0,0,0,0.1,0,0.1c0,0,0,0,0,0.1c0,0,0,0.1,0,0.1c0,0,0,0.1,0,0.1c0,0,0,0,0,0 | |||||
| c0,0,0,0.1,0,0.1c0,0.1,0,0.1,0,0.2c0,0,0,0,0,0c0,0,0,0,0,0c0,0.1,0,0.3,0,0.4l0.1,26.3c0,0.7,0.2,1.2,0.6,1.4l2.7,1.6 | |||||
| c-0.4-0.2-0.6-0.7-0.6-1.4L-131,220c0-0.1,0-0.3,0-0.4c0,0,0-0.1,0-0.1c0-0.1,0-0.1,0-0.2c0,0,0-0.1,0-0.1c0,0,0-0.1,0-0.1 | |||||
| c0-0.1,0-0.1,0-0.2c0,0,0-0.1,0-0.1c0-0.1,0-0.1,0.1-0.2c0,0,0,0,0-0.1c0-0.1,0.1-0.2,0.1-0.2c0,0,0,0,0,0 | |||||
| c0-0.1,0.1-0.1,0.1-0.2c0,0,0,0,0-0.1c0-0.1,0.1-0.1,0.1-0.2c0,0,0,0,0,0c0-0.1,0.1-0.1,0.1-0.2c0,0,0,0,0-0.1 | |||||
| c0-0.1,0.1-0.1,0.1-0.2c0,0,0-0.1,0.1-0.1c0,0,0.1-0.1,0.1-0.1c0,0,0.1-0.1,0.1-0.1c0,0,0.1-0.1,0.1-0.1 | |||||
| c0-0.1,0.1-0.1,0.1-0.2c0,0,0,0,0.1-0.1c0.1-0.1,0.2-0.2,0.3-0.3c0,0,0,0,0.1,0c0.1-0.1,0.2-0.2,0.3-0.2l36.2-21.1 | |||||
| C-92.6,195.2-92.5,195.1-92.3,195C-92.4,195.1-92.4,195-92.3,195"/> | |||||
| <path id="Fill-6_3_" class="st21" d="M-91.1,196.8c0-0.8-0.3-1.3-0.8-1.6c-0.2-0.1-0.5-0.2-0.8-0.2c-0.3,0-0.6,0.1-0.9,0.3 | |||||
| l-35.8,21.1c-1.3,0.7-2.3,2.5-2.3,4l0.1,25.5c0,0.8,0.3,1.3,0.8,1.6c0.2,0.1,0.5,0.2,0.8,0.2c0.3,0,0.6-0.1,0.9-0.3 | |||||
| l35.8-20.7c1.3-0.7,2.3-2.5,2.3-4L-91.1,196.8z"/> | |||||
| <linearGradient id="Fill-612_1_" gradientUnits="userSpaceOnUse" x1="389.5026" y1="739.7053" x2="389.117" y2="739.0089" gradientTransform="matrix(-35.3958 0 0 -45.873 13684.2344 34133.2852)"> | |||||
| <stop offset="0" style="stop-color:#FEFEFF"/> | |||||
| <stop offset="1" style="stop-color:#F1F6FF"/> | |||||
| </linearGradient> | |||||
| <polygon id="Fill-612_2_" class="st22" points="-128.8,218.9 -93.5,198.3 -93.7,223.5 -128.9,244.1 "/> | |||||
| <path id="Combined-Shape_3_" class="st18" d="M-94.4,193.3L-94.4,193.3c0.1,0,0.1,0,0.3,0c0,0,0,0,0.2,0.1c0,0,0.1,0,0.1,0.1 | |||||
| l0,0l1.8,1.5c0.4,0.2,0.7,0.7,0.7,1.4l0.1,26.3c0,1.4-1,3-2.1,3.7l-36.2,21.1c-0.6,0.4-1.2,0.4-1.6,0.1l0,0l-1.8-1.5 | |||||
| c-0.4-0.2-0.6-0.6-0.6-1.2l0-0.2l-0.1-26.3c0-0.1,0-0.3,0-0.5c0-0.1,0-0.1,0.1-0.3c0,0,0-0.1,0.1-0.3c0,0,0-0.1,0-0.2 | |||||
| c0,0,0-0.1,0.1-0.2c0-0.1,0.1-0.1,0.1-0.2c0-0.1,0-0.1,0.1-0.2c0,0,0,0,0.1-0.2c0,0,0-0.1,0.1-0.2c0-0.1,0.1-0.1,0.1-0.2 | |||||
| c0,0,0,0,0,0l0.1-0.1c0,0,0,0,0.1-0.1c0,0,0,0,0.1-0.1c0,0,0.1-0.1,0.2-0.2c0-0.1,0.1-0.1,0.2-0.2c0.1-0.1,0.2-0.2,0.4-0.3 | |||||
| c0.1-0.1,0.2-0.2,0.3-0.2l0,0l36.2-21.1c0.1-0.1,0.2-0.1,0.4-0.2c0.1,0,0.1,0,0.2-0.1c0,0,0.1,0,0.1,0 | |||||
| C-94.6,193.4-94.6,193.4-94.4,193.3C-94.4,193.3-94.4,193.3-94.4,193.3L-94.4,193.3z"/> | |||||
| </g> | |||||
| </g> | |||||
| </g> | |||||
| </g> | |||||
| </g> | |||||
| </g> | |||||
| </g> | |||||
| <g> | |||||
| <path id="矩形备份-2_3_" class="st10" d="M434,96.7H291.8c-0.3,0-0.5,0.2-0.7,0.4c-0.2,0.3-0.3,0.6-0.3,1.1v76 | |||||
| c0,0.4,0.1,0.8,0.3,1.1c0.2,0.3,0.4,0.4,0.7,0.4H434c0.3,0,0.5-0.2,0.7-0.4c0.2-0.3,0.3-0.6,0.3-1.1v-76c0-0.4-0.1-0.8-0.3-1.1 | |||||
| C434.4,96.9,434.2,96.7,434,96.7z"/> | |||||
| <text transform="matrix(1 0 0 1 361.2133 140.4023)" class="st11 st12 st9">模型代码</text> | |||||
| <g id="dms_1_"> | |||||
| <rect id="矩形_18_" x="301.3" y="108.8" class="st13" width="52.3" height="52.3"/> | |||||
| <g> | |||||
| <rect id="矩形_17_" x="301.3" y="108.8" class="st13" width="52.3" height="52.3"/> | |||||
| <g transform="translate(1.000000, 8.000000)"> | |||||
| <g> | |||||
| <g id="Group_1_"> | |||||
| <linearGradient id="Fill-19_1_" gradientUnits="userSpaceOnUse" x1="-341.2138" y1="733.8543" x2="-340.639" y2="733.6519" gradientTransform="matrix(59.0908 0 0 -36.0906 20474.3906 26604.4609)"> | |||||
| <stop offset="0" style="stop-color:#F9FBFF"/> | |||||
| <stop offset="1" style="stop-color:#F1F6FF"/> | |||||
| </linearGradient> | |||||
| <polygon id="Fill-19_3_" class="st23" points="350.6,122.7 350.6,126.4 335.1,137.1 327.9,137.1 302.3,120.8 302.3,117.3 | |||||
| 318.6,107.6 325,107.6 "/> | |||||
| <polyline id="Fill-19_2_" class="st24" points="350.7,132.3 334.5,141.9 328,141.9 302,126.5 "/> | |||||
| <linearGradient id="形状结合_1_" gradientUnits="userSpaceOnUse" x1="-340.5574" y1="733.4007" x2="-341.7036" y2="733.4007" gradientTransform="matrix(59.9948 0 0 -33.8879 20792.1914 24986.5918)"> | |||||
| <stop offset="0" style="stop-color:#CBD3E0"/> | |||||
| <stop offset="0.1516" style="stop-color:#AEBACD"/> | |||||
| <stop offset="0.2692" style="stop-color:#B9C0CD"/> | |||||
| <stop offset="0.3557" style="stop-color:#B9C1CF"/> | |||||
| <stop offset="0.3934" style="stop-color:#CAD1DC"/> | |||||
| <stop offset="0.3987" style="stop-color:#C1C9D5"/> | |||||
| <stop offset="0.4191" style="stop-color:#C3CBD7"/> | |||||
| <stop offset="0.4339" style="stop-color:#C5CDD9"/> | |||||
| <stop offset="0.445" style="stop-color:#C9D1DD"/> | |||||
| <stop offset="0.464" style="stop-color:#D7DDE9"/> | |||||
| <stop offset="0.4788" style="stop-color:#DDE4EE"/> | |||||
| <stop offset="0.5501" style="stop-color:#D2D8E2"/> | |||||
| <stop offset="0.6178" style="stop-color:#D8DFE9"/> | |||||
| <stop offset="0.6932" style="stop-color:#DCE0E8"/> | |||||
| <stop offset="1" style="stop-color:#EBEEF2"/> | |||||
| </linearGradient> | |||||
| <path id="形状结合_7_" class="st25" d="M351,136.2l-0.8,1.6l-15.6,9.3h-7.1l-25-14.7l-0.6-1.5l0-11.5l0,0.2 | |||||
| c0.1,0.4,0.3,0.8,0.5,1.1c0.4,0.5,8.7,5.4,24.6,15c0.5,0.3,1.2,0.5,2.2,0.6c1.4,0.2,2.5,0.2,2.7,0.2c0.1,0,0.6,0,1.3-0.1 | |||||
| c0.8-0.1,1.5-0.4,2.1-0.7c0.6-0.3,5.6-3.4,15-9.1c0.3-0.3,0.5-0.8,0.6-1.3l0,0V136.2z"/> | |||||
| </g> | |||||
| <path id="路径-29_1_" class="st24" d="M301.8,126.2l25.2,14.9c1,0.5,1.9,0.8,2.5,0.8s1.8,0,3.5,0c1.2-0.1,2.4-0.4,3.7-1.2 | |||||
| c1.3-0.7,6-3.7,14.3-9"/> | |||||
| <path id="Path-9_1_" class="st26" d="M323.6,107.2h-3.9c-0.8,0-1.6,0.2-2.3,0.6l-13.7,8.1c-1.1,0.7-1.8,1.9-1.8,3.2v11.3 | |||||
| c0,1,0.5,2,1.4,2.5l23,13.6c1.1,0.6,2.3,1,3.5,1h3c1.3,0,2.5-0.4,3.6-1l12.8-7.8c1.1-0.7,1.8-1.9,1.8-3.2v-11.2 | |||||
| c0-1-0.5-2-1.4-2.5l-23.3-13.7C325.5,107.5,324.6,107.2,323.6,107.2z"/> | |||||
| </g> | |||||
| </g> | |||||
| </g> | |||||
| </g> | |||||
| <linearGradient id="形状结合_2_" gradientUnits="userSpaceOnUse" x1="-328.252" y1="733.1469" x2="-327.6247" y2="732.8809" gradientTransform="matrix(27.5169 0 0 -15.6984 9349.4238 11636.0732)"> | |||||
| <stop offset="0" style="stop-color:#828BB3"/> | |||||
| <stop offset="1" style="stop-color:#555A6F"/> | |||||
| </linearGradient> | |||||
| <path id="形状结合_5_" class="st27" d="M336.6,127.9c1.2,0.7,1.3,1.8,0,2.5l-8,4.6c-1.2,0.7-3.2,0.7-4.5,0l-8.2-4.7 | |||||
| c-1.2-0.7-1.3-1.8,0-2.5l8-4.6c1.2-0.7,3.2-0.7,4.5,0L336.6,127.9z M333.2,131l-10.2-5.8l-5.8,3.3c-0.5,0.3-0.5,0.8-0.1,1.1 | |||||
| l0.1,0.1l8.2,4.7c0.6,0.3,1.5,0.3,2,0L333.2,131z M327.9,129.6c0.5,0,0.9,0.2,0.9,0.5l0,1.8l0,0.1c-0.1,0.2-0.4,0.4-0.8,0.4l-3.2,0 | |||||
| l-0.1,0c-0.4,0-0.7-0.2-0.7-0.5l0-0.1c0.1-0.2,0.4-0.4,0.8-0.4l2.4,0l0-1.4l0-0.1C327.1,129.7,327.5,129.6,327.9,129.6z | |||||
| M325.5,128.2c0,0.2-0.3,0.4-0.7,0.5l-0.1,0l-2.4,0l0,1.4c0,0.2-0.3,0.4-0.7,0.5l-0.1,0c-0.4,0-0.8-0.2-0.9-0.4l0-0.1l0-1.8 | |||||
| c0-0.2,0.3-0.4,0.7-0.5l0.1,0l3.2,0C325.1,127.7,325.5,127.9,325.5,128.2z M335.4,128.6l-8.2-4.7c-0.6-0.3-1.5-0.3-2,0l-1,0.6 | |||||
| l10.2,5.8l1-0.6C335.9,129.5,336,129,335.4,128.6L335.4,128.6z"/> | |||||
| </g> | |||||
| <g> | |||||
| <path id="矩形备份-2_6_" class="st10" d="M434,273.2H291.8c-0.3,0-0.5,0.2-0.7,0.4c-0.2,0.3-0.3,0.6-0.3,1.1v76 | |||||
| c0,0.4,0.1,0.8,0.3,1.1c0.2,0.3,0.4,0.4,0.7,0.4H434c0.3,0,0.5-0.2,0.7-0.4c0.2-0.3,0.3-0.6,0.3-1.1v-76c0-0.4-0.1-0.8-0.3-1.1 | |||||
| C434.4,273.4,434.2,273.2,434,273.2z"/> | |||||
| <text transform="matrix(1 0 0 1 361.2133 316.8983)" class="st11 st12 st9">上传数据</text> | |||||
| <g id="编组-7_1_" transform="translate(516.000000, 64.000000)"> | |||||
| <rect id="矩形_19_" x="-217.5" y="219.8" class="st13" width="57.8" height="57.8"/> | |||||
| <g id="编组-2_1_" transform="translate(10.000000, 2.000000)"> | |||||
| <g id="智能配送_1_"> | |||||
| <g id="分组-5_1_"> | |||||
| <g id="Group-9-Copy_1_" transform="translate(0.000000, 0.431581)"> | |||||
| <g id="Group-6_1_"> | |||||
| <linearGradient id="Oval-2_1_" gradientUnits="userSpaceOnUse" x1="-873.7617" y1="659.7869" x2="-873.203" y2="659.5386" gradientTransform="matrix(43.1523 0 0 -24.5174 37494.2148 16404.498)"> | |||||
| <stop offset="0" style="stop-color:#FEFEFF"/> | |||||
| <stop offset="1" style="stop-color:#F1F6FF"/> | |||||
| </linearGradient> | |||||
| <ellipse id="Oval-2_5_" class="st28" cx="-198.4" cy="231.3" rx="19.5" ry="11.1"/> | |||||
| <linearGradient id="Combined-Shape_1_" gradientUnits="userSpaceOnUse" x1="-872.9349" y1="670.6534" x2="-873.8142" y2="670.6534" gradientTransform="matrix(43.1523 0 0 -47.9385 37494.2109 32401.2207)"> | |||||
| <stop offset="0" style="stop-color:#CBD3E0"/> | |||||
| <stop offset="0.2354" style="stop-color:#90A1BD"/> | |||||
| <stop offset="0.4664" style="stop-color:#DCE0E8"/> | |||||
| <stop offset="0.6916" style="stop-color:#CAD1DC"/> | |||||
| <stop offset="1" style="stop-color:#EBEEF2"/> | |||||
| </linearGradient> | |||||
| <path id="Combined-Shape_5_" class="st29" d="M-179,229.5L-179,229.5l0,32.7h0c-0.6,5.9-9.1,10.6-19.4,10.6 | |||||
| s-18.9-4.7-19.4-10.6h0v-32.7h0c0,0.2,0,0.4,0,0.7c0,6.2,8.7,11.3,19.5,11.3s19.5-5.1,19.5-11.3 | |||||
| C-179,229.9-179,229.7-179,229.5z"/> | |||||
| <path id="Oval-2_4_" class="st30" d="M-217.4,252.7c0,6,8.5,10.8,19,10.8s19-4.8,19-10.8"/> | |||||
| <path id="Combined-Shape_4_" class="st26" d="M-178.6,229.6h0.1v32.8h-0.1c-1.1,5.6-9.6,9.9-19.8,9.9s-18.7-4.2-19.8-9.9 | |||||
| h-0.1v-32.8h0.1c1.1-5.6,9.6-9.9,19.8-9.9S-179.7,224-178.6,229.6z"/> | |||||
| <polygon id="Rectangle_7_" class="st31" points="-214.8,253.2 -213.3,254.4 -213.3,257.3 -214.8,256.1 "/> | |||||
| <polygon id="Rectangle_6_" class="st32" points="-211.8,255.3 -210.2,256.5 -210.2,259.4 -211.8,258.2 "/> | |||||
| <path id="Oval-2_3_" class="st30" d="M-217.4,241.9c0,6,8.5,10.8,19,10.8s19-4.8,19-10.8"/> | |||||
| <polygon id="Rectangle_5_" class="st31" points="-214.8,242.3 -213.3,243.6 -213.3,246.5 -214.8,245.2 "/> | |||||
| <polygon id="Rectangle_4_" class="st32" points="-211.8,244.4 -210.2,245.7 -210.2,248.5 -211.8,247.3 "/> | |||||
| </g> | |||||
| </g> | |||||
| </g> | |||||
| </g> | |||||
| </g> | |||||
| </g> | |||||
| </g> | |||||
| <g> | |||||
| <g class="st4"> | |||||
| <path class="st5" d="M433.7,135.5h67.2c12.2,0,22.2,10,22.2,22.2V183"/> | |||||
| <g> | |||||
| <polygon class="st6" points="513.3,175 515.1,173.4 523.1,182.1 531.2,173.4 532.9,175 523.1,185.6 "/> | |||||
| </g> | |||||
| </g> | |||||
| </g> | |||||
| <g> | |||||
| <g class="st4"> | |||||
| <path class="st5" d="M433.7,314.6h67.2c12.2,0,22.2-10,22.2-22.2v-25.2"/> | |||||
| <g> | |||||
| <polygon class="st6" points="532.9,275.1 531.2,276.8 523.1,268.1 515.1,276.8 513.3,275.1 523.1,264.6 "/> | |||||
| </g> | |||||
| </g> | |||||
| </g> | |||||
| <g> | |||||
| <path id="矩形备份-2_8_" class="st10" d="M589.2,185.6H447c-0.3,0-0.5,0.2-0.7,0.4c-0.2,0.3-0.3,0.6-0.3,1.1v76 | |||||
| c0,0.4,0.1,0.8,0.3,1.1c0.2,0.3,0.4,0.4,0.7,0.4h142.2c0.3,0,0.5-0.2,0.7-0.4c0.2-0.3,0.3-0.6,0.3-1.1v-76c0-0.4-0.1-0.8-0.3-1.1 | |||||
| C589.7,185.7,589.4,185.6,589.2,185.6z"/> | |||||
| <text transform="matrix(1 0 0 1 523.1293 229.2355)" class="st11 st12 st9">创建任务</text> | |||||
| <g id="电脑_4_" transform="translate(33.000000, 32.000000) scale(-1, 1) translate(-33.000000, -32.000000) translate(1.000000, 0.000000)"> | |||||
| <g> | |||||
| <rect id="矩形_26_" x="-453.5" y="256.9" class="st13" width="64" height="-64"/> | |||||
| <g id="电脑复制_2_" transform="translate(11.000000, 2.000000)"> | |||||
| <g id="编组_6_" transform="translate(5.371982, 40.317507)"> | |||||
| <polygon id="矩形_25_" class="st14" points="-440.4,209.2 -422.5,198.3 -422.5,201.1 -440.4,212 "/> | |||||
| <polygon id="矩形_20_" class="st15" points="-431.8,192.9 -422.5,198.3 -440.4,209.2 -450,203.5 "/> | |||||
| <polygon id="矩形_13_" class="st16" points="-453,201.8 -440.4,209.2 -440.4,212.1 -453,204.7 "/> | |||||
| </g> | |||||
| <g id="电脑-2_2_"> | |||||
| <g id="电脑_5_"> | |||||
| <g id="Group-616_2_" transform="translate(2.559524, 37.948718)"> | |||||
| <g id="编组_5_" transform="translate(6.786976, 7.749090)"> | |||||
| <path id="形状结合_6_" class="st17" d="M-444.4,203.8l17.9-10.9 M-444.4,203.8v2.6 M-444.4,203.8l-8.7-5.1"/> | |||||
| </g> | |||||
| <polygon id="路径-6_2_" class="st18" points="-437.6,214.5 -453.1,205.2 -432.3,193.3 -419.7,200.5 -419.7,203.6 | |||||
| "/> | |||||
| </g> | |||||
| <g id="Group-616-Copy_2_" transform="translate(16.380952, 37.948718)"> | |||||
| <polygon id="Fill-610_2_" class="st16" points="-451.6,198.9 -451.6,206.7 -453.1,205.8 -453.1,198 "/> | |||||
| <polygon id="Fill-612_5_" class="st19" points="-451.6,198.9 -441,192.9 -441,200.5 -451.6,206.7 "/> | |||||
| <polyline id="Path-3_2_" class="st18" points="-453.1,201.4 -453.1,205.8 -451.6,206.7 -441,200.5 -441,194.4 -451.6,200.7 | |||||
| -451.6,206.7 "/> | |||||
| </g> | |||||
| <g id="Group-2_2_"> | |||||
| <path id="Fill-8_3_" class="st20" d="M-411.9,194.8c0.1,0,0.1,0,0.2-0.1c0,0,0.1,0,0.1,0c0,0,0.1,0,0.1,0c0,0,0.1,0,0.1,0 | |||||
| c0,0,0,0,0.1,0c0,0,0.1,0,0.1,0c0,0,0,0,0,0c0.1,0,0.1,0,0.2,0c0,0,0,0,0,0c0,0,0.1,0,0.1,0c0,0,0,0,0,0c0,0,0.1,0,0.1,0.1 | |||||
| l-2.7-1.6c0,0,0,0,0,0c0,0-0.1,0-0.1-0.1c0,0,0,0,0,0c0,0,0,0,0,0c0,0,0,0-0.1,0c0,0,0,0-0.1,0c0,0,0,0,0,0c0,0,0,0,0,0 | |||||
| c0,0-0.1,0-0.1,0c0,0,0,0,0,0c0,0,0,0,0,0c0,0-0.1,0-0.1,0c0,0,0,0,0,0c0,0,0,0-0.1,0c0,0,0,0-0.1,0c0,0,0,0-0.1,0 | |||||
| c0,0-0.1,0-0.1,0c0,0,0,0,0,0c0,0,0,0,0,0c0,0-0.1,0-0.2,0.1c0,0,0,0-0.1,0c0,0,0,0,0,0c-0.1,0-0.2,0.1-0.3,0.1l-36.2,21.1 | |||||
| c-0.1,0.1-0.2,0.1-0.3,0.2c0,0,0,0-0.1,0c-0.1,0.1-0.2,0.2-0.3,0.3c0,0,0,0,0,0c0,0,0,0,0,0c0,0-0.1,0.1-0.1,0.2c0,0,0,0,0,0 | |||||
| c0,0,0,0,0,0c0,0-0.1,0.1-0.1,0.1c0,0,0,0-0.1,0.1c0,0,0,0,0,0.1c0,0,0,0.1-0.1,0.1c0,0,0,0,0,0.1c0,0,0,0.1-0.1,0.1 | |||||
| c0,0,0,0,0,0.1c0,0,0,0,0,0c0,0.1-0.1,0.1-0.1,0.2c0,0,0,0,0,0c0,0,0,0,0,0c0,0,0,0.1-0.1,0.1c0,0,0,0,0,0.1c0,0,0,0,0,0.1 | |||||
| c0,0,0,0,0,0.1c0,0.1,0,0.1-0.1,0.2c0,0,0,0,0,0c0,0,0,0,0,0c0,0.1-0.1,0.1-0.1,0.2c0,0,0,0,0,0c0,0,0,0,0,0.1 | |||||
| c0,0,0,0.1,0,0.1c0,0,0,0.1,0,0.1c0,0,0,0.1,0,0.1c0,0,0,0,0,0.1c0,0,0,0.1,0,0.1c0,0,0,0.1,0,0.1c0,0,0,0,0,0 | |||||
| c0,0,0,0.1,0,0.1c0,0.1,0,0.1,0,0.2c0,0,0,0,0,0c0,0,0,0,0,0c0,0.1,0,0.3,0,0.4l0.1,26.3c0,0.7,0.2,1.2,0.6,1.4l2.7,1.6 | |||||
| c-0.4-0.2-0.6-0.7-0.6-1.4l-0.1-26.3c0-0.1,0-0.3,0-0.4c0,0,0-0.1,0-0.1c0-0.1,0-0.1,0-0.2c0,0,0-0.1,0-0.1c0,0,0-0.1,0-0.1 | |||||
| c0-0.1,0-0.1,0-0.2c0,0,0-0.1,0-0.1c0-0.1,0-0.1,0.1-0.2c0,0,0,0,0-0.1c0-0.1,0.1-0.2,0.1-0.2c0,0,0,0,0,0 | |||||
| c0-0.1,0.1-0.1,0.1-0.2c0,0,0,0,0-0.1c0-0.1,0.1-0.1,0.1-0.2c0,0,0,0,0,0c0-0.1,0.1-0.1,0.1-0.2c0,0,0,0,0-0.1 | |||||
| c0-0.1,0.1-0.1,0.1-0.2c0,0,0-0.1,0.1-0.1c0,0,0.1-0.1,0.1-0.1c0,0,0.1-0.1,0.1-0.1c0,0,0.1-0.1,0.1-0.1 | |||||
| c0-0.1,0.1-0.1,0.1-0.2c0,0,0,0,0.1-0.1c0.1-0.1,0.2-0.2,0.3-0.3c0,0,0,0,0.1,0c0.1-0.1,0.2-0.2,0.3-0.2l36.2-21.1 | |||||
| C-412.2,194.9-412.1,194.9-411.9,194.8C-412,194.9-412,194.8-411.9,194.8"/> | |||||
| <path id="Fill-6_4_" class="st21" d="M-410.6,196.6c0-0.8-0.3-1.3-0.8-1.6c-0.2-0.1-0.5-0.2-0.8-0.2c-0.3,0-0.6,0.1-0.9,0.3 | |||||
| l-35.8,21.1c-1.3,0.7-2.3,2.5-2.3,4l0.1,25.5c0,0.8,0.3,1.3,0.8,1.6c0.2,0.1,0.5,0.2,0.8,0.2c0.3,0,0.6-0.1,0.9-0.3 | |||||
| l35.8-20.7c1.3-0.7,2.3-2.5,2.3-4L-410.6,196.6z"/> | |||||
| <linearGradient id="Fill-612_6_" gradientUnits="userSpaceOnUse" x1="398.5316" y1="739.7098" x2="398.146" y2="739.0134" gradientTransform="matrix(-35.3958 0 0 -45.873 13684.2344 34133.2852)"> | |||||
| <stop offset="0" style="stop-color:#FEFEFF"/> | |||||
| <stop offset="1" style="stop-color:#F1F6FF"/> | |||||
| </linearGradient> | |||||
| <polygon id="Fill-612_4_" class="st33" points="-448.4,218.7 -413.1,198.1 -413.3,223.3 -448.5,243.9 "/> | |||||
| <path id="Combined-Shape_6_" class="st18" d="M-414,193.1L-414,193.1c0.1,0,0.1,0,0.3,0c0,0,0,0,0.2,0.1c0,0,0.1,0,0.1,0.1 | |||||
| l0,0l1.8,1.5c0.4,0.2,0.7,0.7,0.7,1.4l0.1,26.3c0,1.4-1,3-2.1,3.7l-36.2,21.1c-0.6,0.4-1.2,0.4-1.6,0.1l0,0l-1.8-1.5 | |||||
| c-0.4-0.2-0.6-0.6-0.6-1.2l0-0.2l-0.1-26.3c0-0.1,0-0.3,0-0.5c0-0.1,0-0.1,0.1-0.3c0,0,0-0.1,0.1-0.3c0,0,0-0.1,0-0.2 | |||||
| c0,0,0-0.1,0.1-0.2c0-0.1,0.1-0.1,0.1-0.2c0-0.1,0-0.1,0.1-0.2c0,0,0,0,0.1-0.2c0,0,0-0.1,0.1-0.2c0-0.1,0.1-0.1,0.1-0.2 | |||||
| c0,0,0,0,0,0l0.1-0.1c0,0,0,0,0.1-0.1c0,0,0,0,0.1-0.1c0,0,0.1-0.1,0.2-0.2c0-0.1,0.1-0.1,0.2-0.2c0.1-0.1,0.2-0.2,0.4-0.3 | |||||
| c0.1-0.1,0.2-0.2,0.3-0.2l0,0l36.2-21.1c0.1-0.1,0.2-0.1,0.4-0.2c0.1,0,0.1,0,0.2-0.1c0,0,0.1,0,0.1,0 | |||||
| C-414.2,193.1-414.2,193.1-414,193.1C-414,193.1-414,193.1-414,193.1L-414,193.1z"/> | |||||
| </g> | |||||
| </g> | |||||
| </g> | |||||
| </g> | |||||
| </g> | |||||
| </g> | |||||
| </g> | |||||
| <g> | |||||
| <path id="矩形备份-2_9_" class="st34" d="M790.4,185.6H648.3c-0.3,0-0.5,0.2-0.7,0.4c-0.2,0.3-0.3,0.6-0.3,1.1v76 | |||||
| c0,0.4,0.1,0.8,0.3,1.1c0.2,0.3,0.4,0.4,0.7,0.4h142.2c0.3,0,0.5-0.2,0.7-0.4c0.2-0.3,0.3-0.6,0.3-1.1v-76c0-0.4-0.1-0.8-0.3-1.1 | |||||
| C790.9,185.7,790.7,185.6,790.4,185.6z"/> | |||||
| <text transform="matrix(1 0 0 1 724.3945 229.2355)" class="st11 st12 st9">调试环境</text> | |||||
| <g id="云竖_2_" transform="translate(516.000000, 320.000000)"> | |||||
| <g> | |||||
| <rect id="矩形_21_" x="147.6" y="-121" class="st13" width="48.8" height="48.8"/> | |||||
| <g id="编组-6_2_" transform="translate(2.000000, 6.000000)"> | |||||
| <path id="Path-15_5_" class="st35" d="M168.1-83.8c1.7,0.9,3.7,2.1,6.2,0.5c2.4-1.6,15.5-8.8,16.9-9.7c1.9-0.9,3.6-8.5-4.3-15.5 | |||||
| c-0.4-5-6.8-16.2-14-13.6c-2,1.1-7.3,4.3-16.1,9.3c-0.7,0.4-1.3,0.7-1.8,1c-0.2,0.1-0.8,0.6-1.2,1.2c-0.5,0.4-1.7,1.1-3.5,2.3 | |||||
| c-2,0.8-2.9,2.2-2.9,4.4c0,3.5,1.5,7.7,5.5,10.8C156.8-90.4,166.4-84.7,168.1-83.8z"/> | |||||
| <linearGradient id="Fill-1_3_" gradientUnits="userSpaceOnUse" x1="-850.8792" y1="407.687" x2="-851.0427" y2="407.7502" gradientTransform="matrix(27.8283 0 0 -13.8442 23834.3965 5530.2881)"> | |||||
| <stop offset="0" style="stop-color:#B2B7BF"/> | |||||
| <stop offset="0.1064" style="stop-color:#E2EBFD"/> | |||||
| <stop offset="0.2734" style="stop-color:#F8FAFF"/> | |||||
| <stop offset="0.4104" style="stop-color:#D8E0EE"/> | |||||
| <stop offset="1" style="stop-color:#F1F6FF"/> | |||||
| </linearGradient> | |||||
| <path id="Fill-1_2_" class="st36" d="M151-108.5c0.3,0,0.7,0,1,0.1c0,0,0,0,0,0c0.4,0.1,0.7,0.2,1.1,0.4l17.2-10 | |||||
| c-0.1,0-0.2-0.1-0.2-0.1c-0.1,0-0.2-0.1-0.3-0.1c-0.1,0-0.2-0.1-0.3-0.1c-0.1,0-0.2-0.1-0.3-0.1c0,0,0,0-0.1,0c0,0,0,0,0,0 | |||||
| c-0.1,0-0.1,0-0.2,0c-0.1,0-0.2,0-0.3,0c-0.1,0-0.2,0-0.3,0c-0.1,0-0.2,0-0.3,0c0,0,0,0,0,0c0,0,0,0,0,0c-0.1,0-0.2,0-0.4,0 | |||||
| c-0.1,0-0.3,0-0.4,0.1c0,0-0.1,0-0.1,0c0,0-0.1,0-0.1,0c-0.1,0-0.2,0-0.2,0.1c-0.2,0.1-0.4,0.2-0.6,0.3l-17.2,10 | |||||
| c0.2-0.1,0.5-0.2,0.8-0.3c0,0,0.1,0,0.1,0C150.3-108.4,150.6-108.5,151-108.5C151-108.5,151-108.5,151-108.5z"/> | |||||
| <linearGradient id="Fill-3_3_" gradientUnits="userSpaceOnUse" x1="-852.3721" y1="416.4146" x2="-852.6138" y2="416.8685" gradientTransform="matrix(30.367 0 0 -33.6775 26067.5156 13933.0166)"> | |||||
| <stop offset="0" style="stop-color:#C0CBDC"/> | |||||
| <stop offset="1.654118e-02" style="stop-color:#B3C0D4"/> | |||||
| <stop offset="0.1143" style="stop-color:#A9B8D1"/> | |||||
| <stop offset="0.1737" style="stop-color:#BEC9DB"/> | |||||
| <stop offset="0.3293" style="stop-color:#E0E5F0"/> | |||||
| <stop offset="0.5383" style="stop-color:#D9DEE6"/> | |||||
| <stop offset="0.5471" style="stop-color:#D6DBE4"/> | |||||
| <stop offset="0.6916" style="stop-color:#CAD1DC"/> | |||||
| <stop offset="1" style="stop-color:#EBEEF2"/> | |||||
| </linearGradient> | |||||
| <path id="Fill-3_2_" class="st37" d="M192.9-97.7c0-0.1,0-0.2,0-0.3c0-0.1,0-0.2,0-0.3c0-0.1,0-0.1,0-0.2c0,0,0,0,0,0 | |||||
| c0,0,0-0.1,0-0.1c0-0.1,0-0.2-0.1-0.3c0-0.1,0-0.2-0.1-0.4c0-0.1-0.1-0.2-0.1-0.4c0-0.1-0.1-0.2-0.1-0.4c0,0,0,0,0,0 | |||||
| c0,0,0,0,0,0c0-0.1-0.1-0.2-0.1-0.3c0-0.1-0.1-0.2-0.1-0.4c0-0.1-0.1-0.2-0.1-0.3c0-0.1-0.1-0.2-0.1-0.3c0-0.1-0.1-0.1-0.1-0.2 | |||||
| c0,0,0,0,0,0l0-0.1c0-0.1-0.1-0.2-0.1-0.3c0-0.1-0.1-0.2-0.2-0.3c-0.1-0.1-0.1-0.2-0.2-0.4c-0.1-0.1-0.1-0.3-0.2-0.4 | |||||
| c0,0,0,0,0,0c0,0,0,0,0,0c-0.1-0.2-0.2-0.4-0.3-0.5c-0.2-0.3-0.4-0.6-0.5-0.9c0,0,0,0,0,0l0,0c-0.1-0.2-0.2-0.4-0.4-0.5 | |||||
| c-0.1-0.1-0.2-0.3-0.3-0.4c-0.1-0.1-0.2-0.2-0.3-0.3c0,0,0,0-0.1-0.1c0,0,0,0,0,0c-0.1-0.1-0.1-0.1-0.2-0.2 | |||||
| c-0.1-0.1-0.2-0.2-0.3-0.3c-0.1-0.1-0.2-0.2-0.3-0.3c-0.1-0.1-0.2-0.2-0.3-0.3c0,0-0.1-0.1-0.1-0.1c0,0,0,0,0,0 | |||||
| c-0.1-0.1-0.1-0.1-0.2-0.2c-0.1-0.1-0.2-0.2-0.3-0.3c-0.1-0.1-0.2-0.2-0.3-0.2c-0.1-0.1-0.2-0.2-0.3-0.2c0,0-0.1-0.1-0.1-0.1 | |||||
| l-17.2,10c0.4,0.3,0.8,0.6,1.2,1c0,0,0,0,0,0c0.4,0.4,0.8,0.8,1.1,1.2c0,0,0,0,0,0c0.3,0.4,0.7,0.9,1,1.3c0,0,0,0,0,0 | |||||
| c0.3,0.5,0.6,0.9,0.9,1.4c0,0,0,0,0,0c0.3,0.5,0.5,1,0.7,1.5c0,0,0,0,0,0c0.2,0.5,0.4,1,0.5,1.6c0,0,0,0,0,0 | |||||
| c0.1,0.5,0.3,1,0.3,1.6c0,0,0,0,0,0c0.1,0.5,0.1,1,0.1,1.5c0,0.3,0,0.5,0,0.7c0,0,0,0,0,0.1c0,0.2-0.1,0.4-0.1,0.6 | |||||
| c0,0,0,0.1,0,0.1c0,0.2-0.1,0.4-0.1,0.6c0,0,0,0.1,0,0.1c-0.1,0.2-0.1,0.3-0.2,0.5c0,0,0,0,0,0c-0.1,0.2-0.2,0.3-0.3,0.5 | |||||
| c-0.1,0.2-0.3,0.4-0.5,0.6c0,0-0.1,0.1-0.1,0.1c-0.2,0.2-0.4,0.3-0.6,0.4l17.2-10c0.2-0.1,0.4-0.3,0.6-0.4c0,0,0.1-0.1,0.1-0.1 | |||||
| c0.2-0.2,0.3-0.4,0.5-0.6c0,0,0,0,0,0c0.1-0.1,0.2-0.3,0.3-0.5c0,0,0,0,0,0c0,0,0,0,0,0c0-0.1,0.1-0.2,0.1-0.3 | |||||
| c0-0.1,0-0.1,0.1-0.2c0,0,0-0.1,0-0.1c0,0,0-0.1,0-0.1c0-0.1,0.1-0.2,0.1-0.3c0,0,0-0.1,0-0.1c0,0,0-0.1,0-0.1c0,0,0-0.1,0-0.1 | |||||
| c0-0.1,0-0.2,0-0.3c0-0.1,0-0.1,0-0.2c0,0,0,0,0-0.1c0,0,0-0.1,0-0.1c0-0.1,0-0.2,0-0.3c0-0.1,0-0.2,0-0.3c0,0,0,0,0,0 | |||||
| c0-0.1,0-0.2,0-0.3C192.9-97.5,192.9-97.6,192.9-97.7z"/> | |||||
| <linearGradient id="Fill-8_1_" gradientUnits="userSpaceOnUse" x1="-856.3117" y1="415.72" x2="-856.7656" y2="416.3181" gradientTransform="matrix(41.218 0 0 -31.5976 35478.3477 13034.8008)"> | |||||
| <stop offset="0" style="stop-color:#CBD3E0"/> | |||||
| <stop offset="0.2302" style="stop-color:#D7DCE6"/> | |||||
| <stop offset="0.3076" style="stop-color:#C2CBDA"/> | |||||
| <stop offset="0.4132" style="stop-color:#DCE0E8"/> | |||||
| <stop offset="0.5076" style="stop-color:#EBEDF1"/> | |||||
| <stop offset="0.5317" style="stop-color:#F2F3F6"/> | |||||
| <stop offset="0.6002" style="stop-color:#FDFBFB"/> | |||||
| <stop offset="0.6687" style="stop-color:#F8F9FA"/> | |||||
| <stop offset="0.7321" style="stop-color:#D6DBE1"/> | |||||
| <stop offset="1" style="stop-color:#EBEEF2"/> | |||||
| </linearGradient> | |||||
| <path id="Fill-8_5_" class="st38" d="M163.7-109.7C163.7-109.7,163.7-109.7,163.7-109.7c0.2,0.2,0.5,0.5,0.7,0.8c0,0,0,0,0,0 | |||||
| c0.2,0.2,0.4,0.5,0.6,0.7c0,0,0,0,0,0c0.2,0.2,0.4,0.5,0.6,0.7c0,0,0,0,0,0c0.2,0.2,0.3,0.4,0.5,0.7c0.1,0.1,0.2,0.2,0.2,0.3 | |||||
| c0.1,0.1,0.2,0.3,0.3,0.4c0.2,0.2,0.3,0.5,0.5,0.7c0.1,0.1,0.1,0.2,0.2,0.3c0,0.1,0.1,0.2,0.1,0.2c0.1,0.2,0.2,0.5,0.4,0.7 | |||||
| c0,0,0,0.1,0,0.1c0.1,0.3,0.3,0.6,0.4,0.9c0,0,0,0,0,0c0.1,0.3,0.3,0.6,0.4,0.9c0,0,0,0,0,0.1c0.1,0.3,0.2,0.6,0.3,0.9l0,0.1 | |||||
| c0.1,0.3,0.2,0.6,0.2,0.8c0,0,0,0.1,0,0.1c0.1,0.3,0.1,0.6,0.2,0.9c0,0,0,0.1,0,0.1c0.1,0.3,0.1,0.6,0.1,0.9l17.2-10 | |||||
| c0-0.1,0-0.3-0.1-0.4c0-0.1,0-0.3-0.1-0.4c0,0,0-0.1,0-0.1c0,0,0-0.1,0-0.1c0-0.1,0-0.2-0.1-0.3c0-0.1-0.1-0.3-0.1-0.4 | |||||
| c0,0,0-0.1,0-0.1c0,0,0-0.1,0-0.1c0-0.1,0-0.1-0.1-0.2c0-0.1-0.1-0.3-0.1-0.4c0-0.1,0-0.1-0.1-0.2c0,0,0-0.1,0-0.1 | |||||
| c0-0.1,0-0.1-0.1-0.2c0-0.1-0.1-0.3-0.1-0.4c0-0.1-0.1-0.2-0.1-0.3c0,0,0,0,0-0.1c0,0,0-0.1,0-0.1c-0.1-0.1-0.1-0.3-0.2-0.4 | |||||
| c-0.1-0.1-0.1-0.3-0.2-0.4c0,0,0,0,0,0c0,0,0,0,0,0c-0.1-0.1-0.1-0.2-0.2-0.4c-0.1-0.1-0.1-0.3-0.2-0.4c0,0,0,0,0-0.1 | |||||
| c0,0,0-0.1,0-0.1c-0.1-0.1-0.1-0.2-0.2-0.3c-0.1-0.1-0.1-0.2-0.2-0.4c0-0.1-0.1-0.2-0.1-0.2c0,0,0-0.1-0.1-0.1 | |||||
| c0-0.1-0.1-0.1-0.1-0.2c-0.2-0.3-0.3-0.5-0.5-0.7c0-0.1-0.1-0.1-0.1-0.2c-0.1-0.1-0.1-0.2-0.2-0.3c-0.1-0.1-0.2-0.2-0.2-0.3 | |||||
| c0-0.1-0.1-0.1-0.1-0.2c-0.1-0.2-0.2-0.3-0.4-0.5c0,0,0,0,0,0c0,0,0,0,0,0c-0.1-0.1-0.2-0.2-0.3-0.3c-0.1-0.1-0.2-0.3-0.3-0.4 | |||||
| c0,0,0,0,0,0c0,0,0,0,0,0c-0.1-0.1-0.2-0.2-0.3-0.3c-0.1-0.1-0.2-0.2-0.3-0.4l0,0c0,0,0,0,0,0c-0.1-0.1-0.2-0.2-0.3-0.3 | |||||
| c-0.1-0.1-0.2-0.2-0.4-0.3c0,0,0,0,0,0l0,0c-0.1-0.1-0.2-0.2-0.4-0.3c-0.1-0.1-0.2-0.2-0.4-0.3c0,0,0,0,0,0 | |||||
| c-0.1-0.1-0.2-0.2-0.4-0.3c-0.1-0.1-0.2-0.2-0.4-0.3c0,0,0,0,0,0l0,0c-0.1-0.1-0.2-0.1-0.3-0.2c-0.1-0.1-0.2-0.1-0.4-0.2 | |||||
| c0,0-0.1,0-0.1,0c-0.1-0.1-0.2-0.1-0.3-0.1c-0.1-0.1-0.2-0.1-0.3-0.2c-0.1,0-0.1-0.1-0.2-0.1c0,0,0,0-0.1,0c0,0,0,0-0.1,0 | |||||
| c-0.1-0.1-0.2-0.1-0.3-0.1c-0.1,0-0.2-0.1-0.3-0.1c0,0,0,0-0.1,0c0,0,0,0-0.1,0c-0.1,0-0.1-0.1-0.2-0.1c-0.1,0-0.2-0.1-0.3-0.1 | |||||
| c-0.1,0-0.1,0-0.2,0c0,0-0.1,0-0.1,0c0,0-0.1,0-0.1,0c-0.1,0-0.2,0-0.4-0.1c-0.1,0-0.2,0-0.2,0c0,0-0.1,0-0.1,0c0,0,0,0-0.1,0 | |||||
| c-0.1,0-0.3,0-0.4,0c-0.1,0-0.1,0-0.2,0c0,0-0.1,0-0.1,0c0,0-0.1,0-0.1,0c-0.2,0-0.3,0-0.5,0.1c0,0,0,0,0,0c0,0-0.1,0-0.1,0 | |||||
| c-0.2,0-0.3,0.1-0.4,0.1c0,0,0,0,0,0c-0.2,0.1-0.4,0.2-0.6,0.3l-17.2,9.9c0.2-0.1,0.4-0.2,0.6-0.3c0.2-0.1,0.3-0.1,0.5-0.1 | |||||
| c0,0,0.1,0,0.1,0c0.2,0,0.4-0.1,0.6-0.1c0,0,0.1,0,0.1,0c0.2,0,0.4,0,0.6,0c0,0,0.1,0,0.1,0c0.2,0,0.5,0.1,0.7,0.1 | |||||
| c0,0,0.1,0,0.1,0c0.2,0.1,0.5,0.1,0.7,0.2c0,0,0,0,0.1,0c0.3,0.1,0.5,0.2,0.8,0.3c0,0,0,0,0.1,0c0.3,0.1,0.6,0.3,0.8,0.4 | |||||
| c0.3,0.1,0.5,0.3,0.8,0.5c0,0,0,0,0,0c0.3,0.2,0.5,0.4,0.7,0.6C163.2-110.1,163.4-109.9,163.7-109.7z"/> | |||||
| <linearGradient id="Fill-5_1_" gradientUnits="userSpaceOnUse" x1="-855.4323" y1="417.6272" x2="-855.1285" y2="417.117" gradientTransform="matrix(37.419 0 0 -39.8938 32166.1191 16556.9258)"> | |||||
| <stop offset="0" style="stop-color:#FCFDFF"/> | |||||
| <stop offset="1" style="stop-color:#EFF1F6"/> | |||||
| </linearGradient> | |||||
| <path id="Fill-5_5_" class="st39" d="M169.7-98.3c3.4,2.4,6,7.3,6,11.3c0,4.3-3.1,6.1-6.8,3.9l-15-8.7 | |||||
| c-3.8-2.2-6.8-7.5-6.8-11.8c0-4,2.6-5.8,6-4.3c0.7-4.2,2.9-6.2,8.4-3.4C166.2-108.3,169.1-103.3,169.7-98.3z"/> | |||||
| <path id="Fill-5_4_" class="st17" d="M164.4-117.4c1.6-1.1,4-0.9,6.6,0.6c4.2,2.4,7.6,8,8.3,12.9c3.4,2.4,6,7.3,6,11.3 | |||||
| c0,2.1-0.6,3.6-1.8,4.3"/> | |||||
| <path id="Path-15_4_" class="st40" d="M172.7-122.3c-2,1.1-7.3,4.2-16.1,9.3c-0.8,0.4-1.4,0.7-1.8,1.1c-0.2,0.1-0.8,0.6-1.3,1.3 | |||||
| c-0.5,0.4-1.7,1.1-3.4,2.2c-1,0.4-1.8,1-2.3,1.8c-0.5,0.8-0.8,1.8-0.8,2.9c0,3.6,1.6,7.9,5.6,11.2c4,2.6,13.6,8.3,15.5,9.3 | |||||
| c1,0.6,2.2,1.2,3.4,1.3c0.9,0.1,1.9-0.1,3-0.9c1.5-1,6.8-3.9,11.1-6.4c2.8-1.6,5.2-2.9,5.8-3.3c0.7-0.3,1.4-1.5,1.7-3.2 | |||||
| c0.2-1.3,0.2-2.9-0.3-4.6c-0.7-2.5-2.3-5.4-5.4-8.2c-0.3-3-2.6-7.9-5.9-11.1c-1.3-1.3-2.8-2.2-4.3-2.7 | |||||
| C175.7-122.9,174.3-122.9,172.7-122.3z"/> | |||||
| </g> | |||||
| </g> | |||||
| </g> | |||||
| </g> | |||||
| <g> | |||||
| <g class="st4"> | |||||
| <line class="st5" x1="590.1" y1="226" x2="644.7" y2="226"/> | |||||
| <g> | |||||
| <polygon class="st6" points="636.8,235.8 635.1,234 643.8,226 635.1,217.9 636.8,216.2 647.3,226 "/> | |||||
| </g> | |||||
| </g> | |||||
| </g> | |||||
| <text transform="matrix(1 0 0 1 603.4565 209.8904)" class="st7 st8 st9">推送</text> | |||||
| <g> | |||||
| <path id="矩形备份-2_11_" class="st10" d="M978.3,185.7H849.4c-0.2,0-0.4,0.2-0.6,0.4c-0.2,0.3-0.2,0.6-0.2,1.1v76 | |||||
| c0,0.4,0.1,0.8,0.2,1.1c0.2,0.3,0.4,0.4,0.6,0.4h128.9c0.2,0,0.4-0.2,0.6-0.4c0.2-0.3,0.2-0.6,0.2-1.1v-76c0-0.4-0.1-0.8-0.2-1.1 | |||||
| C978.7,185.8,978.5,185.7,978.3,185.7z"/> | |||||
| <text transform="matrix(1 0 0 1 925.62 229.3147)" class="st11 st12 st9">模型库</text> | |||||
| <g> | |||||
| <g id="database_3_"> | |||||
| <g> | |||||
| <rect id="矩形_22_" x="859.9" y="198.5" class="st13" width="55.8" height="55.8"/> | |||||
| <g transform="translate(2.000000, 8.000000)"> | |||||
| <linearGradient id="路径-25_1_" gradientUnits="userSpaceOnUse" x1="-340.618" y1="731.4043" x2="-341.5138" y2="731.4182" gradientTransform="matrix(60.476 0 0 -36.6097 21513.0371 27000.8066)"> | |||||
| <stop offset="0" style="stop-color:#CBD3E0"/> | |||||
| <stop offset="9.337495e-02" style="stop-color:#ACB8CD"/> | |||||
| <stop offset="0.1911" style="stop-color:#97A7C1"/> | |||||
| <stop offset="0.3147" style="stop-color:#AAB4C4"/> | |||||
| <stop offset="0.3631" style="stop-color:#BBC4D5"/> | |||||
| <stop offset="0.3762" style="stop-color:#C2CBD9"/> | |||||
| <stop offset="0.4187" style="stop-color:#E2E5EC"/> | |||||
| <stop offset="0.6689" style="stop-color:#DBDFE7"/> | |||||
| <stop offset="0.7262" style="stop-color:#D8DDE5"/> | |||||
| <stop offset="0.8284" style="stop-color:#CDD4DE"/> | |||||
| <stop offset="0.8558" style="stop-color:#D3D9E3"/> | |||||
| <stop offset="0.8813" style="stop-color:#F6F6F7"/> | |||||
| <stop offset="0.9502" style="stop-color:#DBE0E8"/> | |||||
| <stop offset="1" style="stop-color:#EBEEF2"/> | |||||
| </linearGradient> | |||||
| <polygon id="路径-25_3_" class="st41" points="910.6,214 904.4,218.9 894.8,224.7 890.9,225.8 869.8,222.5 865.9,217.8 | |||||
| 863.5,211.3 861.4,208 860,209.4 859.6,213.7 859.6,220.1 865.9,233.5 867.2,235.4 868.8,236.2 892.8,239.9 911.3,229.1 | |||||
| 912.2,226.9 912.4,217.1 "/> | |||||
| <polygon id="Fill-6_9_" class="st42" points="889.1,235.5 889.1,237.6 887.3,237.4 887.3,235.3 "/> | |||||
| <polygon id="Fill-6-Copy_7_" class="st43" points="886.1,235.1 886.1,237.2 884.3,236.9 884.3,234.8 "/> | |||||
| <polygon id="Fill-6-Copy-2_7_" class="st42" points="883.1,234.6 883.1,236.7 881.3,236.5 881.3,234.4 "/> | |||||
| <path id="路径-26_3_" class="st44" d="M859.6,215.3l6.4,12.9c0.4,0.5,1.2,1,2.4,1.4s8.7,1.8,22.3,4c1.4,0.2,2.6,0,3.8-0.4 | |||||
| c1.3-0.5,3.2-1.6,4.7-2.5c3.4-2.1,7.8-4.8,13.2-8.2"/> | |||||
| <linearGradient id="路径-13_1_" gradientUnits="userSpaceOnUse" x1="-340.6088" y1="730.8391" x2="-340.151" y2="730.7928" gradientTransform="matrix(57.2286 0 0 -34.5361 20368.2871 25452.4648)"> | |||||
| <stop offset="0" style="stop-color:#FEFEFF"/> | |||||
| <stop offset="1" style="stop-color:#F1F6FF"/> | |||||
| </linearGradient> | |||||
| <path id="路径-13_7_" class="st45" d="M877.6,198.3l-14.4,8.4c-2,1.2-2.7,3.7-1.7,5.7l4.8,9.6c0.6,1.3,1.8,2.1,3.2,2.3 | |||||
| l22,3.4c1,0.2,2,0,2.9-0.6l14.4-8.5c1.9-1.1,2.7-3.5,1.8-5.6l-4.3-9.4c-0.6-1.3-1.8-2.3-3.3-2.5l-22.5-3.6 | |||||
| C879.5,197.6,878.5,197.8,877.6,198.3z"/> | |||||
| <path id="路径-13_6_" class="st40" d="M860.1,221.2l5.9,12.6c0.6,1.3,1.8,2.2,3.3,2.5l22.3,3.5c1,0.2,2,0,2.9-0.5l15.8-9.3 | |||||
| c1.3-0.8,2.2-2.2,2.2-3.8v-8c0-0.6-0.1-1.3-0.4-1.8l-5.7-12.4c-0.6-1.3-1.8-2.3-3.3-2.5l-22.5-3.5c-1-0.2-2,0-2.9,0.5 | |||||
| l-15.8,9.2c-1.3,0.8-2.2,2.2-2.2,3.8v8.1C859.6,219.9,859.8,220.6,860.1,221.2z"/> | |||||
| </g> | |||||
| </g> | |||||
| <polygon id="Fill-6_8_" class="st42" points="911.6,234 911.6,236.1 909.8,237.1 909.8,235.1 "/> | |||||
| <polygon id="Fill-6-Copy_6_" class="st46" points="908.6,235.8 908.6,237.8 906.8,238.9 906.8,236.8 "/> | |||||
| <polygon id="Fill-6-Copy-2_6_" class="st47" points="905.6,237.5 905.6,239.6 903.8,240.7 903.8,238.6 "/> | |||||
| </g> | |||||
| <g id="形状结合-2_3_" transform="translate(17.000000, 18.000000)"> | |||||
| <linearGradient id="形状结合_3_" gradientUnits="userSpaceOnUse" x1="-342.2407" y1="708.4328" x2="-341.5711" y2="708.1635" gradientTransform="matrix(27 0 0 -15 10101 10826)"> | |||||
| <stop offset="0" style="stop-color:#828BB3"/> | |||||
| <stop offset="1" style="stop-color:#555A6F"/> | |||||
| </linearGradient> | |||||
| <path id="形状结合_9_" class="st48" d="M863.9,199.4c1.4,0.8,1.4,2.1,0,3c-0.3,0.2-0.5,0.3-0.9,0.4c0.2,0.9,1,1.8,2.1,2.4 | |||||
| c0.4,0.2,0.9,0.4,1.3,0.6c0.5,0.2,0.7,0.6,0.3,0.9c-0.3,0.3-1,0.4-1.5,0.2c-0.6-0.2-1.2-0.5-1.7-0.8c-1.5-0.8-2.4-1.9-2.7-3.1 | |||||
| c-0.7,0-1.4-0.2-1.9-0.5l-0.2-0.1c-1.4-0.8-1.4-2.1,0-3c1.4-0.8,3.5-0.9,4.9-0.1L863.9,199.4z M880.3,202 | |||||
| c-0.1,1.4-1.1,2.8-2.8,3.8c-0.4,0.3-0.9,0.5-1.4,0.7c0.4,0.7,0.1,1.5-0.9,2.1c-1.4,0.8-3.5,0.9-4.9,0.1l-0.2-0.1 | |||||
| c-1.4-0.8-1.4-2.1,0-3c1.3-0.8,3.3-0.8,4.7-0.2c0.4-0.2,0.8-0.3,1.2-0.6c1.4-0.8,2.2-1.9,2.2-3c0-0.3,0.5-0.6,1.1-0.6 | |||||
| C879.8,201.4,880.3,201.7,880.3,202z M862.4,200.3c-0.6-0.3-1.5-0.3-2,0c-0.6,0.3-0.6,0.9,0,1.2c0.6,0.3,1.5,0.3,2,0 | |||||
| C862.9,201.1,862.9,200.6,862.4,200.3z M873.6,206.6c-0.6-0.3-1.5-0.3-2,0c-0.6,0.3-0.6,0.9,0,1.2c0.6,0.3,1.5,0.3,2,0 | |||||
| c0.5-0.3,0.6-0.7,0.2-1C873.7,206.8,873.7,206.7,873.6,206.6C873.6,206.6,873.6,206.6,873.6,206.6z M880.2,196.8 | |||||
| c1.4,0.8,1.4,2.1,0,3c-1.4,0.8-3.5,0.9-4.9,0.1l-0.2-0.1c-0.8-0.5-1.2-1.1-1-1.8c-2.2-0.7-4.9-0.6-7.1,0.1 | |||||
| c-0.5,0.2-1.2,0.1-1.5-0.2s-0.1-0.7,0.5-0.9c2.8-0.9,6.2-0.9,9.1-0.1c0,0,0,0,0,0c1.4-0.8,3.5-0.9,4.9-0.1L880.2,196.8z | |||||
| M878.7,197.7c-0.6-0.3-1.5-0.3-2,0c-0.6,0.3-0.6,0.9,0,1.2s1.5,0.3,2,0C879.3,198.6,879.3,198,878.7,197.7z"/> | |||||
| </g> | |||||
| </g> | |||||
| </g> | |||||
| <text transform="matrix(1 0 0 1 805.6185 198.5263)" class="st49"><tspan x="0" y="0" class="st6 st8 st9">模型</tspan><tspan x="0" y="16.8" class="st6 st8 st9">存储</tspan></text> | |||||
| <g> | |||||
| <path id="矩形备份-2_13_" class="st34" d="M1179.1,183.7h-142.2c-0.3,0-0.5,0.2-0.7,0.4c-0.2,0.3-0.3,0.6-0.3,1.1v76 | |||||
| c0,0.4,0.1,0.8,0.3,1.1c0.2,0.3,0.4,0.4,0.7,0.4h142.2c0.3,0,0.5-0.2,0.7-0.4c0.2-0.3,0.3-0.6,0.3-1.1v-76c0-0.4-0.1-0.8-0.3-1.1 | |||||
| C1179.6,183.9,1179.3,183.7,1179.1,183.7z"/> | |||||
| <text transform="matrix(1 0 0 1 1113.0444 227.3935)" class="st11 st12 st9">推理环境</text> | |||||
| <g id="云竖_1_" transform="translate(516.000000, 320.000000)"> | |||||
| <g> | |||||
| <rect id="矩形_23_" x="535.8" y="-119.6" class="st13" width="48.8" height="48.8"/> | |||||
| <g id="编组-6_1_" transform="translate(2.000000, 6.000000)"> | |||||
| <path id="Path-15_3_" class="st35" d="M556.3-82.3c1.7,0.9,3.7,2.1,6.2,0.5c2.4-1.6,15.5-8.8,16.9-9.7c1.9-0.9,3.6-8.5-4.3-15.5 | |||||
| c-0.4-5-6.8-16.2-14-13.6c-2,1.1-7.3,4.3-16.1,9.3c-0.7,0.4-1.3,0.7-1.8,1c-0.2,0.1-0.8,0.6-1.2,1.2c-0.5,0.4-1.7,1.1-3.5,2.3 | |||||
| c-2,0.8-2.9,2.2-2.9,4.4c0,3.5,1.5,7.7,5.5,10.8C545-88.9,554.6-83.2,556.3-82.3z"/> | |||||
| <linearGradient id="Fill-1_4_" gradientUnits="userSpaceOnUse" x1="-836.9307" y1="407.5797" x2="-837.0942" y2="407.6429" gradientTransform="matrix(27.8283 0 0 -13.8442 23834.3965 5530.2881)"> | |||||
| <stop offset="0" style="stop-color:#B2B7BF"/> | |||||
| <stop offset="0.1064" style="stop-color:#E2EBFD"/> | |||||
| <stop offset="0.2734" style="stop-color:#F8FAFF"/> | |||||
| <stop offset="0.4104" style="stop-color:#D8E0EE"/> | |||||
| <stop offset="1" style="stop-color:#F1F6FF"/> | |||||
| </linearGradient> | |||||
| <path id="Fill-1_1_" class="st50" d="M539.1-107c0.3,0,0.7,0,1,0.1c0,0,0,0,0,0c0.4,0.1,0.7,0.2,1.1,0.4l17.2-10 | |||||
| c-0.1,0-0.2-0.1-0.2-0.1c-0.1,0-0.2-0.1-0.3-0.1c-0.1,0-0.2-0.1-0.3-0.1c-0.1,0-0.2-0.1-0.3-0.1c0,0,0,0-0.1,0c0,0,0,0,0,0 | |||||
| c-0.1,0-0.1,0-0.2,0c-0.1,0-0.2,0-0.3,0c-0.1,0-0.2,0-0.3,0c-0.1,0-0.2,0-0.3,0c0,0,0,0,0,0c0,0,0,0,0,0c-0.1,0-0.2,0-0.4,0 | |||||
| c-0.1,0-0.3,0-0.4,0.1c0,0-0.1,0-0.1,0c0,0-0.1,0-0.1,0c-0.1,0-0.2,0-0.2,0.1c-0.2,0.1-0.4,0.2-0.6,0.3l-17.2,10 | |||||
| c0.2-0.1,0.5-0.2,0.8-0.3c0,0,0.1,0,0.1,0C538.5-106.9,538.8-107,539.1-107C539.1-107,539.1-107,539.1-107z"/> | |||||
| <linearGradient id="Fill-3_4_" gradientUnits="userSpaceOnUse" x1="-839.5898" y1="416.3705" x2="-839.8314" y2="416.8244" gradientTransform="matrix(30.367 0 0 -33.6775 26067.5156 13933.0166)"> | |||||
| <stop offset="0" style="stop-color:#C0CBDC"/> | |||||
| <stop offset="1.654118e-02" style="stop-color:#B3C0D4"/> | |||||
| <stop offset="0.1143" style="stop-color:#A9B8D1"/> | |||||
| <stop offset="0.1737" style="stop-color:#BEC9DB"/> | |||||
| <stop offset="0.3293" style="stop-color:#E0E5F0"/> | |||||
| <stop offset="0.5383" style="stop-color:#D9DEE6"/> | |||||
| <stop offset="0.5471" style="stop-color:#D6DBE4"/> | |||||
| <stop offset="0.6916" style="stop-color:#CAD1DC"/> | |||||
| <stop offset="1" style="stop-color:#EBEEF2"/> | |||||
| </linearGradient> | |||||
| <path id="Fill-3_1_" class="st51" d="M581-96.3c0-0.1,0-0.2,0-0.3c0-0.1,0-0.2,0-0.3c0-0.1,0-0.1,0-0.2c0,0,0,0,0,0 | |||||
| c0,0,0-0.1,0-0.1c0-0.1,0-0.2-0.1-0.3c0-0.1,0-0.2-0.1-0.4c0-0.1-0.1-0.2-0.1-0.4c0-0.1-0.1-0.2-0.1-0.4c0,0,0,0,0,0 | |||||
| c0,0,0,0,0,0c0-0.1-0.1-0.2-0.1-0.3c0-0.1-0.1-0.2-0.1-0.4c0-0.1-0.1-0.2-0.1-0.3c0-0.1-0.1-0.2-0.1-0.3c0-0.1-0.1-0.1-0.1-0.2 | |||||
| c0,0,0,0,0,0l0-0.1c0-0.1-0.1-0.2-0.1-0.3c0-0.1-0.1-0.2-0.2-0.3c-0.1-0.1-0.1-0.2-0.2-0.4c-0.1-0.1-0.1-0.3-0.2-0.4 | |||||
| c0,0,0,0,0,0c0,0,0,0,0,0c-0.1-0.2-0.2-0.4-0.3-0.5c-0.2-0.3-0.4-0.6-0.5-0.9c0,0,0,0,0,0l0,0c-0.1-0.2-0.2-0.4-0.4-0.5 | |||||
| c-0.1-0.1-0.2-0.3-0.3-0.4c-0.1-0.1-0.2-0.2-0.3-0.3c0,0,0,0-0.1-0.1c0,0,0,0,0,0c-0.1-0.1-0.1-0.1-0.2-0.2 | |||||
| c-0.1-0.1-0.2-0.2-0.3-0.3c-0.1-0.1-0.2-0.2-0.3-0.3c-0.1-0.1-0.2-0.2-0.3-0.3c0,0-0.1-0.1-0.1-0.1c0,0,0,0,0,0 | |||||
| c-0.1-0.1-0.1-0.1-0.2-0.2c-0.1-0.1-0.2-0.2-0.3-0.3c-0.1-0.1-0.2-0.2-0.3-0.2c-0.1-0.1-0.2-0.2-0.3-0.2c0,0-0.1-0.1-0.1-0.1 | |||||
| l-17.2,10c0.4,0.3,0.8,0.6,1.2,1c0,0,0,0,0,0c0.4,0.4,0.8,0.8,1.1,1.2c0,0,0,0,0,0c0.3,0.4,0.7,0.9,1,1.3c0,0,0,0,0,0 | |||||
| c0.3,0.5,0.6,0.9,0.9,1.4c0,0,0,0,0,0c0.3,0.5,0.5,1,0.7,1.5c0,0,0,0,0,0c0.2,0.5,0.4,1,0.5,1.6c0,0,0,0,0,0 | |||||
| c0.1,0.5,0.3,1,0.3,1.6c0,0,0,0,0,0c0.1,0.5,0.1,1,0.1,1.5c0,0.3,0,0.5,0,0.7c0,0,0,0,0,0.1c0,0.2-0.1,0.4-0.1,0.6 | |||||
| c0,0,0,0.1,0,0.1c0,0.2-0.1,0.4-0.1,0.6c0,0,0,0.1,0,0.1c-0.1,0.2-0.1,0.3-0.2,0.5c0,0,0,0,0,0c-0.1,0.2-0.2,0.3-0.3,0.5 | |||||
| c-0.1,0.2-0.3,0.4-0.5,0.6c0,0-0.1,0.1-0.1,0.1c-0.2,0.2-0.4,0.3-0.6,0.4l17.2-10c0.2-0.1,0.4-0.3,0.6-0.4c0,0,0.1-0.1,0.1-0.1 | |||||
| c0.2-0.2,0.3-0.4,0.5-0.6c0,0,0,0,0,0c0.1-0.1,0.2-0.3,0.3-0.5c0,0,0,0,0,0c0,0,0,0,0,0c0-0.1,0.1-0.2,0.1-0.3 | |||||
| c0-0.1,0-0.1,0.1-0.2c0,0,0-0.1,0-0.1c0,0,0-0.1,0-0.1c0-0.1,0.1-0.2,0.1-0.3c0,0,0-0.1,0-0.1c0,0,0-0.1,0-0.1c0,0,0-0.1,0-0.1 | |||||
| c0-0.1,0-0.2,0-0.3c0-0.1,0-0.1,0-0.2c0,0,0,0,0-0.1c0,0,0-0.1,0-0.1c0-0.1,0-0.2,0-0.3c0-0.1,0-0.2,0-0.3c0,0,0,0,0,0 | |||||
| c0-0.1,0-0.2,0-0.3C581.1-96,581-96.1,581-96.3z"/> | |||||
| <linearGradient id="Fill-8_6_" gradientUnits="userSpaceOnUse" x1="-846.8944" y1="415.673" x2="-847.3483" y2="416.2711" gradientTransform="matrix(41.218 0 0 -31.5976 35478.3477 13034.8008)"> | |||||
| <stop offset="0" style="stop-color:#CBD3E0"/> | |||||
| <stop offset="0.2302" style="stop-color:#D7DCE6"/> | |||||
| <stop offset="0.3076" style="stop-color:#C2CBDA"/> | |||||
| <stop offset="0.4132" style="stop-color:#DCE0E8"/> | |||||
| <stop offset="0.5076" style="stop-color:#EBEDF1"/> | |||||
| <stop offset="0.5317" style="stop-color:#F2F3F6"/> | |||||
| <stop offset="0.6002" style="stop-color:#FDFBFB"/> | |||||
| <stop offset="0.6687" style="stop-color:#F8F9FA"/> | |||||
| <stop offset="0.7321" style="stop-color:#D6DBE1"/> | |||||
| <stop offset="1" style="stop-color:#EBEEF2"/> | |||||
| </linearGradient> | |||||
| <path id="Fill-8_4_" class="st52" d="M551.8-108.2C551.8-108.2,551.8-108.2,551.8-108.2c0.2,0.2,0.5,0.5,0.7,0.8c0,0,0,0,0,0 | |||||
| c0.2,0.2,0.4,0.5,0.6,0.7c0,0,0,0,0,0c0.2,0.2,0.4,0.5,0.6,0.7c0,0,0,0,0,0c0.2,0.2,0.3,0.4,0.5,0.7c0.1,0.1,0.2,0.2,0.2,0.3 | |||||
| c0.1,0.1,0.2,0.3,0.3,0.4c0.2,0.2,0.3,0.5,0.5,0.7c0.1,0.1,0.1,0.2,0.2,0.3c0,0.1,0.1,0.2,0.1,0.2c0.1,0.2,0.2,0.5,0.4,0.7 | |||||
| c0,0,0,0.1,0,0.1c0.1,0.3,0.3,0.6,0.4,0.9c0,0,0,0,0,0c0.1,0.3,0.3,0.6,0.4,0.9c0,0,0,0,0,0.1c0.1,0.3,0.2,0.6,0.3,0.9l0,0.1 | |||||
| c0.1,0.3,0.2,0.6,0.2,0.8c0,0,0,0.1,0,0.1c0.1,0.3,0.1,0.6,0.2,0.9c0,0,0,0.1,0,0.1c0.1,0.3,0.1,0.6,0.1,0.9l17.2-10 | |||||
| c0-0.1,0-0.3-0.1-0.4c0-0.1,0-0.3-0.1-0.4c0,0,0-0.1,0-0.1c0,0,0-0.1,0-0.1c0-0.1,0-0.2-0.1-0.3c0-0.1-0.1-0.3-0.1-0.4 | |||||
| c0,0,0-0.1,0-0.1c0,0,0-0.1,0-0.1c0-0.1,0-0.1-0.1-0.2c0-0.1-0.1-0.3-0.1-0.4c0-0.1,0-0.1-0.1-0.2c0,0,0-0.1,0-0.1 | |||||
| c0-0.1,0-0.1,0-0.2c0-0.1-0.1-0.3-0.1-0.4c0-0.1-0.1-0.2-0.1-0.3c0,0,0,0,0-0.1c0,0,0-0.1,0-0.1c-0.1-0.1-0.1-0.3-0.2-0.4 | |||||
| c-0.1-0.1-0.1-0.3-0.2-0.4c0,0,0,0,0,0c0,0,0,0,0,0c-0.1-0.1-0.1-0.2-0.2-0.4c-0.1-0.1-0.1-0.3-0.2-0.4c0,0,0,0,0-0.1 | |||||
| c0,0,0-0.1,0-0.1c-0.1-0.1-0.1-0.2-0.2-0.3c-0.1-0.1-0.1-0.2-0.2-0.4c0-0.1-0.1-0.2-0.1-0.2c0,0,0-0.1-0.1-0.1 | |||||
| c0-0.1-0.1-0.1-0.1-0.2c-0.2-0.3-0.3-0.5-0.5-0.7c0-0.1-0.1-0.1-0.1-0.2c-0.1-0.1-0.1-0.2-0.2-0.3c-0.1-0.1-0.2-0.2-0.2-0.3 | |||||
| c0-0.1-0.1-0.1-0.1-0.2c-0.1-0.2-0.2-0.3-0.4-0.5c0,0,0,0,0,0c0,0,0,0,0,0c-0.1-0.1-0.2-0.2-0.3-0.3c-0.1-0.1-0.2-0.3-0.3-0.4 | |||||
| c0,0,0,0,0,0c0,0,0,0,0,0c-0.1-0.1-0.2-0.2-0.3-0.3c-0.1-0.1-0.2-0.2-0.3-0.4l0,0c0,0,0,0,0,0c-0.1-0.1-0.2-0.2-0.3-0.3 | |||||
| c-0.1-0.1-0.2-0.2-0.4-0.3c0,0,0,0,0,0l0,0c-0.1-0.1-0.2-0.2-0.4-0.3c-0.1-0.1-0.2-0.2-0.4-0.3c0,0,0,0,0,0 | |||||
| c-0.1-0.1-0.2-0.2-0.4-0.3c-0.1-0.1-0.2-0.2-0.4-0.3c0,0,0,0,0,0l0,0c-0.1-0.1-0.2-0.1-0.3-0.2c-0.1-0.1-0.2-0.1-0.4-0.2 | |||||
| c0,0-0.1,0-0.1,0c-0.1-0.1-0.2-0.1-0.3-0.1c-0.1-0.1-0.2-0.1-0.3-0.2c-0.1,0-0.1-0.1-0.2-0.1c0,0,0,0-0.1,0c0,0,0,0-0.1,0 | |||||
| c-0.1-0.1-0.2-0.1-0.3-0.1c-0.1,0-0.2-0.1-0.3-0.1c0,0,0,0-0.1,0c0,0,0,0-0.1,0c-0.1,0-0.1-0.1-0.2-0.1c-0.1,0-0.2-0.1-0.3-0.1 | |||||
| c-0.1,0-0.1,0-0.2,0c0,0-0.1,0-0.1,0c0,0-0.1,0-0.1,0c-0.1,0-0.2,0-0.4-0.1c-0.1,0-0.2,0-0.2,0c0,0-0.1,0-0.1,0c0,0,0,0-0.1,0 | |||||
| c-0.1,0-0.3,0-0.4,0c-0.1,0-0.1,0-0.2,0c0,0-0.1,0-0.1,0c0,0-0.1,0-0.1,0c-0.2,0-0.3,0-0.5,0.1c0,0,0,0,0,0c0,0-0.1,0-0.1,0 | |||||
| c-0.2,0-0.3,0.1-0.4,0.1c0,0,0,0,0,0c-0.2,0.1-0.4,0.2-0.6,0.3l-17.2,9.9c0.2-0.1,0.4-0.2,0.6-0.3c0.2-0.1,0.3-0.1,0.5-0.1 | |||||
| c0,0,0.1,0,0.1,0c0.2,0,0.4-0.1,0.6-0.1c0,0,0.1,0,0.1,0c0.2,0,0.4,0,0.6,0c0,0,0.1,0,0.1,0c0.2,0,0.5,0.1,0.7,0.1 | |||||
| c0,0,0.1,0,0.1,0c0.2,0.1,0.5,0.1,0.7,0.2c0,0,0,0,0.1,0c0.3,0.1,0.5,0.2,0.8,0.3c0,0,0,0,0.1,0c0.3,0.1,0.6,0.3,0.8,0.4 | |||||
| c0.3,0.1,0.5,0.3,0.8,0.5c0,0,0,0,0,0c0.3,0.2,0.5,0.4,0.7,0.6C551.4-108.6,551.6-108.4,551.8-108.2z"/> | |||||
| <linearGradient id="Fill-5_6_" gradientUnits="userSpaceOnUse" x1="-845.0588" y1="417.5899" x2="-844.7551" y2="417.0798" gradientTransform="matrix(37.419 0 0 -39.8938 32166.1191 16556.9258)"> | |||||
| <stop offset="0" style="stop-color:#FCFDFF"/> | |||||
| <stop offset="1" style="stop-color:#EFF1F6"/> | |||||
| </linearGradient> | |||||
| <path id="Fill-5_3_" class="st53" d="M557.9-96.9c3.4,2.4,6,7.3,6,11.3c0,4.3-3.1,6.1-6.8,3.9l-15-8.7 | |||||
| c-3.8-2.2-6.8-7.5-6.8-11.8c0-4,2.6-5.8,6-4.3c0.7-4.2,2.9-6.2,8.4-3.4C554.3-106.9,557.3-101.8,557.9-96.9z"/> | |||||
| <path id="Fill-5_2_" class="st17" d="M552.6-115.9c1.6-1.1,4-0.9,6.6,0.6c4.2,2.4,7.6,8,8.3,12.9c3.4,2.4,6,7.3,6,11.3 | |||||
| c0,2.1-0.6,3.6-1.8,4.3"/> | |||||
| <path id="Path-15_2_" class="st40" d="M560.9-120.9c-2,1.1-7.3,4.2-16.1,9.3c-0.8,0.4-1.4,0.7-1.8,1.1c-0.2,0.1-0.8,0.6-1.3,1.3 | |||||
| c-0.5,0.4-1.7,1.1-3.4,2.2c-1,0.4-1.8,1-2.3,1.8c-0.5,0.8-0.8,1.8-0.8,2.9c0,3.6,1.6,7.9,5.6,11.2c4,2.6,13.6,8.3,15.5,9.3 | |||||
| c1,0.6,2.2,1.2,3.4,1.3c0.9,0.1,1.9-0.1,3-0.9c1.5-1,6.8-3.9,11.1-6.4c2.8-1.6,5.2-2.9,5.8-3.3c0.7-0.3,1.4-1.5,1.7-3.2 | |||||
| c0.2-1.3,0.2-2.9-0.3-4.6c-0.7-2.5-2.3-5.4-5.4-8.2c-0.3-3-2.6-7.9-5.9-11.1c-1.3-1.3-2.8-2.2-4.3-2.7 | |||||
| C563.9-121.4,562.4-121.4,560.9-120.9z"/> | |||||
| </g> | |||||
| </g> | |||||
| </g> | |||||
| </g> | |||||
| <g> | |||||
| <g class="st4"> | |||||
| <line class="st5" x1="979.1" y1="224.1" x2="1033.7" y2="224.1"/> | |||||
| <g> | |||||
| <polygon class="st6" points="1025.8,234 1024.1,232.2 1032.8,224.2 1024.1,216.1 1025.8,214.3 1036.3,224.2 "/> | |||||
| </g> | |||||
| </g> | |||||
| </g> | |||||
| <text transform="matrix(1 0 0 1 992.8185 195.1307)" class="st49"><tspan x="0" y="0" class="st6 st8 st9">模型</tspan><tspan x="0" y="16.8" class="st6 st8 st9">推理</tspan></text> | |||||
| <g> | |||||
| <g class="st4"> | |||||
| <path class="st5" d="M361.4,94.1v-4.6c0-11,9-20,20-20h323.2c11,0,20,9,20,20v96"/> | |||||
| <g> | |||||
| <polygon class="st6" points="371.3,86.3 369.5,84.6 361.4,93.2 353.4,84.5 351.6,86.1 361.4,96.7 "/> | |||||
| </g> | |||||
| </g> | |||||
| </g> | |||||
| <g> | |||||
| <g class="st4"> | |||||
| <path class="st5" d="M361.4,355.1v4.6c0,11,9,20,20,20h323.2c11,0,20-9,20-20v-96"/> | |||||
| <g> | |||||
| <polygon class="st6" points="351.6,363.2 353.4,364.8 361.4,356 369.5,364.6 371.3,363 361.3,352.5 "/> | |||||
| </g> | |||||
| </g> | |||||
| </g> | |||||
| <text transform="matrix(1 0 0 1 497.7269 89.4885)" class="st7 st8 st9">迭代-调试代码</text> | |||||
| <text transform="matrix(1 0 0 1 497.7271 366.8143)" class="st7 st8 st9">迭代-修正数据</text> | |||||
| <text transform="matrix(1 0 0 1 187.7229 54.4447)" class="st54 st9">创建</text> | |||||
| <g> | |||||
| <line class="st55" x1="281.8" y1="43.1" x2="281.8" y2="375.8"/> | |||||
| <line class="st55" x1="800.2" y1="43.1" x2="800.2" y2="375.8"/> | |||||
| </g> | |||||
| <g> | |||||
| <g class="st4"> | |||||
| <line class="st5" x1="791.4" y1="226.1" x2="846" y2="226.1"/> | |||||
| <g> | |||||
| <polygon class="st6" points="838,235.9 836.4,234.1 845,226.1 836.4,218 838,216.3 848.6,226.1 "/> | |||||
| </g> | |||||
| </g> | |||||
| </g> | |||||
| <text transform="matrix(1 0 0 1 491.9814 54.4448)" class="st54 st9">模型开发与训练</text> | |||||
| <g> | |||||
| <g class="st4"> | |||||
| <path class="st5" d="M288.3,135.5h-64.6c-12.2,0-22.2,10-22.2,22.2v27.8"/> | |||||
| <g> | |||||
| <polygon class="st6" points="280.3,125.7 278.7,127.5 287.3,135.5 278.7,143.6 280.3,145.4 290.9,135.5 "/> | |||||
| </g> | |||||
| </g> | |||||
| </g> | |||||
| <g> | |||||
| <g class="st4"> | |||||
| <path class="st5" d="M288.3,314.6h-64.6c-12.2,0-22.2-10-22.2-22.2v-27.8"/> | |||||
| <g> | |||||
| <polygon class="st6" points="280.3,304.8 278.7,306.5 287.3,314.6 278.7,322.7 280.3,324.4 290.9,314.6 "/> | |||||
| </g> | |||||
| </g> | |||||
| </g> | |||||
| <text transform="matrix(1 0 0 1 953.21 54.4449)" class="st54 st9">模型推理</text> | |||||
| </svg> | |||||
| @@ -0,0 +1 @@ | |||||
| <svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 50"><defs><style>.cls-1{fill:#5bb973;}.cls-2{fill:#fff;}</style></defs><title>logo-w</title><path class="cls-1" d="M42.08,12.13l-15.65-9a4.44,4.44,0,0,0-4.43,0l-15.65,9A4.44,4.44,0,0,0,4.13,16V34a4.44,4.44,0,0,0,2.22,3.84l3.83,2.21a2.88,2.88,0,0,0-.06.59,2.95,2.95,0,1,0,1-2.17L7.26,36.3A2.63,2.63,0,0,1,6,34V16A2.62,2.62,0,0,1,7.26,13.7l15.65-9a2.59,2.59,0,0,1,2.61,0l15.65,9A2.63,2.63,0,0,1,42.47,16V34a2.64,2.64,0,0,1-1.3,2.27l-15.65,9a3.16,3.16,0,0,1-.5.22V39.88a1.31,1.31,0,0,0,0-.28V36.35l.1,0,9-6a.92.92,0,0,0,.41-.75V20a3,3,0,1,0-1.82,0v9L25,34.18V15.94a3,3,0,1,0-1.82,0v12l-5.08-2.95V20.19a3,3,0,1,0-1.82,0v5.26a.9.9,0,0,0,.45.79L23.2,30v8.16L12.11,31.73V23.84a2.93,2.93,0,1,0-1.82,0v8.41a.94.94,0,0,0,.46.79l12.45,7.2v6.34a.22.22,0,0,0,0,.08v.09l0,.1s0,0,0,.07l.06.1s0,0,0,0l.08.1,0,0a.39.39,0,0,0,.1.08l0,0,.12.07,0,0,.14,0h0a.39.39,0,0,0,.15,0h.16a4.44,4.44,0,0,0,2.22-.59l15.65-9A4.46,4.46,0,0,0,44.29,34V16a4.45,4.45,0,0,0-2.21-3.83m-29,27.42a1.12,1.12,0,1,1-1.12,1.12,1.12,1.12,0,0,1,1.12-1.12m20.6-23.46a1.12,1.12,0,1,1-1.12,1.12,1.12,1.12,0,0,1,1.12-1.12m-16.45.19a1.12,1.12,0,1,1-1.12,1.12,1.12,1.12,0,0,1,1.12-1.12m-6,3.65a1.12,1.12,0,1,1-1.12,1.12,1.12,1.12,0,0,1,1.12-1.12M24.13,12A1.12,1.12,0,1,1,23,13.14,1.12,1.12,0,0,1,24.13,12"/><path class="cls-2" d="M81.68,26.69H67.86c-2,.1-3.06,1-3.06,2.85v6.33c.1,1.68,1.16,2.53,3.06,2.63H81.57c1.9-.1,2.85-1,3-2.74V29.54A2.71,2.71,0,0,0,81.68,26.69Zm-.53,8c-.11.73-.53,1.16-1.48,1.26H69.54c-1-.21-1.37-.53-1.47-1.26V30.59a1.44,1.44,0,0,1,1.47-1.48h10a1.54,1.54,0,0,1,1.58,1.48Z"/><path class="cls-2" d="M63.21,20.57V17A1.63,1.63,0,0,1,64.8,15.4H79.25c1.06-.11,1.58.42,1.58,1.37V19.3c0,.85-.52,1.27-1.47,1.27H64.59V23H81.47c1.79,0,2.74-.85,2.74-2.43V15.72A2.45,2.45,0,0,0,81.47,13H74.08V11H70.6v2H62.69c-2,0-3,.95-3,3v9.39a42.65,42.65,0,0,1-2,13l3.27.64a43.43,43.43,0,0,0,2.11-13V20.57Z"/><path class="cls-2" d="M90,24.47l3.38,1.8a10.1,10.1,0,0,0,3.9-5.81h5.91V18H97.82a25.57,25.57,0,0,0,.21-3h5V12.55H93.7V11H90.22v4h4.43a17.38,17.38,0,0,1-.21,2.95H89.38v2.53h4.43A7.05,7.05,0,0,1,90,24.47Z"/><path class="cls-2" d="M97.82,21.62A21.82,21.82,0,0,1,100,26.05h3.7a25.8,25.8,0,0,0-2.22-4.43Z"/><path class="cls-2" d="M112.17,26.79H93.39c-1.8.21-2.85,1.06-3,2.64v4.75H112v1c0,.85-.52,1.27-1.58,1.27h-15c-1,0-1.48-.42-1.48-1.16H90.54v1A2.75,2.75,0,0,0,93.18,39h19.09c2-.1,3.06-1,3.06-2.64V29.54A3.21,3.21,0,0,0,112.17,26.79Zm-.32,4.86h-18V30.8a1.43,1.43,0,0,1,1.48-1.47h15c1,0,1.58.52,1.58,1.47Z"/><path class="cls-2" d="M113.64,12h-6.22q-2.53.17-2.85,2.22V23.1a2.33,2.33,0,0,0,2.32,2.22h6.65c1.47-.11,2.32-.85,2.32-2.22V14.24C116,13,115.23,12.23,113.64,12Zm-1,9.29c0,1.05-.53,1.58-1.48,1.58h-1.79A1.39,1.39,0,0,1,108,21.31V16a1.42,1.42,0,0,1,1.47-1.47H111A1.53,1.53,0,0,1,112.59,16Z"/></svg> | |||||
| @@ -0,0 +1 @@ | |||||
| <svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 50"><defs><style>.cls-1{fill:#35373f;}</style></defs><title>logo</title><path class="cls-1" d="M42.08,12.13l-15.65-9a4.44,4.44,0,0,0-4.43,0l-15.65,9A4.44,4.44,0,0,0,4.13,16V34a4.44,4.44,0,0,0,2.22,3.84l3.83,2.21a2.88,2.88,0,0,0-.06.59,2.95,2.95,0,1,0,1-2.17L7.26,36.3A2.63,2.63,0,0,1,6,34V16A2.62,2.62,0,0,1,7.26,13.7l15.65-9a2.59,2.59,0,0,1,2.61,0l15.65,9A2.63,2.63,0,0,1,42.47,16V34a2.64,2.64,0,0,1-1.3,2.27l-15.65,9a3.16,3.16,0,0,1-.5.22V39.88a1.31,1.31,0,0,0,0-.28V36.35l.1,0,9-6a.92.92,0,0,0,.41-.75V20a3,3,0,1,0-1.82,0v9L25,34.18V15.94a3,3,0,1,0-1.82,0v12l-5.08-2.95V20.19a3,3,0,1,0-1.82,0v5.26a.9.9,0,0,0,.45.79L23.2,30v8.16L12.11,31.73V23.84a2.93,2.93,0,1,0-1.82,0v8.41a.94.94,0,0,0,.46.79l12.45,7.2v6.34a.22.22,0,0,0,0,.08v.09l0,.1s0,0,0,.07l.06.1s0,0,0,0l.08.1,0,0a.39.39,0,0,0,.1.08l0,0,.12.07,0,0,.14,0h0a.39.39,0,0,0,.15,0h.16a4.44,4.44,0,0,0,2.22-.59l15.65-9A4.46,4.46,0,0,0,44.29,34V16a4.45,4.45,0,0,0-2.21-3.83m-29,27.42a1.12,1.12,0,1,1-1.12,1.12,1.12,1.12,0,0,1,1.12-1.12m20.6-23.46a1.12,1.12,0,1,1-1.12,1.12,1.12,1.12,0,0,1,1.12-1.12m-16.45.19a1.12,1.12,0,1,1-1.12,1.12,1.12,1.12,0,0,1,1.12-1.12m-6,3.65a1.12,1.12,0,1,1-1.12,1.12,1.12,1.12,0,0,1,1.12-1.12M24.13,12A1.12,1.12,0,1,1,23,13.14,1.12,1.12,0,0,1,24.13,12"/><path class="cls-1" d="M81.68,26.69H67.86c-2,.1-3.06,1-3.06,2.85v6.33c.1,1.68,1.16,2.53,3.06,2.63H81.57c1.9-.1,2.85-1,3-2.74V29.54A2.71,2.71,0,0,0,81.68,26.69Zm-.53,8c-.11.73-.53,1.16-1.48,1.26H69.54c-1-.21-1.37-.53-1.47-1.26V30.59a1.44,1.44,0,0,1,1.47-1.48h10a1.54,1.54,0,0,1,1.58,1.48Z"/><path class="cls-1" d="M63.21,20.57V17A1.63,1.63,0,0,1,64.8,15.4H79.25c1.06-.11,1.58.42,1.58,1.37V19.3c0,.85-.52,1.27-1.47,1.27H64.59V23H81.47c1.79,0,2.74-.85,2.74-2.43V15.72A2.45,2.45,0,0,0,81.47,13H74.08V11H70.6v2H62.69c-2,0-3,.95-3,3v9.39a42.65,42.65,0,0,1-2,13l3.27.64a43.43,43.43,0,0,0,2.11-13V20.57Z"/><path class="cls-1" d="M90,24.47l3.38,1.8a10.1,10.1,0,0,0,3.9-5.81h5.91V18H97.82a25.57,25.57,0,0,0,.21-3h5V12.55H93.7V11H90.22v4h4.43a17.38,17.38,0,0,1-.21,2.95H89.38v2.53h4.43A7.05,7.05,0,0,1,90,24.47Z"/><path class="cls-1" d="M97.82,21.62A21.82,21.82,0,0,1,100,26.05h3.7a25.8,25.8,0,0,0-2.22-4.43Z"/><path class="cls-1" d="M112.17,26.79H93.39c-1.8.21-2.85,1.06-3,2.64v4.75H112v1c0,.85-.52,1.27-1.58,1.27h-15c-1,0-1.48-.42-1.48-1.16H90.54v1A2.75,2.75,0,0,0,93.18,39h19.09c2-.1,3.06-1,3.06-2.64V29.54A3.21,3.21,0,0,0,112.17,26.79Zm-.32,4.86h-18V30.8a1.43,1.43,0,0,1,1.48-1.47h15c1,0,1.58.52,1.58,1.47Z"/><path class="cls-1" d="M113.64,12h-6.22q-2.53.17-2.85,2.22V23.1a2.33,2.33,0,0,0,2.32,2.22h6.65c1.47-.11,2.32-.85,2.32-2.22V14.24C116,13,115.23,12.23,113.64,12Zm-1,9.29c0,1.05-.53,1.58-1.48,1.58h-1.79A1.39,1.39,0,0,1,108,21.31V16a1.42,1.42,0,0,1,1.47-1.47H111A1.53,1.53,0,0,1,112.59,16Z"/></svg> | |||||
| @@ -6,11 +6,12 @@ package models | |||||
| import ( | import ( | ||||
| "bytes" | "bytes" | ||||
| "code.gitea.io/gitea/modules/log" | |||||
| "fmt" | "fmt" | ||||
| "io" | "io" | ||||
| "path" | "path" | ||||
| "code.gitea.io/gitea/modules/log" | |||||
| "code.gitea.io/gitea/modules/obs" | |||||
| "code.gitea.io/gitea/modules/setting" | "code.gitea.io/gitea/modules/setting" | ||||
| "code.gitea.io/gitea/modules/storage" | "code.gitea.io/gitea/modules/storage" | ||||
| api "code.gitea.io/gitea/modules/structs" | api "code.gitea.io/gitea/modules/structs" | ||||
| @@ -253,9 +254,33 @@ func DeleteAttachments(attachments []*Attachment, remove bool) (int, error) { | |||||
| if remove { | if remove { | ||||
| for i, a := range attachments { | for i, a := range attachments { | ||||
| if err := storage.Attachments.Delete(a.RelativePath()); err != nil { | |||||
| return i, err | |||||
| if a.Type == TypeCloudBrainOne { | |||||
| if err := storage.Attachments.Delete(a.RelativePath()); err != nil { | |||||
| return i, err | |||||
| } | |||||
| } | } | ||||
| if a.Type == TypeCloudBrainTwo { | |||||
| input := &obs.DeleteObjectInput{} | |||||
| input.Bucket = setting.Bucket | |||||
| input.Key = setting.BasePath + path.Join(a.UUID[0:1], a.UUID[1:2], a.UUID, a.Name) | |||||
| log.Info("delete obs file:" + input.Key) | |||||
| output, err := storage.ObsCli.DeleteObject(input) | |||||
| if err == nil { | |||||
| log.Info("RequestId:%s\n", output.RequestId) | |||||
| } else if obsError, ok := err.(obs.ObsError); ok { | |||||
| log.Info("Code:%s\n", obsError.Code) | |||||
| log.Info("Message:%s\n", obsError.Message) | |||||
| } | |||||
| } | |||||
| //rf := path.Join(a.UUID[0:1], a.UUID[1:2]) | |||||
| /* | |||||
| files, err := repo.GetDatasetDirs(a.UUID, "") | |||||
| if err != nil { | |||||
| log.Info("No files in attachment dirs.") | |||||
| } | |||||
| log.Info("files=" + files) | |||||
| */ | |||||
| } | } | ||||
| } | } | ||||
| return int(cnt), nil | return int(cnt), nil | ||||
| @@ -91,6 +91,7 @@ func GetBlockChainUnSuccessCommits() ([]*BlockChain, error) { | |||||
| blockChains := make([]*BlockChain, 0, 10) | blockChains := make([]*BlockChain, 0, 10) | ||||
| return blockChains, x. | return blockChains, x. | ||||
| Where("status != ?", BlockChainCommitSuccess). | Where("status != ?", BlockChainCommitSuccess). | ||||
| Limit(100). | |||||
| Find(&blockChains) | Find(&blockChains) | ||||
| } | } | ||||
| @@ -2,7 +2,6 @@ package models | |||||
| import ( | import ( | ||||
| "encoding/json" | "encoding/json" | ||||
| "errors" | |||||
| "fmt" | "fmt" | ||||
| "time" | "time" | ||||
| "xorm.io/xorm" | "xorm.io/xorm" | ||||
| @@ -77,11 +76,11 @@ type CloudBrainLoginResult struct { | |||||
| type TaskRole struct { | type TaskRole struct { | ||||
| Name string `json:"name"` | Name string `json:"name"` | ||||
| TaskNumber int8 `json:"taskNumber"` | |||||
| MinSucceededTaskCount int8 `json:"minSucceededTaskCount"` | |||||
| MinFailedTaskCount int8 `json:"minFailedTaskCount"` | |||||
| CPUNumber int8 `json:"cpuNumber"` | |||||
| GPUNumber int8 `json:"gpuNumber"` | |||||
| TaskNumber int `json:"taskNumber"` | |||||
| MinSucceededTaskCount int `json:"minSucceededTaskCount"` | |||||
| MinFailedTaskCount int `json:"minFailedTaskCount"` | |||||
| CPUNumber int `json:"cpuNumber"` | |||||
| GPUNumber int `json:"gpuNumber"` | |||||
| MemoryMB int `json:"memoryMB"` | MemoryMB int `json:"memoryMB"` | ||||
| ShmMB int `json:"shmMB"` | ShmMB int `json:"shmMB"` | ||||
| Command string `json:"command"` | Command string `json:"command"` | ||||
| @@ -128,8 +127,9 @@ type GetImagesResult struct { | |||||
| } | } | ||||
| type GetImagesPayload struct { | type GetImagesPayload struct { | ||||
| Count int `json:"count"` | |||||
| ImageInfo []*ImageInfo `json:"rows"` | |||||
| Count int `json:"count"` | |||||
| TotalPages int `json:"totalPages,omitempty"` | |||||
| ImageInfo []*ImageInfo `json:"rows"` | |||||
| } | } | ||||
| type CloudbrainsOptions struct { | type CloudbrainsOptions struct { | ||||
| @@ -291,6 +291,37 @@ type GpuInfo struct { | |||||
| Queue string `json:"queue"` | Queue string `json:"queue"` | ||||
| } | } | ||||
| type ResourceSpecs struct { | |||||
| ResourceSpec []*ResourceSpec `json:"resorce_specs"` | |||||
| } | |||||
| type ResourceSpec struct { | |||||
| Id int `json:"id"` | |||||
| CpuNum int `json:"cpu"` | |||||
| GpuNum int `json:"gpu"` | |||||
| MemMiB int `json:"memMiB"` | |||||
| ShareMemMiB int `json:"shareMemMiB"` | |||||
| } | |||||
| type FlavorInfos struct { | |||||
| FlavorInfo []*FlavorInfo `json:"flavor_info"` | |||||
| } | |||||
| type FlavorInfo struct { | |||||
| Id int `json:"id"` | |||||
| Value string `json:"value"` | |||||
| } | |||||
| type PoolInfos struct { | |||||
| PoolInfo []*PoolInfo `json:"pool_info"` | |||||
| } | |||||
| type PoolInfo struct { | |||||
| PoolId string `json:"pool_id"` | |||||
| PoolName string `json:"pool_name"` | |||||
| PoolType string `json:"pool_type"` | |||||
| } | |||||
| type CommitImageParams struct { | type CommitImageParams struct { | ||||
| Ip string `json:"ip"` | Ip string `json:"ip"` | ||||
| TaskContainerId string `json:"taskContainerId"` | TaskContainerId string `json:"taskContainerId"` | ||||
| @@ -304,7 +335,7 @@ type CommitImageResult struct { | |||||
| Payload map[string]interface{} `json:"payload"` | Payload map[string]interface{} `json:"payload"` | ||||
| } | } | ||||
| type StopJobResult struct { | |||||
| type CloudBrainResult struct { | |||||
| Code string `json:"code"` | Code string `json:"code"` | ||||
| Msg string `json:"msg"` | Msg string `json:"msg"` | ||||
| } | } | ||||
| @@ -826,7 +857,7 @@ func getRepoCloudBrain(cb *Cloudbrain) (*Cloudbrain, error) { | |||||
| if err != nil { | if err != nil { | ||||
| return nil, err | return nil, err | ||||
| } else if !has { | } else if !has { | ||||
| return nil, errors.New("cloudbrain task is not found") | |||||
| return nil, ErrJobNotExist{} | |||||
| } | } | ||||
| return cb, nil | return cb, nil | ||||
| } | } | ||||
| @@ -866,3 +897,8 @@ func deleteJob(e Engine, job *Cloudbrain) error { | |||||
| _, err := e.ID(job.ID).Delete(job) | _, err := e.ID(job.ID).Delete(job) | ||||
| return err | return err | ||||
| } | } | ||||
| func GetCloudbrainByName(jobName string) (*Cloudbrain, error) { | |||||
| cb := &Cloudbrain{JobName: jobName} | |||||
| return getRepoCloudBrain(cb) | |||||
| } | |||||
| @@ -0,0 +1,36 @@ | |||||
| package models | |||||
| import ( | |||||
| "code.gitea.io/gitea/modules/log" | |||||
| "xorm.io/xorm" | |||||
| ) | |||||
| type CustomMigration struct { | |||||
| Description string | |||||
| Migrate func(*xorm.Engine) error | |||||
| } | |||||
| var customMigrations = []CustomMigration{ | |||||
| {"Custom v1 Topic struct change to support chinese", syncTopicStruct}, | |||||
| } | |||||
| func MigrateCustom(x *xorm.Engine) { | |||||
| for _, m := range customMigrations { | |||||
| log.Info("Migration: %s", m.Description) | |||||
| if err := m.Migrate(x); err != nil { | |||||
| log.Error("Migration: %v", err) | |||||
| } | |||||
| } | |||||
| } | |||||
| func syncTopicStruct(x *xorm.Engine) error { | |||||
| query := "ALTER TABLE topic ALTER COLUMN name TYPE varchar(105);" | |||||
| _, err := x.Exec(query) | |||||
| return err | |||||
| } | |||||
| @@ -1987,3 +1987,15 @@ func IsErrFileChunkNotExist(err error) bool { | |||||
| _, ok := err.(ErrFileChunkNotExist) | _, ok := err.(ErrFileChunkNotExist) | ||||
| return ok | return ok | ||||
| } | } | ||||
| type ErrJobNotExist struct { | |||||
| } | |||||
| func IsErrJobNotExist(err error) bool { | |||||
| _, ok := err.(ErrJobNotExist) | |||||
| return ok | |||||
| } | |||||
| func (err ErrJobNotExist) Error() string { | |||||
| return fmt.Sprintf("the job does not exist") | |||||
| } | |||||
| @@ -1,6 +1,9 @@ | |||||
| package models | package models | ||||
| import ( | import ( | ||||
| "fmt" | |||||
| "code.gitea.io/gitea/modules/log" | |||||
| "code.gitea.io/gitea/modules/timeutil" | "code.gitea.io/gitea/modules/timeutil" | ||||
| "xorm.io/xorm" | "xorm.io/xorm" | ||||
| ) | ) | ||||
| @@ -88,7 +91,28 @@ func InsertFileChunk(fileChunk *FileChunk) (_ *FileChunk, err error) { | |||||
| return fileChunk, nil | return fileChunk, nil | ||||
| } | } | ||||
| // UpdateFileChunk updates the given attachment in database | |||||
| func DeleteFileChunkById(uuid string) (*FileChunk, error) { | |||||
| return deleteFileChunkById(x, uuid) | |||||
| } | |||||
| func deleteFileChunkById(e Engine, uuid string) (*FileChunk, error) { | |||||
| fileChunk := new(FileChunk) | |||||
| if has, err := e.Where("uuid = ?", uuid).Get(fileChunk); err != nil { | |||||
| return nil, err | |||||
| } else if !has { | |||||
| return nil, ErrFileChunkNotExist{"", uuid} | |||||
| } | |||||
| err := deleteFileChunk(e, fileChunk) | |||||
| log.Info("delete the filechunk,id=" + fmt.Sprint(fileChunk.ID)) | |||||
| if err != nil { | |||||
| return nil, err | |||||
| } else { | |||||
| return fileChunk, nil | |||||
| } | |||||
| } | |||||
| // UpdateFileChunk updates the given file_chunk in database | |||||
| func UpdateFileChunk(fileChunk *FileChunk) error { | func UpdateFileChunk(fileChunk *FileChunk) error { | ||||
| return updateFileChunk(x, fileChunk) | return updateFileChunk(x, fileChunk) | ||||
| } | } | ||||
| @@ -129,6 +129,7 @@ func init() { | |||||
| new(Cloudbrain), | new(Cloudbrain), | ||||
| new(FileChunk), | new(FileChunk), | ||||
| new(BlockChain), | new(BlockChain), | ||||
| new(RecommendOrg), | |||||
| ) | ) | ||||
| gonicNames := []string{"SSL", "UID"} | gonicNames := []string{"SSL", "UID"} | ||||
| @@ -185,6 +186,8 @@ func SetEngine() (err error) { | |||||
| x.SetMaxOpenConns(setting.Database.MaxOpenConns) | x.SetMaxOpenConns(setting.Database.MaxOpenConns) | ||||
| x.SetMaxIdleConns(setting.Database.MaxIdleConns) | x.SetMaxIdleConns(setting.Database.MaxIdleConns) | ||||
| x.SetConnMaxLifetime(setting.Database.ConnMaxLifetime) | x.SetConnMaxLifetime(setting.Database.ConnMaxLifetime) | ||||
| x.Sync2(tables...) | |||||
| MigrateCustom(x) | |||||
| return nil | return nil | ||||
| } | } | ||||
| @@ -0,0 +1,65 @@ | |||||
| package models | |||||
| import ( | |||||
| "code.gitea.io/gitea/modules/log" | |||||
| "code.gitea.io/gitea/modules/timeutil" | |||||
| ) | |||||
| type RecommendOrg struct { | |||||
| ID int64 `xorm:"pk autoincr"` | |||||
| Order int64 `xorm:"INDEX NOT NULL unique"` | |||||
| OrgID int64 `xorm:"INDEX NOT NULL unique"` | |||||
| CreatedUnix timeutil.TimeStamp `xorm:"created"` | |||||
| } | |||||
| type RecommendOrgInfo struct { | |||||
| RecommendOrg `xorm:"extends"` | |||||
| User `xorm:"extends"` | |||||
| } | |||||
| type RecommendOrgList []*RecommendOrg | |||||
| type RecommendOrgInfoList []*RecommendOrgInfo | |||||
| func getRecommendOrgs(e Engine) (RecommendOrgList, error) { | |||||
| orgs := make(RecommendOrgList, 0, 10) | |||||
| err := e.Asc("order"). | |||||
| Find(&orgs) | |||||
| return orgs, err | |||||
| } | |||||
| func GetRecommendOrgs() (RecommendOrgList, error) { | |||||
| return getRecommendOrgs(x) | |||||
| } | |||||
| func getRecommendOrgInfos(e Engine) (RecommendOrgInfoList, error) { | |||||
| orgs := make(RecommendOrgInfoList, 0, 10) | |||||
| if err := e.Table(&RecommendOrg{}).Join("INNER", "`user`", "`user`.id = `recommend_org`.org_id"). | |||||
| OrderBy("recommend_org.order").Find(&orgs); err != nil { | |||||
| return orgs, err | |||||
| } | |||||
| return orgs, nil | |||||
| } | |||||
| func GetRecommendOrgInfos() (RecommendOrgInfoList, error) { | |||||
| return getRecommendOrgInfos(x) | |||||
| } | |||||
| func delRecommendOrgs(e Engine) error { | |||||
| sql := "delete from recommend_org" | |||||
| _, err := e.Exec(sql) | |||||
| return err | |||||
| } | |||||
| func UpdateRecommendOrgs(orgs RecommendOrgList) error { | |||||
| if err := delRecommendOrgs(x); err != nil { | |||||
| log.Error("delRecommendOrgs failed:%v", err.Error()) | |||||
| return err | |||||
| } | |||||
| if _, err := x.Insert(&orgs); err != nil { | |||||
| log.Error("Insert failed:%v", err.Error()) | |||||
| return err | |||||
| } | |||||
| return nil | |||||
| } | |||||
| @@ -175,6 +175,7 @@ type Repository struct { | |||||
| NumMilestones int `xorm:"NOT NULL DEFAULT 0"` | NumMilestones int `xorm:"NOT NULL DEFAULT 0"` | ||||
| NumClosedMilestones int `xorm:"NOT NULL DEFAULT 0"` | NumClosedMilestones int `xorm:"NOT NULL DEFAULT 0"` | ||||
| NumOpenMilestones int `xorm:"-"` | NumOpenMilestones int `xorm:"-"` | ||||
| NumCommit int64 `xorm:"NOT NULL DEFAULT 0"` | |||||
| IsPrivate bool `xorm:"INDEX"` | IsPrivate bool `xorm:"INDEX"` | ||||
| IsEmpty bool `xorm:"INDEX"` | IsEmpty bool `xorm:"INDEX"` | ||||
| @@ -213,6 +214,9 @@ type Repository struct { | |||||
| CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` | CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` | ||||
| UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` | UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` | ||||
| Hot int64 `xorm:"-"` | |||||
| Active int64 `xorm:"-"` | |||||
| } | } | ||||
| // SanitizedOriginalURL returns a sanitized OriginalURL | // SanitizedOriginalURL returns a sanitized OriginalURL | ||||
| @@ -1411,6 +1415,15 @@ func GetRepositoriesByForkID(forkID int64) ([]*Repository, error) { | |||||
| return getRepositoriesByForkID(x, forkID) | return getRepositoriesByForkID(x, forkID) | ||||
| } | } | ||||
| func getALLRepositories(e Engine) ([]*Repository, error) { | |||||
| repos := make([]*Repository, 0, 1000) | |||||
| return repos, e.Find(&repos) | |||||
| } | |||||
| func GetAllRepositories() ([]*Repository, error) { | |||||
| return getALLRepositories(x) | |||||
| } | |||||
| func updateRepository(e Engine, repo *Repository, visibilityChanged bool) (err error) { | func updateRepository(e Engine, repo *Repository, visibilityChanged bool) (err error) { | ||||
| repo.LowerName = strings.ToLower(repo.Name) | repo.LowerName = strings.ToLower(repo.Name) | ||||
| @@ -2413,6 +2426,7 @@ func updateRepositoryCols(e Engine, repo *Repository, cols ...string) error { | |||||
| } | } | ||||
| // UpdateRepositoryCols updates repository's columns | // UpdateRepositoryCols updates repository's columns | ||||
| // Notice: it will update the updated_unix automatically, be careful to use this | |||||
| func UpdateRepositoryCols(repo *Repository, cols ...string) error { | func UpdateRepositoryCols(repo *Repository, cols ...string) error { | ||||
| return updateRepositoryCols(x, repo, cols...) | return updateRepositoryCols(x, repo, cols...) | ||||
| } | } | ||||
| @@ -2421,6 +2435,7 @@ func GetBlockChainUnSuccessRepos() ([]*Repository, error) { | |||||
| repos := make([]*Repository, 0, 10) | repos := make([]*Repository, 0, 10) | ||||
| return repos, x. | return repos, x. | ||||
| Where("block_chain_status != ?", RepoBlockChainSuccess). | Where("block_chain_status != ?", RepoBlockChainSuccess). | ||||
| Limit(100). | |||||
| Find(&repos) | Find(&repos) | ||||
| } | } | ||||
| @@ -2441,3 +2456,11 @@ func (repo *Repository) IncreaseCloneCnt() { | |||||
| return | return | ||||
| } | } | ||||
| func UpdateRepositoryCommitNum(repo *Repository) error { | |||||
| if _,err := x.Exec("UPDATE `repository` SET num_commit = ? where id = ?", repo.NumCommit, repo.ID); err != nil { | |||||
| return err | |||||
| } | |||||
| return nil | |||||
| } | |||||
| @@ -198,6 +198,8 @@ const ( | |||||
| SearchOrderByForks SearchOrderBy = "num_forks ASC" | SearchOrderByForks SearchOrderBy = "num_forks ASC" | ||||
| SearchOrderByForksReverse SearchOrderBy = "num_forks DESC" | SearchOrderByForksReverse SearchOrderBy = "num_forks DESC" | ||||
| SearchOrderByDownloadTimes SearchOrderBy = "download_times DESC" | SearchOrderByDownloadTimes SearchOrderBy = "download_times DESC" | ||||
| SearchOrderByHot SearchOrderBy = "(num_watches + num_stars + num_forks + clone_cnt) DESC" | |||||
| SearchOrderByActive SearchOrderBy = "(num_issues + num_pulls + num_commit) DESC" | |||||
| ) | ) | ||||
| // SearchRepositoryCondition creates a query condition according search repository options | // SearchRepositoryCondition creates a query condition according search repository options | ||||
| @@ -8,6 +8,7 @@ import ( | |||||
| "fmt" | "fmt" | ||||
| "regexp" | "regexp" | ||||
| "strings" | "strings" | ||||
| "unicode/utf8" | |||||
| "code.gitea.io/gitea/modules/timeutil" | "code.gitea.io/gitea/modules/timeutil" | ||||
| @@ -21,12 +22,12 @@ func init() { | |||||
| ) | ) | ||||
| } | } | ||||
| var topicPattern = regexp.MustCompile(`^[a-z0-9][a-z0-9-]*$`) | |||||
| var topicPattern = regexp.MustCompile(`^[\x{4e00}-\x{9fa5}a-z0-9][\x{4e00}-\x{9fa5}a-z0-9-]*$`) | |||||
| // Topic represents a topic of repositories | // Topic represents a topic of repositories | ||||
| type Topic struct { | type Topic struct { | ||||
| ID int64 | ID int64 | ||||
| Name string `xorm:"UNIQUE VARCHAR(25)"` | |||||
| Name string `xorm:"UNIQUE VARCHAR(105)"` | |||||
| RepoCount int | RepoCount int | ||||
| CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` | CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` | ||||
| UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` | UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` | ||||
| @@ -56,7 +57,7 @@ func (err ErrTopicNotExist) Error() string { | |||||
| // ValidateTopic checks a topic by length and match pattern rules | // ValidateTopic checks a topic by length and match pattern rules | ||||
| func ValidateTopic(topic string) bool { | func ValidateTopic(topic string) bool { | ||||
| return len(topic) <= 35 && topicPattern.MatchString(topic) | |||||
| return utf8.RuneCountInString(topic) <= 35 && topicPattern.MatchString(topic) | |||||
| } | } | ||||
| // SanitizeAndValidateTopics sanitizes and checks an array or topics | // SanitizeAndValidateTopics sanitizes and checks an array or topics | ||||
| @@ -976,12 +976,12 @@ func CreateUser(u *User) (err error) { | |||||
| result, err := blockchain.CreateBlockchainAccount() | result, err := blockchain.CreateBlockchainAccount() | ||||
| if err != nil { | if err != nil { | ||||
| log.Error("createBlockchainAccount failed:", err.Error()) | log.Error("createBlockchainAccount failed:", err.Error()) | ||||
| return err | |||||
| //return err | |||||
| } else { | |||||
| u.PublicKey = result.Payload["publickey"].(string) | |||||
| u.PrivateKey = result.Payload["privatekey"].(string) | |||||
| } | } | ||||
| u.PublicKey = result.Payload["publickey"].(string) | |||||
| u.PrivateKey = result.Payload["privatekey"].(string) | |||||
| sess := x.NewSession() | sess := x.NewSession() | ||||
| defer sess.Close() | defer sess.Close() | ||||
| if err = sess.Begin(); err != nil { | if err = sess.Begin(); err != nil { | ||||
| @@ -2047,6 +2047,7 @@ func GetBlockChainUnSuccessUsers() ([]*User, error) { | |||||
| users := make([]*User, 0, 10) | users := make([]*User, 0, 10) | ||||
| err := x.Where("public_key = ''"). | err := x.Where("public_key = ''"). | ||||
| Or("private_key = ''"). | Or("private_key = ''"). | ||||
| Limit(100). | |||||
| Find(&users) | Find(&users) | ||||
| return users, err | return users, err | ||||
| } | } | ||||
| @@ -80,6 +80,18 @@ func GetEmailAddressByID(uid, id int64) (*EmailAddress, error) { | |||||
| return email, nil | return email, nil | ||||
| } | } | ||||
| // GetEmailAddressByIDAndEmail gets a user's email address by ID and email | |||||
| func GetEmailAddressByIDAndEmail(uid int64, emailAddr string) (*EmailAddress, error) { | |||||
| // User ID is required for security reasons | |||||
| email := &EmailAddress{UID: uid, Email: emailAddr} | |||||
| if has, err := x.Get(email); err != nil { | |||||
| return nil, err | |||||
| } else if !has { | |||||
| return nil, nil | |||||
| } | |||||
| return email, nil | |||||
| } | |||||
| func isEmailActive(e Engine, email string, userID, emailID int64) (bool, error) { | func isEmailActive(e Engine, email string, userID, emailID int64) (bool, error) { | ||||
| if len(email) == 0 { | if len(email) == 0 { | ||||
| return true, nil | return true, nil | ||||
| @@ -281,6 +293,16 @@ func MakeEmailPrimary(email *EmailAddress) error { | |||||
| } | } | ||||
| user.Email = email.Email | user.Email = email.Email | ||||
| has, err = sess.Where("id!=?", user.ID). | |||||
| And("type=?", user.Type). | |||||
| And("email=?", strings.ToLower(user.Email)). | |||||
| Get(new(User)) | |||||
| if err != nil { | |||||
| return err | |||||
| } else if has { | |||||
| return ErrEmailAlreadyUsed{user.Email} | |||||
| } | |||||
| if _, err = sess.ID(user.ID).Cols("email").Update(user); err != nil { | if _, err = sess.ID(user.ID).Cols("email").Update(user); err != nil { | ||||
| return err | return err | ||||
| } | } | ||||
| @@ -13,6 +13,7 @@ type CreateCloudBrainForm struct { | |||||
| JobType string `form:"job_type" binding:"Required"` | JobType string `form:"job_type" binding:"Required"` | ||||
| BenchmarkCategory string `form:"get_benchmark_category"` | BenchmarkCategory string `form:"get_benchmark_category"` | ||||
| GpuType string `form:"gpu_type"` | GpuType string `form:"gpu_type"` | ||||
| ResourceSpecId int `form:"resource_spec_id" binding:"Required"` | |||||
| } | } | ||||
| type CommitImageCloudBrainForm struct { | type CommitImageCloudBrainForm struct { | ||||
| @@ -7,7 +7,7 @@ import ( | |||||
| type CreateModelArtsNotebookForm struct { | type CreateModelArtsNotebookForm struct { | ||||
| JobName string `form:"job_name" binding:"Required"` | JobName string `form:"job_name" binding:"Required"` | ||||
| Attachment string `form:"attachment" binding:"Required"` | |||||
| Attachment string `form:"attachment"` | |||||
| Description string `form:"description"` | Description string `form:"description"` | ||||
| } | } | ||||
| @@ -23,12 +23,29 @@ const ( | |||||
| Success = "S000" | Success = "S000" | ||||
| ) | ) | ||||
| func GenerateTask(ctx *context.Context, jobName, image, command, uuid, codePath, modelPath, benchmarkPath, snn4imagenetPath, jobType, gpuQueue string) error { | |||||
| var ( | |||||
| ResourceSpecs *models.ResourceSpecs | |||||
| ) | |||||
| func GenerateTask(ctx *context.Context, jobName, image, command, uuid, codePath, modelPath, benchmarkPath, snn4imagenetPath, jobType, gpuQueue string, resourceSpecId int) error { | |||||
| dataActualPath := setting.Attachment.Minio.RealPath + | dataActualPath := setting.Attachment.Minio.RealPath + | ||||
| setting.Attachment.Minio.Bucket + "/" + | setting.Attachment.Minio.Bucket + "/" + | ||||
| setting.Attachment.Minio.BasePath + | setting.Attachment.Minio.BasePath + | ||||
| models.AttachmentRelativePath(uuid) + | models.AttachmentRelativePath(uuid) + | ||||
| uuid | uuid | ||||
| var resourceSpec *models.ResourceSpec | |||||
| for _, spec := range ResourceSpecs.ResourceSpec { | |||||
| if resourceSpecId == spec.Id { | |||||
| resourceSpec = spec | |||||
| } | |||||
| } | |||||
| if resourceSpec == nil { | |||||
| log.Error("no such resourceSpecId(%d)", resourceSpecId, ctx.Data["MsgID"]) | |||||
| return errors.New("no such resourceSpec") | |||||
| } | |||||
| jobResult, err := CreateJob(jobName, models.CreateJobParams{ | jobResult, err := CreateJob(jobName, models.CreateJobParams{ | ||||
| JobName: jobName, | JobName: jobName, | ||||
| RetryCount: 1, | RetryCount: 1, | ||||
| @@ -40,10 +57,10 @@ func GenerateTask(ctx *context.Context, jobName, image, command, uuid, codePath, | |||||
| TaskNumber: 1, | TaskNumber: 1, | ||||
| MinSucceededTaskCount: 1, | MinSucceededTaskCount: 1, | ||||
| MinFailedTaskCount: 1, | MinFailedTaskCount: 1, | ||||
| CPUNumber: 2, | |||||
| GPUNumber: 1, | |||||
| MemoryMB: 16384, | |||||
| ShmMB: 8192, | |||||
| CPUNumber: resourceSpec.CpuNum, | |||||
| GPUNumber: resourceSpec.GpuNum, | |||||
| MemoryMB: resourceSpec.MemMiB, | |||||
| ShmMB: resourceSpec.ShareMemMiB, | |||||
| Command: command, | Command: command, | ||||
| NeedIBDevice: false, | NeedIBDevice: false, | ||||
| IsMainRole: false, | IsMainRole: false, | ||||
| @@ -1,8 +1,11 @@ | |||||
| package cloudbrain | package cloudbrain | ||||
| import ( | import ( | ||||
| "code.gitea.io/gitea/modules/log" | |||||
| "encoding/json" | |||||
| "fmt" | "fmt" | ||||
| "strings" | |||||
| "code.gitea.io/gitea/modules/log" | |||||
| "code.gitea.io/gitea/models" | "code.gitea.io/gitea/models" | ||||
| "code.gitea.io/gitea/modules/setting" | "code.gitea.io/gitea/modules/setting" | ||||
| @@ -10,13 +13,16 @@ import ( | |||||
| ) | ) | ||||
| var ( | var ( | ||||
| restyClient *resty.Client | |||||
| HOST string | |||||
| TOKEN string | |||||
| restyClient *resty.Client | |||||
| HOST string | |||||
| TOKEN string | |||||
| ImagesUrlMap = map[string]string{Public: "/rest-server/api/v1/image/public/list/", Custom: "/rest-server/api/v1/image/list/"} | |||||
| ) | ) | ||||
| const ( | const ( | ||||
| JobHasBeenStopped = "S410" | JobHasBeenStopped = "S410" | ||||
| Public = "public" | |||||
| Custom = "custom" | |||||
| ) | ) | ||||
| func getRestyClient() *resty.Client { | func getRestyClient() *resty.Client { | ||||
| @@ -76,6 +82,12 @@ sendjob: | |||||
| Post(HOST + "/rest-server/api/v1/jobs/") | Post(HOST + "/rest-server/api/v1/jobs/") | ||||
| if err != nil { | if err != nil { | ||||
| if res != nil { | |||||
| var response models.CloudBrainResult | |||||
| json.Unmarshal(res.Body(), &response) | |||||
| log.Error("code(%s), msg(%s)", response.Code, response.Msg) | |||||
| return nil, fmt.Errorf(response.Msg) | |||||
| } | |||||
| return nil, fmt.Errorf("resty create job: %s", err) | return nil, fmt.Errorf("resty create job: %s", err) | ||||
| } | } | ||||
| @@ -125,6 +137,16 @@ sendjob: | |||||
| } | } | ||||
| func GetImages() (*models.GetImagesResult, error) { | func GetImages() (*models.GetImagesResult, error) { | ||||
| return GetImagesPageable(1, 100, Custom, "") | |||||
| } | |||||
| func GetPublicImages() (*models.GetImagesResult, error) { | |||||
| return GetImagesPageable(1, 100, Public, "") | |||||
| } | |||||
| func GetImagesPageable(page int, size int, imageType string, name string) (*models.GetImagesResult, error) { | |||||
| checkSetting() | checkSetting() | ||||
| client := getRestyClient() | client := getRestyClient() | ||||
| var getImagesResult models.GetImagesResult | var getImagesResult models.GetImagesResult | ||||
| @@ -135,57 +157,51 @@ sendjob: | |||||
| res, err := client.R(). | res, err := client.R(). | ||||
| SetHeader("Content-Type", "application/json"). | SetHeader("Content-Type", "application/json"). | ||||
| SetAuthToken(TOKEN). | SetAuthToken(TOKEN). | ||||
| SetQueryString("pageIndex=1&pageSize=100"). | |||||
| SetQueryString(getQueryString(page, size, name)). | |||||
| SetResult(&getImagesResult). | SetResult(&getImagesResult). | ||||
| Get(HOST + "/rest-server/api/v1/image/list/") | |||||
| Get(HOST + ImagesUrlMap[imageType]) | |||||
| if err != nil { | if err != nil { | ||||
| return nil, fmt.Errorf("resty GetImages: %v", err) | return nil, fmt.Errorf("resty GetImages: %v", err) | ||||
| } | } | ||||
| if getImagesResult.Code == "S401" && retry < 1 { | |||||
| var response models.CloudBrainResult | |||||
| err = json.Unmarshal(res.Body(), &response) | |||||
| if err != nil { | |||||
| log.Error("json.Unmarshal failed: %s", err.Error()) | |||||
| return &getImagesResult, fmt.Errorf("json.Unmarshal failed: %s", err.Error()) | |||||
| } | |||||
| if response.Code == "S401" && retry < 1 { | |||||
| retry++ | retry++ | ||||
| _ = loginCloudbrain() | _ = loginCloudbrain() | ||||
| goto sendjob | goto sendjob | ||||
| } | } | ||||
| if getImagesResult.Code != Success { | if getImagesResult.Code != Success { | ||||
| return &getImagesResult, fmt.Errorf("getImgesResult err: %s", res.String()) | |||||
| return &getImagesResult, fmt.Errorf("getImagesResult err: %s", res.String()) | |||||
| } | } | ||||
| getImagesResult.Payload.TotalPages = getTotalPages(getImagesResult, size) | |||||
| return &getImagesResult, nil | return &getImagesResult, nil | ||||
| } | } | ||||
| func GetPublicImages() (*models.GetImagesResult, error) { | |||||
| checkSetting() | |||||
| client := getRestyClient() | |||||
| var getImagesResult models.GetImagesResult | |||||
| retry := 0 | |||||
| sendjob: | |||||
| res, err := client.R(). | |||||
| SetHeader("Content-Type", "application/json"). | |||||
| SetAuthToken(TOKEN). | |||||
| SetQueryString("pageIndex=1&pageSize=100"). | |||||
| SetResult(&getImagesResult). | |||||
| Get(HOST + "/rest-server/api/v1/image/public/list/") | |||||
| if err != nil { | |||||
| return nil, fmt.Errorf("resty GetPublicImages: %v", err) | |||||
| } | |||||
| if getImagesResult.Code == "S401" && retry < 1 { | |||||
| retry++ | |||||
| _ = loginCloudbrain() | |||||
| goto sendjob | |||||
| func getTotalPages(getImagesResult models.GetImagesResult, size int) int { | |||||
| totalCount := getImagesResult.Payload.Count | |||||
| var totalPages int | |||||
| if totalCount%size != 0 { | |||||
| totalPages = totalCount/size + 1 | |||||
| } else { | |||||
| totalPages = totalCount / size | |||||
| } | } | ||||
| return totalPages | |||||
| } | |||||
| if getImagesResult.Code != Success { | |||||
| return &getImagesResult, fmt.Errorf("getImgesResult err: %s", res.String()) | |||||
| func getQueryString(page int, size int, name string) string { | |||||
| if strings.TrimSpace(name) == "" { | |||||
| return fmt.Sprintf("pageIndex=%d&pageSize=%d", page, size) | |||||
| } | } | ||||
| return &getImagesResult, nil | |||||
| return fmt.Sprintf("pageIndex=%d&pageSize=%d&name=%s", page, size, name) | |||||
| } | } | ||||
| func CommitImage(jobID string, params models.CommitImageParams) error { | func CommitImage(jobID string, params models.CommitImageParams) error { | ||||
| @@ -223,7 +239,7 @@ sendjob: | |||||
| func StopJob(jobID string) error { | func StopJob(jobID string) error { | ||||
| checkSetting() | checkSetting() | ||||
| client := getRestyClient() | client := getRestyClient() | ||||
| var result models.StopJobResult | |||||
| var result models.CloudBrainResult | |||||
| retry := 0 | retry := 0 | ||||
| @@ -26,6 +26,7 @@ type ToggleOptions struct { | |||||
| AdminRequired bool | AdminRequired bool | ||||
| DisableCSRF bool | DisableCSRF bool | ||||
| BasicAuthRequired bool | BasicAuthRequired bool | ||||
| OperationRequired bool | |||||
| } | } | ||||
| // Toggle returns toggle options as middleware | // Toggle returns toggle options as middleware | ||||
| @@ -142,6 +143,15 @@ func Toggle(options *ToggleOptions) macaron.Handler { | |||||
| return | return | ||||
| } | } | ||||
| } | } | ||||
| if options.OperationRequired { | |||||
| //todo: add isOperator judgement | |||||
| if !ctx.User.IsAdmin { | |||||
| ctx.Error(403) | |||||
| return | |||||
| } | |||||
| ctx.Data["PageIsOperation"] = true | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -335,6 +335,7 @@ func ToUser(user *models.User, signed, authed bool) *api.User { | |||||
| AvatarURL: user.AvatarLink(), | AvatarURL: user.AvatarLink(), | ||||
| FullName: markup.Sanitize(user.FullName), | FullName: markup.Sanitize(user.FullName), | ||||
| Created: user.CreatedUnix.AsTime(), | Created: user.CreatedUnix.AsTime(), | ||||
| IsActive: user.IsActive, | |||||
| } | } | ||||
| // hide primary email if API caller is anonymous or user keep email private | // hide primary email if API caller is anonymous or user keep email private | ||||
| if signed && (!user.KeepEmailPrivate || authed) { | if signed && (!user.KeepEmailPrivate || authed) { | ||||
| @@ -434,3 +434,38 @@ func GetDivergingCommits(repoPath string, baseBranch string, targetBranch string | |||||
| return DivergeObject{ahead, behind}, nil | return DivergeObject{ahead, behind}, nil | ||||
| } | } | ||||
| type Contributor struct { | |||||
| CommitCnt int | |||||
| Committer string | |||||
| Email string | |||||
| } | |||||
| func GetContributors(repoPath string) ([]Contributor, error){ | |||||
| cmd := NewCommand("shortlog", "-sne", "--all") | |||||
| stdout, err := cmd.RunInDir(repoPath) | |||||
| if err != nil { | |||||
| return nil, err | |||||
| } | |||||
| stdout = strings.Trim(stdout, "\n") | |||||
| contributorRows := strings.Split(stdout, "\n") | |||||
| if len(contributorRows) > 0 { | |||||
| contributorsInfo := make([]Contributor, len(contributorRows)) | |||||
| for i := 0; i < len(contributorRows); i++ { | |||||
| var oneCount string = strings.Trim(contributorRows[i], " ") | |||||
| if strings.Index(oneCount, "\t") < 0 { | |||||
| continue | |||||
| } | |||||
| number := oneCount[0:strings.Index(oneCount, "\t")] | |||||
| commitCnt, _ := strconv.Atoi(number) | |||||
| committer := oneCount[strings.Index(oneCount, "\t")+1:strings.LastIndex(oneCount, " ")] | |||||
| committer = strings.Trim(committer, " ") | |||||
| email := oneCount[strings.Index(oneCount, "<")+1:strings.Index(oneCount, ">")] | |||||
| contributorsInfo[i] = Contributor{ | |||||
| commitCnt, committer, email, | |||||
| } | |||||
| } | |||||
| return contributorsInfo, nil | |||||
| } | |||||
| return nil, nil | |||||
| } | |||||
| @@ -0,0 +1,27 @@ | |||||
| package labelmsg | |||||
| import ( | |||||
| "code.gitea.io/gitea/modules/log" | |||||
| "code.gitea.io/gitea/modules/setting" | |||||
| redigo "github.com/gomodule/redigo/redis" | |||||
| ) | |||||
| var pool *redigo.Pool | |||||
| func Init() { | |||||
| redisBroker := setting.Broker | |||||
| pool_size := 20 | |||||
| log.Info("start to connect redis.") | |||||
| pool = redigo.NewPool(func() (redigo.Conn, error) { | |||||
| c, err := redigo.DialURL(redisBroker) | |||||
| if err != nil { | |||||
| return nil, err | |||||
| } | |||||
| return c, nil | |||||
| }, pool_size) | |||||
| } | |||||
| func Get() redigo.Conn { | |||||
| return pool.Get() | |||||
| } | |||||
| @@ -0,0 +1,57 @@ | |||||
| package labelmsg | |||||
| import ( | |||||
| "code.gitea.io/gitea/modules/log" | |||||
| "code.gitea.io/gitea/modules/setting" | |||||
| ) | |||||
| // 方法名 | |||||
| func SendAddAttachToLabelSys(attach string) error { | |||||
| redisclient := Get() | |||||
| //记得销毁本次链连接 | |||||
| defer redisclient.Close() | |||||
| _, err := redisclient.Do("Publish", setting.LabelTaskName, attach) | |||||
| if err != nil { | |||||
| log.Critical("redis Publish failed.") | |||||
| } | |||||
| log.Info("LabelRedisQueue(%s) success", attach) | |||||
| return nil | |||||
| } | |||||
| func SendDeleteAttachToLabelSys(attach string) error { | |||||
| redisclient := Get() | |||||
| //记得销毁本次链连接 | |||||
| defer redisclient.Close() | |||||
| _, err := redisclient.Do("Publish", setting.LabelDatasetDeleteQueue, attach) | |||||
| if err != nil { | |||||
| log.Critical("redis Publish failed.") | |||||
| } | |||||
| log.Info("LabelDatasetDeleteQueue(%s) success", attach) | |||||
| return nil | |||||
| } | |||||
| func SendDecompressAttachToLabelOBS(attach string) error { | |||||
| redisclient := Get() | |||||
| //记得销毁本次链连接 | |||||
| defer redisclient.Close() | |||||
| _, err := redisclient.Do("Publish", setting.DecompressOBSTaskName, attach) | |||||
| if err != nil { | |||||
| log.Critical("redis Publish failed.") | |||||
| } | |||||
| log.Info("LabelDecompressOBSQueue(%s) success", attach) | |||||
| return nil | |||||
| } | |||||
| @@ -1,6 +1,7 @@ | |||||
| package modelarts | package modelarts | ||||
| import ( | import ( | ||||
| "encoding/json" | |||||
| "path" | "path" | ||||
| "strconv" | "strconv" | ||||
| @@ -8,18 +9,13 @@ import ( | |||||
| "code.gitea.io/gitea/modules/context" | "code.gitea.io/gitea/modules/context" | ||||
| "code.gitea.io/gitea/modules/log" | "code.gitea.io/gitea/modules/log" | ||||
| "code.gitea.io/gitea/modules/setting" | "code.gitea.io/gitea/modules/setting" | ||||
| "code.gitea.io/gitea/modules/storage" | |||||
| ) | ) | ||||
| const ( | const ( | ||||
| //notebook | //notebook | ||||
| storageTypeOBS = "obs" | storageTypeOBS = "obs" | ||||
| autoStopDuration = 4 * 60 * 60 | autoStopDuration = 4 * 60 * 60 | ||||
| flavor = "modelarts.kat1.xlarge" | |||||
| //profileID = "Python3-ascend910-arm" | |||||
| profileID = "efa847c0-7359-11eb-b34f-0255ac100057" | |||||
| poolID = "pool1328035d" | |||||
| poolName = "train-private-1" | |||||
| poolType = "USER_DEFINED" | |||||
| DataSetMountPath = "/home/ma-user/work" | DataSetMountPath = "/home/ma-user/work" | ||||
| NotebookEnv = "Python3" | NotebookEnv = "Python3" | ||||
| @@ -54,6 +50,11 @@ const ( | |||||
| ConfigTypeCustom = "custom" | ConfigTypeCustom = "custom" | ||||
| ) | ) | ||||
| var ( | |||||
| poolInfos *models.PoolInfos | |||||
| FlavorInfos *models.FlavorInfos | |||||
| ) | |||||
| type GenerateTrainJobReq struct { | type GenerateTrainJobReq struct { | ||||
| JobName string | JobName string | ||||
| Uuid string | Uuid string | ||||
| @@ -99,16 +100,39 @@ type ResourcePool struct { | |||||
| } | } | ||||
| func GenerateTask(ctx *context.Context, jobName, uuid, description string) error { | func GenerateTask(ctx *context.Context, jobName, uuid, description string) error { | ||||
| dataActualPath := setting.Bucket + "/" + setting.BasePath + path.Join(uuid[0:1], uuid[1:2]) + "/" + uuid + "/" | |||||
| jobResult, err := createNotebook(models.CreateNotebookParams{ | |||||
| var dataActualPath string | |||||
| if uuid != "" { | |||||
| dataActualPath = setting.Bucket + "/" + setting.BasePath + path.Join(uuid[0:1], uuid[1:2]) + "/" + uuid + "/" | |||||
| } else { | |||||
| userPath := setting.UserBasePath + ctx.User.Name + "/" | |||||
| isExist, err := storage.ObsHasObject(userPath) | |||||
| if err != nil { | |||||
| log.Error("ObsHasObject failed:%v", err.Error(), ctx.Data["MsgID"]) | |||||
| return err | |||||
| } | |||||
| if !isExist { | |||||
| if err = storage.ObsCreateObject(userPath); err != nil { | |||||
| log.Error("ObsCreateObject failed:%v", err.Error(), ctx.Data["MsgID"]) | |||||
| return err | |||||
| } | |||||
| } | |||||
| dataActualPath = setting.Bucket + "/" + userPath | |||||
| } | |||||
| if poolInfos == nil { | |||||
| json.Unmarshal([]byte(setting.PoolInfos), &poolInfos) | |||||
| } | |||||
| jobResult, err := CreateJob(models.CreateNotebookParams{ | |||||
| JobName: jobName, | JobName: jobName, | ||||
| Description: description, | Description: description, | ||||
| ProfileID: profileID, | |||||
| Flavor: flavor, | |||||
| ProfileID: setting.ProfileID, | |||||
| Flavor: setting.Flavor, | |||||
| Pool: models.Pool{ | Pool: models.Pool{ | ||||
| ID: poolID, | |||||
| Name: poolName, | |||||
| Type: poolType, | |||||
| ID: poolInfos.PoolInfo[0].PoolId, | |||||
| Name: poolInfos.PoolInfo[0].PoolName, | |||||
| Type: poolInfos.PoolInfo[0].PoolType, | |||||
| }, | }, | ||||
| Spec: models.Spec{ | Spec: models.Spec{ | ||||
| Storage: models.Storage{ | Storage: models.Storage{ | ||||
| @@ -431,6 +431,11 @@ var ( | |||||
| AuthUser string | AuthUser string | ||||
| AuthPassword string | AuthPassword string | ||||
| //labelsystem config | |||||
| LabelTaskName string | |||||
| LabelDatasetDeleteQueue string | |||||
| DecompressOBSTaskName string | |||||
| //cloudbrain config | //cloudbrain config | ||||
| CBAuthUser string | CBAuthUser string | ||||
| CBAuthPassword string | CBAuthPassword string | ||||
| @@ -439,6 +444,7 @@ var ( | |||||
| JobType string | JobType string | ||||
| GpuTypes string | GpuTypes string | ||||
| DebugServerHost string | DebugServerHost string | ||||
| ResourceSpecs string | |||||
| //benchmark config | //benchmark config | ||||
| IsBenchmarkEnabled bool | IsBenchmarkEnabled bool | ||||
| @@ -462,7 +468,11 @@ var ( | |||||
| Bucket string | Bucket string | ||||
| Location string | Location string | ||||
| BasePath string | BasePath string | ||||
| <<<<<<< HEAD | |||||
| CodePathPrefix string | CodePathPrefix string | ||||
| ======= | |||||
| UserBasePath string | |||||
| >>>>>>> origin/develop | |||||
| //modelarts config | //modelarts config | ||||
| ModelArtsHost string | ModelArtsHost string | ||||
| @@ -472,7 +482,14 @@ var ( | |||||
| ModelArtsUsername string | ModelArtsUsername string | ||||
| ModelArtsPassword string | ModelArtsPassword string | ||||
| ModelArtsDomain string | ModelArtsDomain string | ||||
| <<<<<<< HEAD | |||||
| AllowedOrg string | AllowedOrg string | ||||
| ======= | |||||
| ProfileID string | |||||
| PoolInfos string | |||||
| Flavor string | |||||
| FlavorInfos string | |||||
| >>>>>>> origin/develop | |||||
| ) | ) | ||||
| // DateLang transforms standard language locale name to corresponding value in datetime plugin. | // DateLang transforms standard language locale name to corresponding value in datetime plugin. | ||||
| @@ -1141,6 +1158,11 @@ func NewContext() { | |||||
| AuthUser = sec.Key("USER").MustString("cW4cMtH24eoWPE7X") | AuthUser = sec.Key("USER").MustString("cW4cMtH24eoWPE7X") | ||||
| AuthPassword = sec.Key("PASSWORD").MustString("4BPmgvK2hb2Eywwyp4YZRY4B7yQf4DAC") | AuthPassword = sec.Key("PASSWORD").MustString("4BPmgvK2hb2Eywwyp4YZRY4B7yQf4DAC") | ||||
| sec = Cfg.Section("labelsystem") | |||||
| LabelTaskName = sec.Key("LabelTaskName").MustString("LabelRedisQueue") | |||||
| LabelDatasetDeleteQueue = sec.Key("LabelDatasetDeleteQueue").MustString("LabelDatasetDeleteQueue") | |||||
| DecompressOBSTaskName = sec.Key("DecompressOBSTaskName").MustString("LabelDecompressOBSQueue") | |||||
| sec = Cfg.Section("cloudbrain") | sec = Cfg.Section("cloudbrain") | ||||
| CBAuthUser = sec.Key("USER").MustString("cW4cMtH24eoWPE7X") | CBAuthUser = sec.Key("USER").MustString("cW4cMtH24eoWPE7X") | ||||
| CBAuthPassword = sec.Key("PWD").MustString("4BPmgvK2hb2Eywwyp4YZRY4B7yQf4DAC") | CBAuthPassword = sec.Key("PWD").MustString("4BPmgvK2hb2Eywwyp4YZRY4B7yQf4DAC") | ||||
| @@ -1148,7 +1170,8 @@ func NewContext() { | |||||
| JobPath = sec.Key("JOB_PATH").MustString("/datasets/minio/data/opendata/jobs/") | JobPath = sec.Key("JOB_PATH").MustString("/datasets/minio/data/opendata/jobs/") | ||||
| DebugServerHost = sec.Key("DEBUG_SERVER_HOST").MustString("http://192.168.202.73") | DebugServerHost = sec.Key("DEBUG_SERVER_HOST").MustString("http://192.168.202.73") | ||||
| JobType = sec.Key("GPU_TYPE_DEFAULT").MustString("openidebug") | JobType = sec.Key("GPU_TYPE_DEFAULT").MustString("openidebug") | ||||
| GpuTypes = sec.Key("GPU_TYPES").MustString("openidebug,openidgx") | |||||
| GpuTypes = sec.Key("GPU_TYPES").MustString("") | |||||
| ResourceSpecs = sec.Key("RESOURCE_SPECS").MustString("") | |||||
| sec = Cfg.Section("benchmark") | sec = Cfg.Section("benchmark") | ||||
| IsBenchmarkEnabled = sec.Key("ENABLED").MustBool(false) | IsBenchmarkEnabled = sec.Key("ENABLED").MustBool(false) | ||||
| @@ -1172,7 +1195,11 @@ func NewContext() { | |||||
| Bucket = sec.Key("BUCKET").MustString("testopendata") | Bucket = sec.Key("BUCKET").MustString("testopendata") | ||||
| Location = sec.Key("LOCATION").MustString("cn-south-222") | Location = sec.Key("LOCATION").MustString("cn-south-222") | ||||
| BasePath = sec.Key("BASE_PATH").MustString("attachment/") | BasePath = sec.Key("BASE_PATH").MustString("attachment/") | ||||
| <<<<<<< HEAD | |||||
| CodePathPrefix = sec.Key("CODE_PATH_PREFIX").MustString("code/") | CodePathPrefix = sec.Key("CODE_PATH_PREFIX").MustString("code/") | ||||
| ======= | |||||
| UserBasePath = sec.Key("BASE_PATH_USER").MustString("users/") | |||||
| >>>>>>> origin/develop | |||||
| sec = Cfg.Section("modelarts") | sec = Cfg.Section("modelarts") | ||||
| ModelArtsHost = sec.Key("ENDPOINT").MustString("112.95.163.80") | ModelArtsHost = sec.Key("ENDPOINT").MustString("112.95.163.80") | ||||
| @@ -1182,7 +1209,14 @@ func NewContext() { | |||||
| ModelArtsUsername = sec.Key("USERNAME").MustString("") | ModelArtsUsername = sec.Key("USERNAME").MustString("") | ||||
| ModelArtsPassword = sec.Key("PASSWORD").MustString("") | ModelArtsPassword = sec.Key("PASSWORD").MustString("") | ||||
| ModelArtsDomain = sec.Key("DOMAIN").MustString("cn-south-222") | ModelArtsDomain = sec.Key("DOMAIN").MustString("cn-south-222") | ||||
| <<<<<<< HEAD | |||||
| AllowedOrg = sec.Key("ORGANIZATION").MustString("") | AllowedOrg = sec.Key("ORGANIZATION").MustString("") | ||||
| ======= | |||||
| ProfileID = sec.Key("PROFILE_ID").MustString("") | |||||
| PoolInfos = sec.Key("POOL_INFOS").MustString("") | |||||
| Flavor = sec.Key("FLAVOR").MustString("") | |||||
| FlavorInfos = sec.Key("FLAVOR_INFOS").MustString("") | |||||
| >>>>>>> origin/develop | |||||
| } | } | ||||
| func loadInternalToken(sec *ini.Section) string { | func loadInternalToken(sec *ini.Section) string { | ||||
| @@ -5,11 +5,12 @@ | |||||
| package storage | package storage | ||||
| import ( | import ( | ||||
| "github.com/unknwon/com" | |||||
| "path" | "path" | ||||
| "strconv" | "strconv" | ||||
| "strings" | "strings" | ||||
| "github.com/unknwon/com" | |||||
| "code.gitea.io/gitea/modules/log" | "code.gitea.io/gitea/modules/log" | ||||
| "code.gitea.io/gitea/modules/obs" | "code.gitea.io/gitea/modules/obs" | ||||
| "code.gitea.io/gitea/modules/setting" | "code.gitea.io/gitea/modules/setting" | ||||
| @@ -144,9 +145,16 @@ func ObsGetPreSignedUrl(uuid, fileName string) (string, error) { | |||||
| return output.SignedUrl, nil | return output.SignedUrl, nil | ||||
| } | } | ||||
| func ObsUploadFileFolder(fileFolder string) error { | |||||
| input := &obs.PutFileInput{} | |||||
| input.Key = "" | |||||
| func ObsCreateObject(path string) error { | |||||
| input := &obs.PutObjectInput{} | |||||
| input.Bucket = setting.Bucket | input.Bucket = setting.Bucket | ||||
| input.Key = path | |||||
| _, err := ObsCli.PutObject(input) | |||||
| if err != nil { | |||||
| log.Error("PutObject failed:", err.Error()) | |||||
| return err | |||||
| } | |||||
| return nil | return nil | ||||
| } | } | ||||
| @@ -26,6 +26,8 @@ type User struct { | |||||
| Language string `json:"language"` | Language string `json:"language"` | ||||
| // Is the user an administrator | // Is the user an administrator | ||||
| IsAdmin bool `json:"is_admin"` | IsAdmin bool `json:"is_admin"` | ||||
| // Is the user active | |||||
| IsActive bool `json:"is_active"` | |||||
| // swagger:strfmt date-time | // swagger:strfmt date-time | ||||
| LastLogin time.Time `json:"last_login,omitempty"` | LastLogin time.Time `json:"last_login,omitempty"` | ||||
| // swagger:strfmt date-time | // swagger:strfmt date-time | ||||
| @@ -1,4 +1,5 @@ | |||||
| home = Home | home = Home | ||||
| index = Home | |||||
| dashboard = Dashboard | dashboard = Dashboard | ||||
| explore = Explore | explore = Explore | ||||
| datasets = Datasets | datasets = Datasets | ||||
| @@ -86,8 +87,10 @@ write = Write | |||||
| preview = Preview | preview = Preview | ||||
| loading = Loading… | loading = Loading… | ||||
| error404_index = Request forbidden by administrative rules | |||||
| error500_index = Internal Server Error | |||||
| error404 = The page you are trying to reach either <strong>does not exist</strong> or <strong>you are not authorized</strong> to view it. | error404 = The page you are trying to reach either <strong>does not exist</strong> or <strong>you are not authorized</strong> to view it. | ||||
| error500= Sorry, the site has encountered some problems, we are trying to <strong>fix the page</strong>, please try again later. | |||||
| [error] | [error] | ||||
| occurred = An error has occurred | occurred = An error has occurred | ||||
| report_message = An error has occurred | report_message = An error has occurred | ||||
| @@ -220,6 +223,7 @@ issues.in_your_repos = In your repositories | |||||
| repos = Repositories | repos = Repositories | ||||
| users = Users | users = Users | ||||
| organizations = Organizations | organizations = Organizations | ||||
| images = CloudImages | |||||
| search = Search | search = Search | ||||
| code = Code | code = Code | ||||
| repo_no_results = No matching repositories found. | repo_no_results = No matching repositories found. | ||||
| @@ -643,7 +647,8 @@ public = public | |||||
| dir = directory | dir = directory | ||||
| back = back | back = back | ||||
| copy_url=copy download url | copy_url=copy download url | ||||
| directory=check directory of the datasets | |||||
| directory=preview of the datasets | |||||
| create_label_task=create label task | |||||
| visibility = visibility | visibility = visibility | ||||
| visibility_description = Only the owner or the organization members if they have rights, will be able to see it. | visibility_description = Only the owner or the organization members if they have rights, will be able to see it. | ||||
| visibility_helper = Make Dataset Private | visibility_helper = Make Dataset Private | ||||
| @@ -702,6 +707,7 @@ delete= delete | |||||
| owner = Owner | owner = Owner | ||||
| repo_name = Repository Name | repo_name = Repository Name | ||||
| repo_name_helper = Good repository names use short, memorable and unique keywords. | repo_name_helper = Good repository names use short, memorable and unique keywords. | ||||
| repo_owner_helper = Some organizations may not show up in the dropdown due to a maximum repository count limit. | |||||
| repo_size = Repository Size | repo_size = Repository Size | ||||
| template = Template | template = Template | ||||
| template_select = Select a template. | template_select = Select a template. | ||||
| @@ -763,6 +769,7 @@ cloudbrain2 = cloudbrain2 | |||||
| cloudbrain_selection = select cloudbrain | cloudbrain_selection = select cloudbrain | ||||
| cloudbrain_platform_selection = Select the cloudbrain platform you want to use: | cloudbrain_platform_selection = Select the cloudbrain platform you want to use: | ||||
| confirm_choice = confirm | confirm_choice = confirm | ||||
| cloudbran1_tips = Only data in zip format can create cloudbrain tasks | |||||
| template.items = Template Items | template.items = Template Items | ||||
| template.git_content = Git Content (Default Branch) | template.git_content = Git Content (Default Branch) | ||||
| @@ -1809,7 +1816,7 @@ branch.included = Included | |||||
| topic.manage_topics = Manage Topics | topic.manage_topics = Manage Topics | ||||
| topic.done = Done | topic.done = Done | ||||
| topic.count_prompt = You can not select more than 25 topics | topic.count_prompt = You can not select more than 25 topics | ||||
| topic.format_prompt = Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long. | |||||
| topic.format_prompt = Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long. | |||||
| [org] | [org] | ||||
| org_name_holder = Organization Name | org_name_holder = Organization Name | ||||
| @@ -1817,6 +1824,7 @@ org_full_name_holder = Organization Full Name | |||||
| org_name_helper = Organization names should be short and memorable. | org_name_helper = Organization names should be short and memorable. | ||||
| create_org = Create Organization | create_org = Create Organization | ||||
| repo_updated = Updated | repo_updated = Updated | ||||
| home = Home | |||||
| people = People | people = People | ||||
| teams = Teams | teams = Teams | ||||
| lower_members = members | lower_members = members | ||||
| @@ -2482,9 +2490,9 @@ error.unit_not_allowed = You are not allowed to access this repository section. | |||||
| [custom] | [custom] | ||||
| head.community = Community | head.community = Community | ||||
| head.project = Project | |||||
| head.project = Repositories | |||||
| head.openi = OpenI | head.openi = OpenI | ||||
| head.dataset = Dataset | |||||
| head.dataset = Datasets | |||||
| foot.council = Council | foot.council = Council | ||||
| foot.technical_committee = Technical Committee | foot.technical_committee = Technical Committee | ||||
| foot.join = Join OpenI | foot.join = Join OpenI | ||||
| @@ -1,5 +1,5 @@ | |||||
| home=个人中心 | home=个人中心 | ||||
| index=首页 | |||||
| index=个人中心 | |||||
| dashboard=个人中心 | dashboard=个人中心 | ||||
| explore=探索 | explore=探索 | ||||
| datasets=数据集 | datasets=数据集 | ||||
| @@ -87,7 +87,10 @@ write=撰写 | |||||
| preview=预览 | preview=预览 | ||||
| loading=正在加载... | loading=正在加载... | ||||
| error404_index = 您的访问受限! | |||||
| error500_index = 抱歉!您指定的网页无法访问。 | |||||
| error404=您正尝试访问的页面 <strong>不存在</strong> 或 <strong>您尚未被授权</strong> 查看该页面。 | error404=您正尝试访问的页面 <strong>不存在</strong> 或 <strong>您尚未被授权</strong> 查看该页面。 | ||||
| error500=抱歉,站点遇到一些问题,我们正尝试<strong>修复网页</strong>,请您稍后再试。 | |||||
| [error] | [error] | ||||
| occurred=发生错误 | occurred=发生错误 | ||||
| @@ -221,6 +224,7 @@ issues.in_your_repos=属于该用户项目的 | |||||
| repos=项目 | repos=项目 | ||||
| users=用户 | users=用户 | ||||
| organizations=组织 | organizations=组织 | ||||
| images = 云脑镜像 | |||||
| search=搜索 | search=搜索 | ||||
| code=代码 | code=代码 | ||||
| repo_no_results=未找到匹配的项目。 | repo_no_results=未找到匹配的项目。 | ||||
| @@ -287,7 +291,7 @@ email_domain_blacklisted=您不能使用您的电子邮件地址注册。 | |||||
| authorize_application=应用授权 | authorize_application=应用授权 | ||||
| authorize_redirect_notice=如果您授权此应用,您将会被重定向到 %s。 | authorize_redirect_notice=如果您授权此应用,您将会被重定向到 %s。 | ||||
| authorize_application_created_by=此应用由%s创建。 | authorize_application_created_by=此应用由%s创建。 | ||||
| authorize_application_description=如果您允许,它将能够读取和修改您的所有帐户信息,包括私人项目和组织。 | |||||
| authorize_application_description=如果您允许,它将能够读取您的个人信息。 | |||||
| authorize_title=授权 %s 访问您的帐户? | authorize_title=授权 %s 访问您的帐户? | ||||
| authorization_failed=授权失败 | authorization_failed=授权失败 | ||||
| authorization_failed_desc=授权失败,这是一个无效的请求。请联系尝试授权应用的管理员。 | authorization_failed_desc=授权失败,这是一个无效的请求。请联系尝试授权应用的管理员。 | ||||
| @@ -331,7 +335,7 @@ SSPIDefaultLanguage=默认语言 | |||||
| require_error=不能为空。 | require_error=不能为空。 | ||||
| alpha_dash_error=应该只包含字母数字、破折号 ('-') 和下划线 ('_') 字符。 | alpha_dash_error=应该只包含字母数字、破折号 ('-') 和下划线 ('_') 字符。 | ||||
| alpha_dash_dot_error=' 应该只包含字母数字, 破折号 ('-'), 下划线 ('_') 和点 ('. ') 。 | |||||
| alpha_dash_dot_error=应该只包含字母数字, 破折号 ('-'), 下划线 ('_') 和点 ('. ') 。 | |||||
| git_ref_name_error=` 必须是格式良好的 git 引用名称。` | git_ref_name_error=` 必须是格式良好的 git 引用名称。` | ||||
| size_error=长度必须为 %s。 | size_error=长度必须为 %s。 | ||||
| min_size_error=长度最小为 %s 个字符。 | min_size_error=长度最小为 %s 个字符。 | ||||
| @@ -475,7 +479,7 @@ add_new_email=添加新的邮箱地址 | |||||
| add_new_openid=添加新的 OpenID URI | add_new_openid=添加新的 OpenID URI | ||||
| add_email=增加电子邮件地址 | add_email=增加电子邮件地址 | ||||
| add_openid=添加 OpenID URI | add_openid=添加 OpenID URI | ||||
| add_email_confirmation_sent=一封新的确认邮件已经被发送至 <b>%s</b>,请检查您的收件箱并在 %s 内完成确认注册操作。 | |||||
| add_email_confirmation_sent=一封新的确认邮件已经被发送至 <b>%s</b>,请检查您的收件箱并在 %s 内完成确认操作。 | |||||
| add_email_success=新的电子邮件地址已添加。 | add_email_success=新的电子邮件地址已添加。 | ||||
| email_preference_set_success=电子邮件首选项已成功设置。 | email_preference_set_success=电子邮件首选项已成功设置。 | ||||
| add_openid_success=新的 OpenID 地址已添加。 | add_openid_success=新的 OpenID 地址已添加。 | ||||
| @@ -645,7 +649,8 @@ dir=目录 | |||||
| back=返回 | back=返回 | ||||
| copy_url=复制下载链接 | copy_url=复制下载链接 | ||||
| copy_md5=复制文件MD5 | copy_md5=复制文件MD5 | ||||
| directory=查看数据集目录结构 | |||||
| directory=数据集预览 | |||||
| create_label_task=创建标注任务 | |||||
| visibility=可见性 | visibility=可见性 | ||||
| visibility_description=只有组织所有人或拥有权利的组织成员才能看到。 | visibility_description=只有组织所有人或拥有权利的组织成员才能看到。 | ||||
| visibility_helper=将数据集设为私有 | visibility_helper=将数据集设为私有 | ||||
| @@ -704,6 +709,7 @@ delete=删除 | |||||
| owner=拥有者 | owner=拥有者 | ||||
| repo_name=项目名称 | repo_name=项目名称 | ||||
| repo_name_helper=好的存储库名称使用简短、深刻和独特的关键字。 | repo_name_helper=好的存储库名称使用简短、深刻和独特的关键字。 | ||||
| repo_owner_helper = 由于最大存储库数量限制,某些组织名称可能不会显示在下拉列表中。 | |||||
| repo_size=项目大小 | repo_size=项目大小 | ||||
| template=模板 | template=模板 | ||||
| template_select=选择模板 | template_select=选择模板 | ||||
| @@ -765,6 +771,7 @@ cloudbrain2=云脑2 | |||||
| cloudbrain_selection=云脑选择 | cloudbrain_selection=云脑选择 | ||||
| cloudbrain_platform_selection=选择您准备使用的云脑平台: | cloudbrain_platform_selection=选择您准备使用的云脑平台: | ||||
| confirm_choice=确定 | confirm_choice=确定 | ||||
| cloudbran1_tips=只有zip格式的数据集才能发起云脑任务 | |||||
| modelarts.notebook=调试作业 | modelarts.notebook=调试作业 | ||||
| modelarts.train_job=训练作业 | modelarts.train_job=训练作业 | ||||
| @@ -1857,7 +1864,7 @@ branch.included=已包含 | |||||
| topic.manage_topics=管理主题 | topic.manage_topics=管理主题 | ||||
| topic.done=保存 | topic.done=保存 | ||||
| topic.count_prompt=您最多选择25个主题 | topic.count_prompt=您最多选择25个主题 | ||||
| topic.format_prompt=主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符 | |||||
| topic.format_prompt=主题必须以中文、字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符 | |||||
| [org] | [org] | ||||
| org_name_holder=组织名称 | org_name_holder=组织名称 | ||||
| @@ -1865,6 +1872,7 @@ org_full_name_holder=组织全名 | |||||
| org_name_helper=组织名字应该简单明了。 | org_name_helper=组织名字应该简单明了。 | ||||
| create_org=创建组织 | create_org=创建组织 | ||||
| repo_updated=最后更新于 | repo_updated=最后更新于 | ||||
| home=组织主页 | |||||
| people=组织成员 | people=组织成员 | ||||
| teams=组织团队 | teams=组织团队 | ||||
| lower_members=名成员 | lower_members=名成员 | ||||
| @@ -2528,7 +2536,7 @@ error.unit_not_allowed=您没有权限访问此项目单元 | |||||
| [custom] | [custom] | ||||
| head.community=启智社区 | head.community=启智社区 | ||||
| head.project=所有项目 | |||||
| head.project=项目 | |||||
| head.openi=启智项目 | head.openi=启智项目 | ||||
| head.dataset=数据集 | head.dataset=数据集 | ||||
| foot.council=理事会 | foot.council=理事会 | ||||
| @@ -19,6 +19,7 @@ | |||||
| "cssnano": "4.1.10", | "cssnano": "4.1.10", | ||||
| "domino": "2.1.5", | "domino": "2.1.5", | ||||
| "dropzone": "5.7.2", | "dropzone": "5.7.2", | ||||
| "element-ui": "2.15.5", | |||||
| "esdk-obs-browserjs": "3.20.7", | "esdk-obs-browserjs": "3.20.7", | ||||
| "esdk-obs-nodejs": "3.20.11", | "esdk-obs-nodejs": "3.20.11", | ||||
| "fast-glob": "3.2.2", | "fast-glob": "3.2.2", | ||||
| @@ -1 +0,0 @@ | |||||
| <svg clip-rule="evenodd" fill-rule="evenodd" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="m83.046 35.842c10.395-.091 22.52-.636 42.972-1.719 12.367.282-4.316 74.37-26.594 76.038h-37.152c-8.48-.911-19.934-18.203-21.002-23.216-9.735-.215-34.086-2.695-35.192-29.423-.707-17.106 12.085-23.932 21.632-23.904 3.736.01 7.213.478 9.708.505 19.935 1.104 30.433 1.729 42.366 1.733l.021 21.503 3.241 1.61zm18.936 34.047-31.267-15.193-15.192 31.267 31.267 15.192zm-71.781-26.813c-12.443-.333-15.784 7.423-14.833 14.834 1.782 13.885 11.469 17.605 22.851 19.11-4.462-12.24-6.666-20.251-8.018-33.944z" transform="matrix(.128847 0 0 .128847 -.779534 -1.26275)"/><g transform="matrix(.128847 0 0 .128847 -.779534 -1.26275)"><g transform="matrix(.940904 -.338674 .338674 .940904 0 0)"><circle cx="49.065" cy="90.078" r="3.475"/><circle cx="36.81" cy="102.105" r="3.475"/><circle cx="46.484" cy="111.439" r="3.475"/></g><path d="m97.333 18.062h2.673v27.261h-2.673z" transform="matrix(.898609 .43875 -.447723 .916987 .406685 -.832937)"/><path d="m76.558 68.116c12.976 6.396 13.013 4.102 4.891 20.908" fill="none" stroke="#000" stroke-width="2.68"/></g></svg> | |||||
| @@ -0,0 +1,17 @@ | |||||
| <svg clip-rule="evenodd" fill-rule="evenodd" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg"> | |||||
| <path class="st0" d="M54.7,15.9L34.8,4.5c-1.7-1-3.9-1-5.6,0L9.3,15.9c-1.8,1-2.8,2.9-2.8,4.9v22.8c0,2,1.1,3.9,2.8,4.9l4.9,2.8 | |||||
| c-0.1,0.2-0.1,0.5-0.1,0.7c0,2.1,1.6,3.8,3.7,3.8s3.8-1.6,3.8-3.7c0-2.1-1.6-3.8-3.7-3.8c-0.9,0-1.8,0.3-2.5,0.9l-4.9-2.8 | |||||
| c-1-0.6-1.6-1.7-1.6-2.9V20.9c0-1.2,0.6-2.3,1.6-2.9L30.3,6.5c1-0.6,2.3-0.6,3.3,0l19.8,11.4c1,0.6,1.7,1.7,1.6,2.9v22.8 | |||||
| c0,1.2-0.6,2.3-1.6,2.9L33.7,58c-0.2,0.1-0.4,0.2-0.6,0.3v-7.1c0-0.1,0-0.2,0-0.4v-4.1h0.1l11.4-7.6c0.3-0.2,0.5-0.6,0.5-1V25.9 | |||||
| c2-0.6,3.1-2.8,2.5-4.8c-0.6-2-2.8-3.1-4.8-2.5c-2,0.6-3.1,2.8-2.5,4.8c0.4,1.2,1.3,2.1,2.5,2.5v11.4L33,43.9V20.8 | |||||
| c2-0.6,3.1-2.8,2.5-4.8c-0.6-2-2.8-3.1-4.8-2.5c-2,0.6-3.1,2.8-2.5,4.8c0.4,1.2,1.3,2.1,2.5,2.5V36l-6.4-3.7v-6.1 | |||||
| c2-0.6,3.1-2.8,2.5-4.8c-0.6-2-2.8-3.1-4.8-2.5s-3.1,2.8-2.5,4.8c0.4,1.2,1.3,2.1,2.5,2.5v6.7c0,0.4,0.2,0.8,0.6,1l8.2,4.8V49 | |||||
| l-14.1-8.2v-10c2-0.6,3-2.7,2.4-4.7s-2.7-3-4.7-2.4c-2,0.6-3,2.7-2.4,4.7c0.4,1.1,1.3,2,2.4,2.4v10.7c0,0.4,0.2,0.8,0.6,1l15.8,9.1 | |||||
| v8c0,0,0,0.1,0,0.1v0.1V60c0,0,0,0,0,0.1l0.1,0.1l0,0l0.1,0.1l0,0c0,0,0.1,0.1,0.1,0.1l0,0l0.2,0.1l0,0h0.2l0,0c0.1,0,0.1,0,0.2,0 | |||||
| h0.2c1,0,2-0.3,2.8-0.7l19.8-11.4c1.8-0.9,2.9-2.7,3.1-4.7V20.9C57.5,18.9,56.4,17,54.7,15.9 M17.9,50.8c0.8,0,1.4,0.6,1.4,1.4 | |||||
| s-0.6,1.4-1.4,1.4s-1.4-0.6-1.4-1.4l0,0C16.5,51.4,17.1,50.8,17.9,50.8 M44,21c0.8,0,1.4,0.6,1.4,1.4c0,0.8-0.6,1.4-1.4,1.4 | |||||
| c-0.8,0-1.4-0.6-1.4-1.4l0,0C42.6,21.7,43.2,21,44,21 M23.1,21.3c0.8,0,1.4,0.6,1.4,1.4s-0.6,1.4-1.4,1.4c-0.8,0-1.4-0.6-1.4-1.4 | |||||
| S22.4,21.3,23.1,21.3L23.1,21.3 M15.5,25.9c0.8,0,1.4,0.6,1.4,1.4s-0.6,1.4-1.4,1.4c-0.8,0-1.4-0.6-1.4-1.4S14.7,25.9,15.5,25.9 | |||||
| L15.5,25.9 M31.9,15.8c0.8,0,1.4,0.6,1.4,1.4s-0.6,1.4-1.4,1.4c-0.8,0-1.4-0.6-1.4-1.4C30.4,16.4,31.1,15.8,31.9,15.8 | |||||
| C31.9,15.8,31.9,15.8,31.9,15.8"/> | |||||
| </svg> | |||||
| @@ -0,0 +1,117 @@ | |||||
| .yhh-data-table-frame{ | |||||
| color:inherit;font-family:inherit;font-size:14px;font-weight:normal; | |||||
| border:0;margin:0;padding:0;background-color:#FFFFFF; | |||||
| } | |||||
| /*table样式*/ | |||||
| .yhh-data-table-frame>table.yhh-data-table{ | |||||
| width:100%;border-collapse:collapse;border-spacing:0;empty-cells:show; | |||||
| } | |||||
| .yhh-data-table-frame>table.yhh-data-table td, | |||||
| .yhh-data-table-frame>table.yhh-data-table th{ | |||||
| vertical-align:middle;text-align:left;border:1px solid #DDDDDD; | |||||
| } | |||||
| .yhh-data-table-frame>table.yhh-data-table.dataTable-theme-a td, | |||||
| .yhh-data-table-frame>table.yhh-data-table.dataTable-theme-a th{ | |||||
| border:0; | |||||
| } | |||||
| .yhh-data-table-frame>table.yhh-data-table.dataTable-theme-a tr{ | |||||
| border-bottom:1px solid #DDDDDD; | |||||
| } | |||||
| .yhh-data-table-frame>table.yhh-data-table td{ | |||||
| background-color:#FFFFFF;color:inherit; | |||||
| } | |||||
| .yhh-data-table-frame>table.yhh-data-table th, | |||||
| .yhh-data-table-frame>table.yhh-data-table thead td, | |||||
| .yhh-data-table-frame>table.yhh-data-table tfoot td{ | |||||
| background-color:#DDDDDD;color:inherit;font-weight:bold; | |||||
| } | |||||
| .yhh-data-table-frame>table.yhh-data-table.dataTable-theme-a th, | |||||
| .yhh-data-table-frame>table.yhh-data-table.dataTable-theme-a thead td, | |||||
| .yhh-data-table-frame>table.yhh-data-table.dataTable-theme-a tfoot td{ | |||||
| background-color:#FFFFFF; | |||||
| } | |||||
| .yhh-data-table-frame>table.yhh-data-table tbody th, | |||||
| .yhh-data-table-frame>table.yhh-data-table tbody td{ | |||||
| padding:10px 10px; | |||||
| } | |||||
| .yhh-data-table-frame>table.yhh-data-table thead th, | |||||
| .yhh-data-table-frame>table.yhh-data-table thead td, | |||||
| .yhh-data-table-frame>table.yhh-data-table tfoot th, | |||||
| .yhh-data-table-frame>table.yhh-data-table tfoot td{ | |||||
| padding:10px 10px; | |||||
| } | |||||
| .yhh-data-table-frame>table.yhh-data-table tr.odd td{} | |||||
| .yhh-data-table-frame>table.yhh-data-table tr.even td{background-color:#F6F6F6;} | |||||
| .yhh-data-table-frame>table.yhh-data-table tr.hover-row td{ | |||||
| background-color:#F0F8FF;color:#00BFFF; | |||||
| } | |||||
| .yhh-data-table-frame>table.yhh-data-table tr.selected-row td{ | |||||
| background-color:#E6E6FA; | |||||
| } | |||||
| /*table上下功能行公共样式*/ | |||||
| .yhh-data-table-frame>.data-table-top-box, | |||||
| .yhh-data-table-frame>.data-table-bottom-box{ | |||||
| position:relative; | |||||
| } | |||||
| .yhh-data-table-frame>.data-table-top-box, | |||||
| .yhh-data-table-frame>.data-table-bottom-box, | |||||
| .yhh-data-table-frame>.data-table-top-box>.per-length-box, | |||||
| .yhh-data-table-frame>.data-table-bottom-box>.info-box, | |||||
| .yhh-data-table-frame>.data-table-bottom-box>.paginate-box{ | |||||
| height:35px; | |||||
| } | |||||
| .yhh-data-table-frame>.data-table-top-box>.per-length-box, | |||||
| .yhh-data-table-frame>.data-table-bottom-box>.info-box, | |||||
| .yhh-data-table-frame>.data-table-bottom-box>.paginate-box{ | |||||
| line-height:35px;position:absolute; | |||||
| } | |||||
| /*改变每页显示数目功能样式*/ | |||||
| .yhh-data-table-frame>.data-table-top-box>.per-length-box{ | |||||
| top:0;right:2px;padding-right:50px;z-index:8; | |||||
| } | |||||
| .yhh-data-table-frame>.data-table-top-box>.per-length-box>.per-length-select{ | |||||
| position:absolute;top:1.5px;right:0;width:50px;margin:0; | |||||
| } | |||||
| .yhh-data-table-frame>.data-table-top-box>.per-length-box dt.sel-choosen-box, | |||||
| .yhh-data-table-frame>.data-table-top-box>.per-length-box dd.sel-list{ | |||||
| border:1px solid #DDDDDD;border-radius:0; | |||||
| } | |||||
| .yhh-data-table-frame>.data-table-top-box>.per-length-box dt.sel-choosen-box{ | |||||
| height:30px;line-height:30px;cursor:pointer;background-color:#F0F8FF; | |||||
| position:relative;padding-right:13px;padding-left:8px; | |||||
| } | |||||
| .yhh-data-table-frame>.data-table-top-box>.per-length-box dt.sel-choosen-box.expand{ | |||||
| border-radius:0; | |||||
| } | |||||
| .yhh-data-table-frame>.data-table-top-box>.per-length-box dd.sel-list.expand{ | |||||
| border-radius:0;border-top:0;margin:0; | |||||
| } | |||||
| .yhh-data-table-frame>.data-table-top-box>.per-length-box i.sel-icon{ | |||||
| height:30px;line-height:30px;position:absolute;top:0;right:2px;color:#AAAAAA; | |||||
| } | |||||
| .yhh-data-table-frame>.data-table-top-box>.per-length-box dd.sel-list{ | |||||
| z-index:10;max-height:200px;height:auto; | |||||
| border-radius:0;border-top:0; | |||||
| } | |||||
| .yhh-data-table-frame>.data-table-top-box>.per-length-box .sel-option{ | |||||
| display:block;border-bottom:1px solid #CCCCCC;line-height:normal; | |||||
| background-color:#FFFFFF;padding:6.5px 0;padding-left:8px;cursor:pointer; | |||||
| } | |||||
| .yhh-data-table-frame>.data-table-top-box>.per-length-box .sel-option:hover{ | |||||
| background-color:#DDE4FE; | |||||
| } | |||||
| .yhh-data-table-frame>.data-table-top-box>.per-length-box .sel-option:active{ | |||||
| background-color:#DA70D6; | |||||
| } | |||||
| .yhh-data-table-frame>.data-table-top-box>.per-length-box .sel-option.last-option{ | |||||
| border-bottom:0; | |||||
| } | |||||
| /*显示数据信息功能样式*/ | |||||
| .yhh-data-table-frame>.data-table-bottom-box>.info-box{ | |||||
| top:0;left:2px; | |||||
| } | |||||
| .yhh-data-table-frame>.data-table-bottom-box>.info-box .info-num{color:#F5A523;padding:0 5px;} | |||||
| /*翻页按钮功能样式*/ | |||||
| .yhh-data-table-frame>.data-table-bottom-box>.paginate-box{ | |||||
| top:3px;right:0;overflow:hidden; | |||||
| } | |||||
| @@ -0,0 +1,754 @@ | |||||
| var img=new Image(); | |||||
| var ip = getIp(); | |||||
| var token = getCookie("_csrf"); | |||||
| canvas = document.getElementById("myCanvas"); | |||||
| context = canvas.getContext("2d"); | |||||
| // canvas.width = document.getElementById("myCanvas").offsetWidth; | |||||
| // canvas.height = document.getElementById("myCanvas").offsetWidth/1280*720; | |||||
| canvas.width = document.getElementById("win_canvas").offsetWidth; | |||||
| canvas.height = document.getElementById("win_canvas").offsetHeight; | |||||
| var color_dict = {"car":"#0099CC", "person":"#FF99CC","point":"#00cc00","pointselected":"red"}; | |||||
| var color_person = {"0":"#13c90c","1":"#fc0707","2":"#FF99CC","3":"#fceb07"}; | |||||
| var rects=[]; | |||||
| var masks=[]; | |||||
| var pointShapes =[]; | |||||
| var fileindex =0; | |||||
| var lastindex=false; | |||||
| var labeltastresult; | |||||
| var pageSize = 12; | |||||
| var tableData; | |||||
| var tablePageData; | |||||
| var dataset_id = $('#hide_uuidid').val(); | |||||
| var dbdatasetid = dataset_id; | |||||
| var textContent; | |||||
| var labelInfo; | |||||
| page(0,pageSize); | |||||
| function getCookie(name) | |||||
| { | |||||
| var arr,reg=new RegExp("(^| )"+name+"=([^;]*)(;|$)"); | |||||
| if(arr=document.cookie.match(reg)) | |||||
| return unescape(arr[2]); | |||||
| else | |||||
| return null; | |||||
| } | |||||
| function list(current,pageSize){ | |||||
| $.ajax({ | |||||
| type:"GET", | |||||
| url:ip + "/gitea-dateset-item-page", | |||||
| headers: { | |||||
| authorization:token, | |||||
| }, | |||||
| dataType:"json", | |||||
| data:{ | |||||
| 'datasetId':dbdatasetid, | |||||
| 'startPage':current, | |||||
| 'pageSize':pageSize}, | |||||
| async:false, | |||||
| success:function(json){ | |||||
| tablePageData = json; | |||||
| tableData = json.data; | |||||
| labeltastresult = tableData; | |||||
| fileindex=0; | |||||
| if(lastindex){ | |||||
| fileindex = pageSize - 1; | |||||
| } | |||||
| }, | |||||
| error:function(response) { | |||||
| } | |||||
| }); | |||||
| } | |||||
| function getTextContent(uuid,filename){ | |||||
| $.ajax({ | |||||
| type:"GET", | |||||
| url:ip + "/getgiteatext", | |||||
| headers: { | |||||
| authorization:token, | |||||
| }, | |||||
| dataType:"text", | |||||
| data:{ | |||||
| 'uuid':uuid, | |||||
| 'filename':filename | |||||
| }, | |||||
| async:false, | |||||
| success:function(json){ | |||||
| textContent = json; | |||||
| }, | |||||
| error:function(response) { | |||||
| } | |||||
| }); | |||||
| } | |||||
| /* | |||||
| function previewDataSetFile(uuid,filename){ | |||||
| console.log('uuid=' + uuid + " filename=" + filename); | |||||
| loadimg(uuid,filename); | |||||
| } | |||||
| function loadimg(uuid,filename){ | |||||
| img.src = ip + "/getgiteaimage?uuid=" + uuid + "&filename=" + filename; | |||||
| var fname = filename.substring(filename.lastIndexOf('/') + 1); | |||||
| $("#filename").text(fname); | |||||
| } | |||||
| */ | |||||
| function loadimg(){ | |||||
| var length = labeltastresult[fileindex].pic_image_field.length; | |||||
| if(labeltastresult[fileindex].pic_image_field.substring(length - 5) == ".json" | |||||
| || labeltastresult[fileindex].pic_image_field.substring(length - 4) == ".xml" | |||||
| || labeltastresult[fileindex].pic_image_field.substring(length - 4) == ".txt" | |||||
| || labeltastresult[fileindex].pic_image_field.substring(length - 4) == ".csv" | |||||
| || labeltastresult[fileindex].pic_image_field.substring(length - 3) == ".md" | |||||
| || labeltastresult[fileindex].pic_image_field.substring(length - 3) == ".py" | |||||
| || labeltastresult[fileindex].pic_image_field.substring(length - 3) == ".sh"){ | |||||
| //文本 | |||||
| canvas.style.display="none"; | |||||
| document.getElementById("textcontent").style.display="block"; | |||||
| getTextContent(dataset_id,labeltastresult[fileindex].pic_image_field); | |||||
| $('#textcontent').height(canvas.height-40) | |||||
| $("#textcontent").text(textContent); | |||||
| }else{ | |||||
| if(labeltastresult[fileindex].pic_image_field.substring(length - 5) == ".jpeg" | |||||
| || labeltastresult[fileindex].pic_image_field.substring(length - 4) == ".jpg" | |||||
| || labeltastresult[fileindex].pic_image_field.substring(length - 4) == ".bmp" | |||||
| || labeltastresult[fileindex].pic_image_field.substring(length - 4) == ".gif" | |||||
| || labeltastresult[fileindex].pic_image_field.substring(length - 4) == ".png"){ | |||||
| canvas.style.display="block"; | |||||
| document.getElementById("textcontent").style.display="none"; | |||||
| img.src = ip + "/getgiteaimage?uuid=" + dataset_id + "&filename=" + labeltastresult[fileindex].pic_image_field; | |||||
| }else{ | |||||
| canvas.style.display="none"; | |||||
| document.getElementById("textcontent").style.display="block"; | |||||
| $('#textcontent').height(canvas.height) | |||||
| $("#textcontent").text("暂不支持预览"); | |||||
| } | |||||
| } | |||||
| var fname = tableData[fileindex].pic_image_field.substring(tableData[fileindex].pic_image_field.lastIndexOf('/') + 1); | |||||
| $("#filename").text(fname); | |||||
| } | |||||
| img.onload = function(){ | |||||
| canvas.width = document.getElementById("win_canvas").offsetWidth; | |||||
| canvas.height = document.getElementById("win_canvas").offsetHeight-40; | |||||
| //调整画布大小 | |||||
| // if ((img.width/img.height)<(canvas.width/canvas.height)){ | |||||
| // canvas.width=canvas.height * img.width / img.height; | |||||
| // } | |||||
| // else{ | |||||
| // canvas.height=canvas.width * img.height / img.width; | |||||
| // } | |||||
| drawimage(); | |||||
| } | |||||
| function isEmpty(str){ | |||||
| if(typeof str == "undefined" || str == null || str == ""){ | |||||
| return true; | |||||
| } | |||||
| return false; | |||||
| } | |||||
| function drawimage() { | |||||
| parse_labelinfo(labeltastresult[fileindex].label_info); | |||||
| // 清除画布,准备绘制 | |||||
| context.clearRect(0, 0, canvas.width, canvas.heigth); | |||||
| // modal_context.cleararc | |||||
| context.drawImage(img,0,0,img.width,img.height,0,0,canvas.width, canvas.height); | |||||
| for(var i=0; i<rects.length; i++) { | |||||
| var rect = rects[i]; | |||||
| rectxywh = new Array(4); | |||||
| rectxywh_tmp = rect.getXYWH(); | |||||
| rectxywh[0] = rectxywh_tmp[0] / canvas.width * canvas.width; | |||||
| rectxywh[1] = rectxywh_tmp[1] / canvas.height * canvas.height; | |||||
| rectxywh[2] = rectxywh_tmp[2] / canvas.width * canvas.width; | |||||
| rectxywh[3] = rectxywh_tmp[3] / canvas.height * canvas.height; | |||||
| // 绘制矩形 | |||||
| context.lineWidth = 3; | |||||
| if(rect.type == "person"){ | |||||
| context.strokeStyle = color_person[ i % 4]; | |||||
| }else{ | |||||
| context.strokeStyle=color_dict[rect.type]; | |||||
| } | |||||
| context.strokeRect(rectxywh[0],rectxywh[1],rectxywh[2],rectxywh[3]); | |||||
| context.font = "15px Georgia"; | |||||
| context.fillStyle= context.strokeStyle; | |||||
| context.fillText(rect.type, rectxywh[0],rectxywh[1]-5); | |||||
| for(var j=0; j<4; j++){ | |||||
| var p_tmp = rect.points[j]; | |||||
| var p = new point(0,0); | |||||
| p.x = p_tmp.x/ canvas.width * canvas.width;; | |||||
| p.y = p_tmp.y / canvas.height * canvas.height; | |||||
| context.fillStyle = color_dict["point"]; | |||||
| context.fillRect(p.x-2,p.y-2,4,4); | |||||
| } | |||||
| } | |||||
| for (var i=0; i<masks.length; i++){ | |||||
| context.strokeStyle="purple" | |||||
| var mask =masks[i]; | |||||
| context.lineWidth = 2; | |||||
| for (var j=1; j<mask.points.length; j++){ | |||||
| context.beginPath(); | |||||
| context.moveTo(mask.points[j-1].x, mask.points[j-1].y); | |||||
| context.lineTo(mask.points[j].x,mask.points[j].y); | |||||
| context.stroke(); | |||||
| // modal_context.closePath(); | |||||
| } | |||||
| context.moveTo(mask.points[mask.points.length-1].x,mask.points[mask.points.length-1].y); | |||||
| context.lineTo(mask.points[0].x,mask.points[0].y); | |||||
| context.stroke(); | |||||
| context.closePath(); | |||||
| for (var j=0; j<mask.points.length; j++){ | |||||
| var p = mask.points[j] | |||||
| context.fillStyle = color_dict["point"]; | |||||
| context.fillRect(p.x-2,p.y-2,4,4); | |||||
| } | |||||
| } | |||||
| } | |||||
| function parse_labelinfo(labelinfo){ | |||||
| rects.length = 0; | |||||
| masks.length = 0; | |||||
| pointShapes.length = 0; | |||||
| if(!isEmpty(labelinfo)){ | |||||
| var label_arr = JSON.parse(labelinfo); | |||||
| for(var i=0;i<label_arr.length;i++){ | |||||
| if(!isEmpty(label_arr[i].mask)){ | |||||
| cls=label_arr[i].class_name; | |||||
| var tmpMask = new maskar(getCanvasLocationX(label_arr[i].mask[0]),getCanvasLocationY(label_arr[i].mask[1]),cls); | |||||
| for(var j = 2; j < label_arr[i].mask.length; j+=2){ | |||||
| tmpMask.points.push(new point(getCanvasLocationX(label_arr[i].mask[j]),getCanvasLocationY(label_arr[i].mask[j+1]))); | |||||
| } | |||||
| if(!isEmpty(label_arr[i].id)){ | |||||
| tmpMask.id= label_arr[i].id; | |||||
| } | |||||
| if(!isEmpty(label_arr[i].blurred)){ | |||||
| tmpMask.blurred = label_arr[i].blurred; | |||||
| } | |||||
| if(!isEmpty(label_arr[i].goodIllumination)){ | |||||
| tmpMask.goodIllumination = label_arr[i].goodIllumination; | |||||
| } | |||||
| if(!isEmpty(label_arr[i].frontview)){ | |||||
| tmpMask.frontview = label_arr[i].frontview; | |||||
| } | |||||
| tmpMask.finish = true; | |||||
| masks.push(tmpMask); | |||||
| }else if(!isEmpty(label_arr[i].box)){ | |||||
| x1 = getCanvasLocationX(label_arr[i].box[0]); | |||||
| y1 = getCanvasLocationY(label_arr[i].box[1]); | |||||
| x2 = getCanvasLocationX(label_arr[i].box[2]); | |||||
| y2 = getCanvasLocationY(label_arr[i].box[3]); | |||||
| cls=label_arr[i].class_name; | |||||
| score = label_arr[i].score; | |||||
| rect = new rectar(x1,y1,x2,y2,cls,score); | |||||
| if(!isEmpty(label_arr[i].id)){ | |||||
| rect.id= label_arr[i].id; | |||||
| } | |||||
| if(!isEmpty(label_arr[i].blurred)){ | |||||
| rect.blurred = label_arr[i].blurred; | |||||
| } | |||||
| if(!isEmpty(label_arr[i].goodIllumination)){ | |||||
| rect.goodIllumination = label_arr[i].goodIllumination; | |||||
| } | |||||
| if(!isEmpty(label_arr[i].frontview)){ | |||||
| rect.frontview = label_arr[i].frontview; | |||||
| } | |||||
| rects.push(rect); | |||||
| }else if(!isEmpty(label_arr[i].keypoints)){ | |||||
| cls=label_arr[i].class_name; | |||||
| score = label_arr[i].score; | |||||
| var pointShapeObj = new pointShape(getCanvasLocationX(label_arr[i].keypoints[0]),getCanvasLocationY(label_arr[i].keypoints[1]),cls,score); | |||||
| pointShapes.push(pointShapeObj); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| function point(x,y){ | |||||
| this.x = x; | |||||
| this.y = y; | |||||
| this.isSelected = false; | |||||
| }; | |||||
| function pointShape(x,y,type,score=1.0){ | |||||
| this.x = x; | |||||
| this.y = y; | |||||
| this.isSelected = false; | |||||
| this.type = type; | |||||
| this.score = score; | |||||
| this.id =""; //标识 | |||||
| this.blurred=false;//模糊不清的; 记不清的; 难以区分的; 模棱两可的 | |||||
| this.goodIllumination = false; //照明 | |||||
| this.frontview = false;//正面图 | |||||
| } | |||||
| function rectar(x1,y1,x2,y2, type, score=1.0){ | |||||
| // this.x = x; | |||||
| // this.y = y; | |||||
| // this.width = width; | |||||
| // this.height = height; | |||||
| this.type = type; | |||||
| this.score = score; | |||||
| //0--1, | |||||
| //| | | |||||
| //2--3 | |||||
| this.points = [new point(x1,y1), new point(x1, y2),new point(x2, y1),new point(x2, y2)]; | |||||
| this.getXYWH = function(){ | |||||
| var x_min=Math.min(this.points[0].x,this.points[1].x,this.points[2].x,this.points[3].x); | |||||
| var x_max=Math.max(this.points[0].x,this.points[1].x,this.points[2].x,this.points[3].x); | |||||
| var y_min=Math.min(this.points[0].y,this.points[1].y,this.points[2].y,this.points[3].y); | |||||
| var y_max=Math.max(this.points[0].y,this.points[1].y,this.points[2].y,this.points[3].y); | |||||
| return [x_min,y_min,x_max-x_min,y_max-y_min]; | |||||
| } | |||||
| this.getX1Y1X2Y2 = function(){ | |||||
| var x_min=Math.min(this.points[0].x,this.points[1].x,this.points[2].x,this.points[3].x); | |||||
| var x_max=Math.max(this.points[0].x,this.points[1].x,this.points[2].x,this.points[3].x); | |||||
| var y_min=Math.min(this.points[0].y,this.points[1].y,this.points[2].y,this.points[3].y); | |||||
| var y_max=Math.max(this.points[0].y,this.points[1].y,this.points[2].y,this.points[3].y); | |||||
| return [x_min,y_min,x_max,y_max]; | |||||
| } | |||||
| this.getdiapid = function(pid){//获取对角点 | |||||
| var twooverlapped,fouroverlapped; | |||||
| for (var i=0;i<4;i++){ | |||||
| if ((this.points[pid].x!=this.points[i].x)&&(this.points[pid].y!=this.points[i].y)){ | |||||
| return i; | |||||
| } | |||||
| if ((this.points[pid].x!=this.points[i].x)||(this.points[pid].y!=this.points[i].y)){ | |||||
| twooverlapped=i; | |||||
| } | |||||
| if (i!=pid) fouroverlapped=i; | |||||
| } | |||||
| if (twooverlapped) | |||||
| return twooverlapped; | |||||
| return fouroverlapped; | |||||
| } | |||||
| this.mouseonpoint = false; | |||||
| this.mouseonrect = false; | |||||
| this.isSelected = false; | |||||
| this.id =""; //标识 | |||||
| this.blurred=false;//模糊不清的; 记不清的; 难以区分的; 模棱两可的 | |||||
| this.goodIllumination = true; //照明 | |||||
| this.frontview = true;//正面图 | |||||
| }; | |||||
| function maskar(x0,y0,type){ | |||||
| this.type = type; | |||||
| this.points = [new point(x0,y0)]; | |||||
| this.finish = false; | |||||
| this.mouseonpoint = false; | |||||
| this.mouseonmask = false; | |||||
| this.isSelected = false; | |||||
| this.getX1Y1 = function(){return [this.points[0].x,this.points[0].y]} | |||||
| this.getBound = function(){ | |||||
| mlen = this.points.length; | |||||
| var minX = 999999999, minY = 999999999, maxX = -1, maxY = -1; | |||||
| for (var i = 0; i < mlen; i ++){ | |||||
| if(minX > this.points[i].x){ | |||||
| minX = this.points[i].x; | |||||
| } | |||||
| if(maxX < this.points[i].x){ | |||||
| maxX = this.points[i].x; | |||||
| } | |||||
| if(minY > this.points[i].y){ | |||||
| minY = this.points[i].y; | |||||
| } | |||||
| if(maxY < this.points[i].y){ | |||||
| maxY = this.points[i].y; | |||||
| } | |||||
| } | |||||
| return [minX, minY, maxX, maxY]; | |||||
| } | |||||
| this.id =""; //标识 | |||||
| this.blurred=false;//模糊不清的; 记不清的; 难以区分的; 模棱两可的 | |||||
| this.goodIllumination = true; //照明 | |||||
| this.frontview = true;//正面图 | |||||
| } | |||||
| function getCanvasLocationX(num){ | |||||
| return Math.round(num * canvas.width/parseInt(img.width)); | |||||
| } | |||||
| function getCanvasLocationY(num){ | |||||
| return Math.round(num * canvas.height/parseInt(img.height)); | |||||
| } | |||||
| function page(current,pageSize){ | |||||
| list(current,pageSize); | |||||
| showfilelist(); | |||||
| breadFiles(); | |||||
| loadimg(); | |||||
| setPage(tablePageData,pageSize); | |||||
| } | |||||
| getLabelInfo(dataset_id); | |||||
| showlabelflist(); | |||||
| function nextPage(){ | |||||
| var current = $('#displayPage1').text(); | |||||
| page(current,pageSize); | |||||
| } | |||||
| function prePage(){ | |||||
| var current =$('#displayPage1').text(); | |||||
| if(current > 1){ | |||||
| page(current - 2,pageSize); | |||||
| } | |||||
| } | |||||
| function goPage(){ | |||||
| var goNum = $('#goNum').val(); | |||||
| var pageTotal = $("#totalNum").text(); | |||||
| var pageNum = parseInt(pageTotal/pageSize); | |||||
| if(pageTotal%pageSize!=0){ | |||||
| pageNum += 1; | |||||
| }else { | |||||
| pageNum = pageNum; | |||||
| } | |||||
| if (goNum<=0){ | |||||
| alert("请输入大于0的数值"); | |||||
| } | |||||
| else if(goNum<=pageNum){ | |||||
| page(goNum - 1,pageSize); | |||||
| } | |||||
| else{ | |||||
| alert("不能超出总页码!"); | |||||
| } | |||||
| } | |||||
| $("#goNum").keydown(function (e) { | |||||
| if (e.keyCode == 13) { | |||||
| goPage(); | |||||
| } | |||||
| }); | |||||
| function setPage(pageData,pageSize){ | |||||
| if (isEmpty(pageData)){ | |||||
| return; | |||||
| } | |||||
| var startIndex = pageData.current * pageSize; | |||||
| if(pageData.total > 0){ | |||||
| startIndex = startIndex + 1; | |||||
| } | |||||
| if(startIndex < 10){ | |||||
| $('#startIndex').text(" " + (startIndex)); | |||||
| }else{ | |||||
| $('#startIndex').text(startIndex); | |||||
| } | |||||
| var endIndex = pageData.current * pageSize + pageData.data.length; | |||||
| if(endIndex < 10){ | |||||
| $('#endIndex').text(" " + (endIndex)); | |||||
| }else{ | |||||
| $('#endIndex').text(endIndex); | |||||
| } | |||||
| $('#totalNum').text(pageData.total); | |||||
| $('#displayPage1').text(pageData.current + 1); | |||||
| if(pageData.current == 0){ | |||||
| $('#prePage').removeAttr("href"); | |||||
| $('#prePage').attr('style','color:#f5f5f6;'); | |||||
| } | |||||
| else{ | |||||
| $('#prePage').attr("href","javascript:prePage()"); | |||||
| $('#prePage').attr('style','color:#000;'); | |||||
| } | |||||
| if((pageData.current + 1) * pageSize >= pageData.total){ | |||||
| $('#nextPage').removeAttr("href"); | |||||
| $('#nextPage').attr('style','color:#f5f5f6;') | |||||
| } | |||||
| else{ | |||||
| $('#nextPage').attr("href","javascript:nextPage()"); | |||||
| $('#nextPage').attr('style','color:#000;'); | |||||
| } | |||||
| var pageTotal = pageData.total; | |||||
| var pageNum = parseInt(pageTotal/pageSize); | |||||
| if(pageTotal%pageSize!=0){ | |||||
| pageNum += 1; | |||||
| }else { | |||||
| pageNum = pageNum; | |||||
| } | |||||
| $("#totalPageNum").text(pageNum); | |||||
| } | |||||
| function clickfilelist(index){ | |||||
| fileindex=index; | |||||
| loadimg(); | |||||
| //drawimage(); | |||||
| breadFiles() | |||||
| showfilelist(); | |||||
| } | |||||
| function clickNext(){ | |||||
| if(fileindex<tableData.length-1) { | |||||
| next(); | |||||
| }else{ | |||||
| if((tablePageData.current + 1) * pageSize >= tablePageData.total){ | |||||
| return; | |||||
| } | |||||
| nextPage(); | |||||
| } | |||||
| } | |||||
| function next(){ | |||||
| if(fileindex<tableData.length-1) {fileindex=fileindex+1;} | |||||
| loadimg(); | |||||
| //drawimage(); | |||||
| breadFiles() | |||||
| showfilelist(); | |||||
| } | |||||
| function clickLast(){ | |||||
| if(fileindex == 0){ | |||||
| lastindex=true; | |||||
| prePage(); | |||||
| lastindex=false; | |||||
| }else{ | |||||
| last(); | |||||
| } | |||||
| } | |||||
| function last(){ | |||||
| if(fileindex>0) {fileindex=fileindex-1;} | |||||
| loadimg(); | |||||
| //drawimage(); | |||||
| breadFiles(); | |||||
| showfilelist(); | |||||
| } | |||||
| // function showfilelist(){ | |||||
| // var htmlstr=""; | |||||
| // for (var i=0;i<labeltastresult.length;i++){ | |||||
| // var fname = labeltastresult[i].pic_image_field.substring(labeltastresult[i].pic_image_field.lastIndexOf('/') + 1); | |||||
| // var lablebg=" style=\"cursor:pointer\""; | |||||
| // if (i==fileindex){lablebg=" style=\"background:#eee;color:#5a5a5a;cursor:pointer;\"";} | |||||
| // htmlstr = htmlstr+"<tr onclick=\"clickfilelist("+i+");\""+ lablebg+"><td>"+ fname+ "</td></tr>"; | |||||
| // }; | |||||
| // document.getElementById("filelist").innerHTML=htmlstr; | |||||
| // } | |||||
| function showfilelist(){ | |||||
| // var filename_title = $('a.section:first').text() | |||||
| // filename_title = filename_title.substring(0,filename_title.lastIndexOf('.')) | |||||
| var filename_index = labeltastresult[0].pic_image_field.indexOf("/",70); | |||||
| filename_title = labeltastresult[0].pic_image_field.substring(filename_index + 1); | |||||
| filename_title = filename_title.substring(0,filename_title.indexOf('/')) | |||||
| var htmlstr = ''; | |||||
| // htmlstr += '<div class="ui list">'; | |||||
| htmlstr += '<div class="item" style="padding:1.2em;border-bottom:0;display: table;width: 100%;">' | |||||
| htmlstr += '<i class="caret down icon"></i>' | |||||
| htmlstr += '<div class="content" style="background:#fff">' | |||||
| htmlstr += '<div class="header" style="color: rgba(0,0,0,.8);font-size: 12px;font-weight: 600;">'+filename_title+'</div>' | |||||
| htmlstr += '<div class="list" style="padding:1.2em">' | |||||
| for (var i=0;i<labeltastresult.length;i++){ | |||||
| var fname = labeltastresult[i].pic_image_field.substring(labeltastresult[i].pic_image_field.lastIndexOf('/') + 1); | |||||
| console.log(labeltastresult[i]) | |||||
| if(labeltastresult[i].pic_image_field.length > 70){ | |||||
| var tmpIndex = labeltastresult[i].pic_image_field.indexOf("/",70); | |||||
| console.log(tmpIndex) | |||||
| if(tmpIndex != -1){ | |||||
| fname = labeltastresult[i].pic_image_field.substring(tmpIndex + 1); | |||||
| fname = fname.substring(fname.indexOf('/')+1); | |||||
| } | |||||
| } | |||||
| htmlstr += '<div class="item" onclick=\"clickfilelist('+i+');\" style="border-bottom:0;padding-bottom:0.9em;cursor:pointer">' | |||||
| htmlstr += '<div class="content" style="background:#fff;padding:0;">' | |||||
| if(i==fileindex){ | |||||
| htmlstr += '<div class="header" style="color: rgba(0,0,0,.8);font-size: 12px;font-weight: 100;color:#0366d6;overflow: hidden;text-overflow:ellipsis;">'+fname+'</div>' | |||||
| } | |||||
| else{ | |||||
| htmlstr += '<div class="header" style="color: rgba(0,0,0,.8);font-size: 12px;font-weight: 100;overflow: hidden;text-overflow:ellipsis;">'+fname+'</div>' | |||||
| } | |||||
| htmlstr += '</div>' | |||||
| htmlstr += '</div>' | |||||
| }; | |||||
| htmlstr += '</div>' | |||||
| htmlstr += '</div>' | |||||
| htmlstr += '</div>' | |||||
| document.getElementById("filelist").innerHTML=htmlstr; | |||||
| } | |||||
| function breadFiles(){ | |||||
| // for (var i=0;i<labeltastresult.length;i++){ | |||||
| // var fname_full_path="" | |||||
| // if(labeltastresult[i].pic_image_field.length > 70){ | |||||
| // var tmp_index = labeltastresult[i].pic_image_field.indexOf("/",70); | |||||
| // if(tmp_index != -1){ | |||||
| // fname_full_path = labeltastresult[i].pic_image_field.substring(tmp_index + 1); | |||||
| // } | |||||
| // var fname_path = fname_full_path.split('/') | |||||
| // html_breadFile += '<div class="section">'+fname_full_path+'.zip'+'</div>' | |||||
| // for(var i=1;i<fname_path.length;i++){ | |||||
| // html_breadFile += '<div class="divider" style="opacity:0.8"> / </div>' | |||||
| // html_breadFile += '<div class="section">'+fname_path[i]+'</div>' | |||||
| // } | |||||
| // } | |||||
| // else{ | |||||
| // } | |||||
| // } | |||||
| var fname_full_path="" | |||||
| var filename_title = $('a.section:first').text() | |||||
| filename_title = filename_title.substring(0,filename_title.lastIndexOf('.')) | |||||
| var tmp_index = tableData[fileindex].pic_image_field.indexOf("/",70); | |||||
| if(tmp_index != -1){ | |||||
| fname_full_path = tableData[fileindex].pic_image_field.substring(tmp_index + 1); | |||||
| } | |||||
| var fname_path = fname_full_path.split('/') | |||||
| console.log(fname_path) | |||||
| // var filename_text = tableData[fileindex].pic_image_field.substring(tableData[fileindex].pic_image_field.lastIndexOf('/')+1) | |||||
| var html_breadFile = '' | |||||
| // var source_name = filename_title+'.zip' | |||||
| // html_breadFile += '<div class="section">'+source_name+'</div>' | |||||
| // html_breadFile += '<div class="divider" style="opacity:0.8"> / </div>' | |||||
| html_breadFile += '<div class="section">'+filename_title+'</div>' | |||||
| html_breadFile += '<div class="divider" style="opacity:0.8"> / </div>' | |||||
| for (var i=0;i<fname_path.length;i++){ | |||||
| html_breadFile += '<div class="section">'+fname_path[i]+'</div>' | |||||
| html_breadFile += '<div class="divider" style="opacity:0.8"> / </div>' | |||||
| } | |||||
| document.getElementById("breadFile").innerHTML=html_breadFile | |||||
| } | |||||
| function showlabelflist(){ | |||||
| if(!isEmpty(labelInfo)){ | |||||
| var resLabelInfo = JSON.parse(labelInfo) | |||||
| var textInfo = resLabelInfo["type"] | |||||
| var html_labelFile = '' | |||||
| for (var i=0;i<textInfo.length;i++){ | |||||
| html_labelFile += `<span style="display:block;width:70%;margin:0.6em 15%;padding-left:1.5em;padding-top:0.4em;padding-bottom:0.4em;font-size:12px;" class="labelInfo">${textInfo[i]}</span>` | |||||
| } | |||||
| document.getElementById("labellist").innerHTML=html_labelFile | |||||
| setColor() | |||||
| } | |||||
| else{ | |||||
| return | |||||
| } | |||||
| } | |||||
| function setColor(){ | |||||
| colorinfo1 = ['rgba(0, 199, 255, 0.4)','rgba(114, 46, 209, 0.4)','rgba(188, 100, 164, 0.4)','rgba(153, 204, 0, 0.4)','rgba(51, 204, 153, 0.4)','rgba(255, 204, 51, 0.4)', | |||||
| 'rgba(71, 255, 71, 0.4)','rgba(255, 154, 71, 0.4)','rgba(71, 126, 255, 0.4)','rgba(71, 255, 255, 0.4)','rgba(255, 247, 71, 0.4)','rgba(196, 127, 255, 0.4)','rgba(233, 84, 100, 0.4)', | |||||
| 'rgba(255, 71, 204, 0.4)',' rgba(43, 199, 160, 0.4)'] | |||||
| colorinfo2 = ['#00C7FF','#722ED1','#BC64A4','#99CC00','#33CC99','#FFCC33','#47FF47','#FF9A47','#477EFF','#47FFFF','#FFF747','#C47FFF','#E95464','#FF47CC','#2BC7A0'] | |||||
| var el_span = document.querySelectorAll("span.labelInfo") | |||||
| for (var i=0;i<el_span.length;i++){ | |||||
| // var colorinfo = ~~(Math.random()*(1<<24)) | |||||
| // var colorinfo1 = '#'+(colorinfo).toString(16) | |||||
| // var colorinfo2 = '#'+(colorinfo+100).toString(16) | |||||
| el_span[i].style.backgroundColor = colorinfo1[i] | |||||
| el_span[i].style.borderLeft = '5px solid'+ colorinfo2[i] | |||||
| } | |||||
| } | |||||
| function getLabelInfo(uuid){ | |||||
| $.ajax({ | |||||
| type:"GET", | |||||
| url:ip + "/getlabelinfo", | |||||
| headers: { | |||||
| authorization:token, | |||||
| }, | |||||
| dataType:"text", | |||||
| data:{ | |||||
| 'uuid':uuid | |||||
| }, | |||||
| async:false, | |||||
| success:function(json){ | |||||
| labelInfo = json; | |||||
| }, | |||||
| error:function(response) { | |||||
| } | |||||
| }); | |||||
| } | |||||
| @@ -0,0 +1,269 @@ | |||||
| function getIp(){ | |||||
| return "/labelsystem"; | |||||
| } | |||||
| function isEmpty(str){ | |||||
| if(typeof str == "undefined" || str == null || str == ""){ | |||||
| return true; | |||||
| } | |||||
| return false; | |||||
| } | |||||
| function redirect(response){ | |||||
| if("REDIRECT" == response.getResponseHeader("REDIRECT")){ //若HEADER中含有REDIRECT说明后端想重定向, | |||||
| var win = window; | |||||
| while(win != win.top){ | |||||
| win = win.top; | |||||
| } | |||||
| win.location.href = getIp() +"/login.html";//使用win.location.href去实现重定向到登录页面 | |||||
| } | |||||
| } | |||||
| function setCookie(name,value) | |||||
| { | |||||
| var Days = 7; | |||||
| var exp = new Date(); | |||||
| exp.setTime(exp.getTime() + Days*24*60*60*1000); | |||||
| document.cookie = name + "="+ escape (value) + ";expires=" + exp.toGMTString(); | |||||
| } | |||||
| //读取cookies | |||||
| function getCookie(name) | |||||
| { | |||||
| var arr,reg=new RegExp("(^| )"+name+"=([^;]*)(;|$)"); | |||||
| if(arr=document.cookie.match(reg)) | |||||
| return unescape(arr[2]); | |||||
| else | |||||
| return null; | |||||
| } | |||||
| function delCookie(name) | |||||
| { | |||||
| var exp = new Date(); | |||||
| exp.setTime(exp.getTime() - 1); | |||||
| var cval=getCookie(name); | |||||
| if(cval!=null) | |||||
| document.cookie= name + "="+cval+";expires="+exp.toGMTString(); | |||||
| } | |||||
| //检查是否都符合 注册 要求 | |||||
| function check_reg() | |||||
| { | |||||
| if(check_email(document.getElementById('email')) && check_web(document.getElementById('web'))) | |||||
| { | |||||
| return true; | |||||
| }else{ | |||||
| return false; | |||||
| } | |||||
| } | |||||
| //检查密码长度不能少于6 | |||||
| function check_len(thisObj){ | |||||
| if(thisObj.value.length==0) | |||||
| { | |||||
| document.getElementById('show_pass').innerHTML="密码不能为空"; | |||||
| return false; | |||||
| }else{ | |||||
| if (thisObj.value.length<6) | |||||
| { | |||||
| document.getElementById('show_pass').innerHTML="密码长度不少于6"; | |||||
| return false; | |||||
| } | |||||
| document.getElementById('show_pass').innerHTML=""; | |||||
| return true; | |||||
| } | |||||
| } | |||||
| //检查俩次密码输入是否一致 | |||||
| function check_pass(thisObj){ | |||||
| var psw=document.getElementById('pass'); | |||||
| if(psw.value.length==0) | |||||
| { | |||||
| document.getElementById('show_pass').innerHTML="密码不能为空"; | |||||
| return false; | |||||
| }else{ | |||||
| document.getElementById('show_pass').innerHTML=""; | |||||
| if (thisObj.value!=psw.value) | |||||
| { | |||||
| document.getElementById('show_repass').innerHTML="两次密码输入不正确"; | |||||
| return false; | |||||
| } | |||||
| document.getElementById('show_repass').innerHTML=""; | |||||
| return true; | |||||
| } | |||||
| } | |||||
| //检查email是否正确 | |||||
| function check_email(thisObj){ | |||||
| var reg=/^([a-zA-Z\d][a-zA-Z0-9_]+@[a-zA-Z\d]+(\.[a-zA-Z\d]+)+)$/gi; | |||||
| var rzt=thisObj.value.match(reg); | |||||
| if(thisObj.value.length==0){ | |||||
| document.getElementById('show_e').innerHTML="Email不能为空"; | |||||
| return false; | |||||
| }else{ | |||||
| if (rzt==null) | |||||
| { | |||||
| document.getElementById('show_e').innerHTML="Email地址不正确"; | |||||
| return false; | |||||
| } | |||||
| document.getElementById('show_e').innerHTML=""; | |||||
| return true; | |||||
| } | |||||
| } | |||||
| //检查web是否正确 | |||||
| function check_web(thisObj){ | |||||
| //var reg=/^\w+([\.\-]\w)*$/; | |||||
| //var rzt=thisObj.value.match(reg); | |||||
| if(thisObj.value.length==0){ | |||||
| document.getElementById('show_web').innerHTML="主页不能为空"; | |||||
| return false; | |||||
| }else{ | |||||
| /*if (rzt==null) | |||||
| { | |||||
| document.getElementById('show_web').innerHTML="主页地址不正确"; | |||||
| return false; | |||||
| } */ | |||||
| var strRegex = "^((https|http|ftp|rtsp|mms)?://)" | |||||
| + "?(([0-9a-z_!~*'().&=+$%-]+: )?[0-9a-z_!~*'().&=+$%-]+@)?" //ftp的user@ | |||||
| + "(([0-9]{1,3}\.){3}[0-9]{1,3}" // IP形式的URL- 199.194.52.184 | |||||
| + "|" // 允许IP和DOMAIN(域名) | |||||
| + "([0-9a-z_!~*'()-]+\.)*" // 域名- www. | |||||
| + "([0-9a-z][0-9a-z-]{0,61})?[0-9a-z]\." // 二级域名 | |||||
| + "[a-z]{2,6})" // first level domain- .com or .museum | |||||
| + "(:[0-9]{1,4})?" // 端口- :80 | |||||
| + "((/?)|" // a slash isn't required if there is no file name | |||||
| + "(/[0-9a-z_!~*'().;?:@&=+$,%#-]+)+/?)$"; | |||||
| var re=new RegExp(strRegex); | |||||
| if(!re.test(thisObj.value)) | |||||
| { | |||||
| document.getElementById('show_web').innerHTML="主页地址不正确"; | |||||
| return false; | |||||
| } | |||||
| document.getElementById('show_web').innerHTML=""; | |||||
| return true; | |||||
| } | |||||
| } | |||||
| function isRightLatitude(lat){ | |||||
| var latreg = /^(\-|\+)?([0-8]?\d{1}\.\d{0,6}|90\.0{0,6}|[0-8]?\d{1}|90)$/; | |||||
| if(!latreg.test(lat)){ | |||||
| return false; | |||||
| //console.log("纬度整数部分为0-90,小数部分为0到6位!"); | |||||
| } | |||||
| return true; | |||||
| } | |||||
| function isRightLongitude(longitude){ | |||||
| var longrg = /^(\-|\+)?(((\d|[1-9]\d|1[0-7]\d|0{1,3})\.\d{0,6})|(\d|[1-9]\d|1[0-7]\d|0{1,3})|180\.0{0,6}|180)$/; | |||||
| if(!longrg.test(longitude)){ | |||||
| return false; | |||||
| //console.log("经度整数部分为0-180,小数部分为0到6位!"); | |||||
| } | |||||
| return true; | |||||
| } | |||||
| function isRightDateTime_dot(time){ | |||||
| //2020-05-20 14:20:20 | |||||
| if(time.length != 19){ | |||||
| return false; | |||||
| } | |||||
| return strDateTime(time); | |||||
| } | |||||
| function strDateTime(str) | |||||
| { | |||||
| var reg = /^(\d{1,4})(-|\/)(\d{1,2})\2(\d{1,2}) (\d{1,2}):(\d{1,2}):(\d{1,2})$/; | |||||
| var r = str.match(reg); | |||||
| if(r==null){ | |||||
| return false; | |||||
| } | |||||
| var d= new Date(r[1], r[3]-1,r[4],r[5],r[6],r[7]); | |||||
| return (d.getFullYear()==r[1]&&(d.getMonth()+1)==r[3]&&d.getDate()==r[4]&&d.getHours()==r[5]&&d.getMinutes()==r[6]&&d.getSeconds()==r[7]); | |||||
| } | |||||
| function isRightDateTime_yyyyMMddHHmmss(time){ | |||||
| //20200520142020 | |||||
| if(time.length != 14){ | |||||
| return false; | |||||
| } | |||||
| var year = time.substring(0,4); | |||||
| var month = time.substring(4,6); | |||||
| var day = time.substring(6,8); | |||||
| var hour = time.substring(8,10); | |||||
| var minute = time.substring(10,12); | |||||
| var second = time.substring(12,14); | |||||
| console.log("year=" + year + " month=" + month + "day=" + day); | |||||
| var d= new Date(year,month-1,day,hour,minute,second); | |||||
| return (d.getFullYear()==year && (d.getMonth()+1)== month&& d.getDate()== day && d.getHours()==hour && d.getMinutes()==minute && d.getSeconds()==second); | |||||
| } | |||||
| function isDateString(strDate){ | |||||
| var strSeparator = "-"; //日期分隔符 | |||||
| var strDateArray; | |||||
| var intYear; | |||||
| var intMonth; | |||||
| var intDay; | |||||
| var boolLeapYear; | |||||
| var ErrorMsg = ""; //出错信息 | |||||
| strDateArray = strDate.split(strSeparator); | |||||
| //没有判断长度,其实2008-8-8也是合理的//strDate.length != 10 || | |||||
| if(strDateArray.length != 3) { | |||||
| ErrorMsg += "日期格式必须为: yyyy-MM-dd"; | |||||
| return ErrorMsg; | |||||
| } | |||||
| intYear = parseInt(strDateArray[0],10); | |||||
| intMonth = parseInt(strDateArray[1],10); | |||||
| intDay = parseInt(strDateArray[2],10); | |||||
| if(isNaN(intYear)||isNaN(intMonth)||isNaN(intDay)) { | |||||
| ErrorMsg += "日期格式错误: 年月日必须为纯数字"; | |||||
| return ErrorMsg; | |||||
| } | |||||
| if(intMonth>12 || intMonth<1) { | |||||
| ErrorMsg += "日期格式错误: 月份必须介于1和12之间"; | |||||
| return ErrorMsg; | |||||
| } | |||||
| if((intMonth==1||intMonth==3||intMonth==5||intMonth==7 | |||||
| ||intMonth==8||intMonth==10||intMonth==12) | |||||
| &&(intDay>31||intDay<1)) { | |||||
| ErrorMsg += "日期格式错误: 大月的天数必须介于1到31之间"; | |||||
| return ErrorMsg; | |||||
| } | |||||
| if((intMonth==4||intMonth==6||intMonth==9||intMonth==11) | |||||
| &&(intDay>30||intDay<1)) { | |||||
| ErrorMsg += "日期格式错误: 小月的天数必须介于1到31之间"; | |||||
| return ErrorMsg; | |||||
| } | |||||
| if(intMonth==2){ | |||||
| if(intDay < 1) { | |||||
| ErrorMsg += "日期格式错误: 日期必须大于或等于1"; | |||||
| return ErrorMsg; | |||||
| } | |||||
| boolLeapYear = false; | |||||
| if((intYear%100) == 0){ | |||||
| if((intYear%400) == 0) | |||||
| boolLeapYear = true; | |||||
| } | |||||
| else{ | |||||
| if((intYear % 4) == 0) | |||||
| boolLeapYear = true; | |||||
| } | |||||
| if(boolLeapYear){ | |||||
| if(intDay > 29) { | |||||
| ErrorMsg += "日期格式错误: 闰年的2月份天数不能超过29"; | |||||
| return ErrorMsg; | |||||
| } | |||||
| } else { | |||||
| if(intDay > 28) { | |||||
| ErrorMsg += "日期格式错误: 非闰年的2月份天数不能超过28"; | |||||
| return ErrorMsg; | |||||
| } | |||||
| } | |||||
| } | |||||
| return ErrorMsg; | |||||
| } | |||||
| @@ -0,0 +1,739 @@ | |||||
| /*! | |||||
| * Author: Abdullah A Almsaeed | |||||
| * Date: 4 Jan 2014 | |||||
| * Description: | |||||
| * This file should be included in all pages | |||||
| !**/ | |||||
| /* | |||||
| * Global variables. If you change any of these vars, don't forget | |||||
| * to change the values in the less files! | |||||
| */ | |||||
| var left_side_width = 220; //Sidebar width in pixels | |||||
| $(function() { | |||||
| "use strict"; | |||||
| //Enable sidebar toggle | |||||
| $("[data-toggle='offcanvas']").click(function(e) { | |||||
| e.preventDefault(); | |||||
| //If window is small enough, enable sidebar push menu | |||||
| if ($(window).width() <= 992) { | |||||
| $('.row-offcanvas').toggleClass('active'); | |||||
| $('.left-side').removeClass("collapse-left"); | |||||
| $(".right-side").removeClass("strech"); | |||||
| $('.row-offcanvas').toggleClass("relative"); | |||||
| } else { | |||||
| //Else, enable content streching | |||||
| $('.left-side').toggleClass("collapse-left"); | |||||
| $(".right-side").toggleClass("strech"); | |||||
| } | |||||
| }); | |||||
| //Add hover support for touch devices | |||||
| $('.btn').bind('touchstart', function() { | |||||
| $(this).addClass('hover'); | |||||
| }).bind('touchend', function() { | |||||
| $(this).removeClass('hover'); | |||||
| }); | |||||
| //Activate tooltips | |||||
| $("[data-toggle='tooltip']").tooltip(); | |||||
| /* | |||||
| * Add collapse and remove events to boxes | |||||
| */ | |||||
| $("[data-widget='collapse']").click(function() { | |||||
| //Find the box parent | |||||
| var box = $(this).parents(".box").first(); | |||||
| //Find the body and the footer | |||||
| var bf = box.find(".box-body, .box-footer"); | |||||
| if (!box.hasClass("collapsed-box")) { | |||||
| box.addClass("collapsed-box"); | |||||
| //Convert minus into plus | |||||
| $(this).children(".fa-minus").removeClass("fa-minus").addClass("fa-plus"); | |||||
| bf.slideUp(); | |||||
| } else { | |||||
| box.removeClass("collapsed-box"); | |||||
| //Convert plus into minus | |||||
| $(this).children(".fa-plus").removeClass("fa-plus").addClass("fa-minus"); | |||||
| bf.slideDown(); | |||||
| } | |||||
| }); | |||||
| /* | |||||
| * ADD SLIMSCROLL TO THE TOP NAV DROPDOWNS | |||||
| * --------------------------------------- | |||||
| */ | |||||
| $(".navbar .menu").slimscroll({ | |||||
| height: "200px", | |||||
| alwaysVisible: false, | |||||
| size: "3px" | |||||
| }).css("width", "100%"); | |||||
| /* | |||||
| * INITIALIZE BUTTON TOGGLE | |||||
| * ------------------------ | |||||
| */ | |||||
| $('.btn-group[data-toggle="btn-toggle"]').each(function() { | |||||
| var group = $(this); | |||||
| $(this).find(".btn").click(function(e) { | |||||
| group.find(".btn.active").removeClass("active"); | |||||
| $(this).addClass("active"); | |||||
| e.preventDefault(); | |||||
| }); | |||||
| }); | |||||
| $("[data-widget='remove']").click(function() { | |||||
| //Find the box parent | |||||
| var box = $(this).parents(".box").first(); | |||||
| box.slideUp(); | |||||
| }); | |||||
| /* Sidebar tree view */ | |||||
| $(".sidebar .treeview").tree(); | |||||
| /* | |||||
| * Make sure that the sidebar is streched full height | |||||
| * --------------------------------------------- | |||||
| * We are gonna assign a min-height value every time the | |||||
| * wrapper gets resized and upon page load. We will use | |||||
| * Ben Alman's method for detecting the resize event. | |||||
| * | |||||
| **/ | |||||
| function _fix() { | |||||
| //Get window height and the wrapper height | |||||
| var height = $(window).height() - $("body > .header").height() - ($("body > .footer").outerHeight() || 0); | |||||
| $(".wrapper").css("min-height", height + "px"); | |||||
| var content = $(".wrapper").height(); | |||||
| //If the wrapper height is greater than the window | |||||
| if (content > height){ | |||||
| //then set sidebar height to the wrapper | |||||
| $(".left-side, html, body").css("min-height", content + "px"); | |||||
| $(".pull-height, html, body").css("min-height", content + "px"); | |||||
| } | |||||
| else { | |||||
| //Otherwise, set the sidebar to the height of the window | |||||
| $(".left-side, html, body").css("min-height", height + "px"); | |||||
| $(".pull-height, html, body").css("min-height", content + "px"); | |||||
| } | |||||
| } | |||||
| //Fire upon load | |||||
| _fix(); | |||||
| //Fire when wrapper is resized | |||||
| $(".wrapper").resize(function() { | |||||
| _fix(); | |||||
| fix_sidebar(); | |||||
| }); | |||||
| //Fix the fixed layout sidebar scroll bug | |||||
| fix_sidebar(); | |||||
| /* | |||||
| * We are gonna initialize all checkbox and radio inputs to | |||||
| * iCheck plugin in. | |||||
| * You can find the documentation at http://fronteed.com/iCheck/ | |||||
| */ | |||||
| // $("input[type='checkbox']:not(.simple), input[type='radio']:not(.simple)").iCheck({ | |||||
| // checkboxClass: 'icheckbox_minimal', | |||||
| // radioClass: 'iradio_minimal' | |||||
| // }); | |||||
| }); | |||||
| function fix_sidebar() { | |||||
| //Make sure the body tag has the .fixed class | |||||
| if (!$("body").hasClass("fixed")) { | |||||
| return; | |||||
| } | |||||
| //Add slimscroll | |||||
| $(".sidebar").slimscroll({ | |||||
| height: ($(window).height() - $(".header").height()) + "px", | |||||
| color: "rgba(0,0,0,0.2)" | |||||
| }); | |||||
| } | |||||
| /* | |||||
| * BOX REFRESH BUTTON | |||||
| * ------------------ | |||||
| * This is a custom plugin to use with the compenet BOX. It allows you to add | |||||
| * a refresh button to the box. It converts the box's state to a loading state. | |||||
| * | |||||
| * USAGE: | |||||
| * $("#box-widget").boxRefresh( options ); | |||||
| * */ | |||||
| (function($) { | |||||
| "use strict"; | |||||
| $.fn.boxRefresh = function(options) { | |||||
| // Render options | |||||
| var settings = $.extend({ | |||||
| //Refressh button selector | |||||
| trigger: ".refresh-btn", | |||||
| //File source to be loaded (e.g: ajax/src.php) | |||||
| source: "", | |||||
| //Callbacks | |||||
| onLoadStart: function(box) { | |||||
| }, //Right after the button has been clicked | |||||
| onLoadDone: function(box) { | |||||
| } //When the source has been loaded | |||||
| }, options); | |||||
| //The overlay | |||||
| var overlay = $('<div class="overlay"></div><div class="loading-img"></div>'); | |||||
| return this.each(function() { | |||||
| //if a source is specified | |||||
| if (settings.source === "") { | |||||
| if (console) { | |||||
| console.log("Please specify a source first - boxRefresh()"); | |||||
| } | |||||
| return; | |||||
| } | |||||
| //the box | |||||
| var box = $(this); | |||||
| //the button | |||||
| var rBtn = box.find(settings.trigger).first(); | |||||
| //On trigger click | |||||
| rBtn.click(function(e) { | |||||
| e.preventDefault(); | |||||
| //Add loading overlay | |||||
| start(box); | |||||
| //Perform ajax call | |||||
| box.find(".box-body").load(settings.source, function() { | |||||
| done(box); | |||||
| }); | |||||
| }); | |||||
| }); | |||||
| function start(box) { | |||||
| //Add overlay and loading img | |||||
| box.append(overlay); | |||||
| settings.onLoadStart.call(box); | |||||
| } | |||||
| function done(box) { | |||||
| //Remove overlay and loading img | |||||
| box.find(overlay).remove(); | |||||
| settings.onLoadDone.call(box); | |||||
| } | |||||
| }; | |||||
| })(jQuery); | |||||
| /* | |||||
| * SIDEBAR MENU | |||||
| * ------------ | |||||
| * This is a custom plugin for the sidebar menu. It provides a tree view. | |||||
| * | |||||
| * Usage: | |||||
| * $(".sidebar).tree(); | |||||
| * | |||||
| * Note: This plugin does not accept any options. Instead, it only requires a class | |||||
| * added to the element that contains a sub-menu. | |||||
| * | |||||
| * When used with the sidebar, for example, it would look something like this: | |||||
| * <ul class='sidebar-menu'> | |||||
| * <li class="treeview active"> | |||||
| * <a href="#>Menu</a> | |||||
| * <ul class='treeview-menu'> | |||||
| * <li class='active'><a href=#>Level 1</a></li> | |||||
| * </ul> | |||||
| * </li> | |||||
| * </ul> | |||||
| * | |||||
| * Add .active class to <li> elements if you want the menu to be open automatically | |||||
| * on page load. See above for an example. | |||||
| */ | |||||
| (function($) { | |||||
| "use strict"; | |||||
| $.fn.tree = function() { | |||||
| return this.each(function() { | |||||
| var btn = $(this).children("a").first(); | |||||
| var menu = $(this).children(".treeview-menu").first(); | |||||
| var isActive = $(this).hasClass('active'); | |||||
| //initialize already active menus | |||||
| if (isActive) { | |||||
| menu.show(); | |||||
| btn.children(".fa-angle-left").first().removeClass("fa-angle-left").addClass("fa-angle-down"); | |||||
| } | |||||
| //Slide open or close the menu on link click | |||||
| btn.click(function(e) { | |||||
| e.preventDefault(); | |||||
| if (isActive) { | |||||
| //Slide up to close menu | |||||
| menu.slideUp(); | |||||
| isActive = false; | |||||
| btn.children(".fa-angle-down").first().removeClass("fa-angle-down").addClass("fa-angle-left"); | |||||
| btn.parent("li").removeClass("active"); | |||||
| } else { | |||||
| //Slide down to open menu | |||||
| menu.slideDown(); | |||||
| isActive = true; | |||||
| btn.children(".fa-angle-left").first().removeClass("fa-angle-left").addClass("fa-angle-down"); | |||||
| btn.parent("li").addClass("active"); | |||||
| } | |||||
| }); | |||||
| /* Add margins to submenu elements to give it a tree look */ | |||||
| menu.find("li > a").each(function() { | |||||
| var pad = parseInt($(this).css("margin-left")) + 10; | |||||
| $(this).css({"margin-left": pad + "px"}); | |||||
| }); | |||||
| }); | |||||
| }; | |||||
| }(jQuery)); | |||||
| /* | |||||
| * TODO LIST CUSTOM PLUGIN | |||||
| * ----------------------- | |||||
| * This plugin depends on iCheck plugin for checkbox and radio inputs | |||||
| */ | |||||
| (function($) { | |||||
| "use strict"; | |||||
| $.fn.todolist = function(options) { | |||||
| // Render options | |||||
| var settings = $.extend({ | |||||
| //When the user checks the input | |||||
| onCheck: function(ele) { | |||||
| }, | |||||
| //When the user unchecks the input | |||||
| onUncheck: function(ele) { | |||||
| } | |||||
| }, options); | |||||
| return this.each(function() { | |||||
| $('input', this).on('ifChecked', function(event) { | |||||
| var ele = $(this).parents("li").first(); | |||||
| ele.toggleClass("done"); | |||||
| settings.onCheck.call(ele); | |||||
| }); | |||||
| $('input', this).on('ifUnchecked', function(event) { | |||||
| var ele = $(this).parents("li").first(); | |||||
| ele.toggleClass("done"); | |||||
| settings.onUncheck.call(ele); | |||||
| }); | |||||
| }); | |||||
| }; | |||||
| }(jQuery)); | |||||
| /* CENTER ELEMENTS */ | |||||
| (function($) { | |||||
| "use strict"; | |||||
| jQuery.fn.center = function(parent) { | |||||
| if (parent) { | |||||
| parent = this.parent(); | |||||
| } else { | |||||
| parent = window; | |||||
| } | |||||
| this.css({ | |||||
| "position": "absolute", | |||||
| "top": ((($(parent).height() - this.outerHeight()) / 2) + $(parent).scrollTop() + "px"), | |||||
| "left": ((($(parent).width() - this.outerWidth()) / 2) + $(parent).scrollLeft() + "px") | |||||
| }); | |||||
| return this; | |||||
| } | |||||
| }(jQuery)); | |||||
| /* | |||||
| * jQuery resize event - v1.1 - 3/14/2010 | |||||
| * http://benalman.com/projects/jquery-resize-plugin/ | |||||
| * | |||||
| * Copyright (c) 2010 "Cowboy" Ben Alman | |||||
| * Dual licensed under the MIT and GPL licenses. | |||||
| * http://benalman.com/about/license/ | |||||
| */ | |||||
| (function($, h, c) { | |||||
| var a = $([]), e = $.resize = $.extend($.resize, {}), i, k = "setTimeout", j = "resize", d = j + "-special-event", b = "delay", f = "throttleWindow"; | |||||
| e[b] = 250; | |||||
| e[f] = true; | |||||
| $.event.special[j] = {setup: function() { | |||||
| if (!e[f] && this[k]) { | |||||
| return false; | |||||
| } | |||||
| var l = $(this); | |||||
| a = a.add(l); | |||||
| $.data(this, d, {w: l.width(), h: l.height()}); | |||||
| if (a.length === 1) { | |||||
| g(); | |||||
| } | |||||
| }, teardown: function() { | |||||
| if (!e[f] && this[k]) { | |||||
| return false | |||||
| } | |||||
| var l = $(this); | |||||
| a = a.not(l); | |||||
| l.removeData(d); | |||||
| if (!a.length) { | |||||
| clearTimeout(i); | |||||
| } | |||||
| }, add: function(l) { | |||||
| if (!e[f] && this[k]) { | |||||
| return false | |||||
| } | |||||
| var n; | |||||
| function m(s, o, p) { | |||||
| var q = $(this), r = $.data(this, d); | |||||
| r.w = o !== c ? o : q.width(); | |||||
| r.h = p !== c ? p : q.height(); | |||||
| n.apply(this, arguments) | |||||
| } | |||||
| if ($.isFunction(l)) { | |||||
| n = l; | |||||
| return m | |||||
| } else { | |||||
| n = l.handler; | |||||
| l.handler = m | |||||
| } | |||||
| }}; | |||||
| function g() { | |||||
| i = h[k](function() { | |||||
| a.each(function() { | |||||
| var n = $(this), m = n.width(), l = n.height(), o = $.data(this, d); | |||||
| if (m !== o.w || l !== o.h) { | |||||
| n.trigger(j, [o.w = m, o.h = l]) | |||||
| } | |||||
| }); | |||||
| g() | |||||
| }, e[b]) | |||||
| }} | |||||
| )(jQuery, this); | |||||
| /*! | |||||
| * SlimScroll https://github.com/rochal/jQuery-slimScroll | |||||
| * ======================================================= | |||||
| * | |||||
| * Copyright (c) 2011 Piotr Rochala (http://rocha.la) Dual licensed under the MIT | |||||
| */ | |||||
| (function(f) { | |||||
| jQuery.fn.extend({slimScroll: function(h) { | |||||
| var a = f.extend({width: "auto", height: "100%", size: "7px", color: "#000", position: "right", distance: "1px", start: "top", opacity: 0.4, alwaysVisible: !0, disableFadeOut: !1, railVisible: !1, railColor: "#333", railOpacity: 0.2, railDraggable: !0, railClass: "slimScrollRail", barClass: "slimScrollBar", wrapperClass: "slimScrollDiv", allowPageScroll: !1, wheelStep: 20, touchScrollStep: 200, borderRadius: "5px", railBorderRadius: "5px"}, h); | |||||
| this.each(function() { | |||||
| function r(d) { | |||||
| if (s) { | |||||
| d = d || | |||||
| window.event; | |||||
| var c = 0; | |||||
| d.wheelDelta && (c = -d.wheelDelta / 120); | |||||
| d.detail && (c = d.detail / 3); | |||||
| f(d.target || d.srcTarget || d.srcElement).closest("." + a.wrapperClass).is(b.parent()) && m(c, !0); | |||||
| d.preventDefault && !k && d.preventDefault(); | |||||
| k || (d.returnValue = !1) | |||||
| } | |||||
| } | |||||
| function m(d, f, h) { | |||||
| k = !1; | |||||
| var e = d, g = b.outerHeight() - c.outerHeight(); | |||||
| f && (e = parseInt(c.css("top")) + d * parseInt(a.wheelStep) / 100 * c.outerHeight(), e = Math.min(Math.max(e, 0), g), e = 0 < d ? Math.ceil(e) : Math.floor(e), c.css({top: e + "px"})); | |||||
| l = parseInt(c.css("top")) / (b.outerHeight() - c.outerHeight()); | |||||
| e = l * (b[0].scrollHeight - b.outerHeight()); | |||||
| h && (e = d, d = e / b[0].scrollHeight * b.outerHeight(), d = Math.min(Math.max(d, 0), g), c.css({top: d + "px"})); | |||||
| b.scrollTop(e); | |||||
| b.trigger("slimscrolling", ~~e); | |||||
| v(); | |||||
| p() | |||||
| } | |||||
| function C() { | |||||
| window.addEventListener ? (this.addEventListener("DOMMouseScroll", r, !1), this.addEventListener("mousewheel", r, !1), this.addEventListener("MozMousePixelScroll", r, !1)) : document.attachEvent("onmousewheel", r) | |||||
| } | |||||
| function w() { | |||||
| u = Math.max(b.outerHeight() / b[0].scrollHeight * b.outerHeight(), D); | |||||
| c.css({height: u + "px"}); | |||||
| var a = u == b.outerHeight() ? "none" : "block"; | |||||
| c.css({display: a}) | |||||
| } | |||||
| function v() { | |||||
| w(); | |||||
| clearTimeout(A); | |||||
| l == ~~l ? (k = a.allowPageScroll, B != l && b.trigger("slimscroll", 0 == ~~l ? "top" : "bottom")) : k = !1; | |||||
| B = l; | |||||
| u >= b.outerHeight() ? k = !0 : (c.stop(!0, !0).fadeIn("fast"), a.railVisible && g.stop(!0, !0).fadeIn("fast")) | |||||
| } | |||||
| function p() { | |||||
| a.alwaysVisible || (A = setTimeout(function() { | |||||
| a.disableFadeOut && s || (x || y) || (c.fadeOut("slow"), g.fadeOut("slow")) | |||||
| }, 1E3)) | |||||
| } | |||||
| var s, x, y, A, z, u, l, B, D = 30, k = !1, b = f(this); | |||||
| if (b.parent().hasClass(a.wrapperClass)) { | |||||
| var n = b.scrollTop(), | |||||
| c = b.parent().find("." + a.barClass), g = b.parent().find("." + a.railClass); | |||||
| w(); | |||||
| if (f.isPlainObject(h)) { | |||||
| if ("height"in h && "auto" == h.height) { | |||||
| b.parent().css("height", "auto"); | |||||
| b.css("height", "auto"); | |||||
| var q = b.parent().parent().height(); | |||||
| b.parent().css("height", q); | |||||
| b.css("height", q) | |||||
| } | |||||
| if ("scrollTo"in h) | |||||
| n = parseInt(a.scrollTo); | |||||
| else if ("scrollBy"in h) | |||||
| n += parseInt(a.scrollBy); | |||||
| else if ("destroy"in h) { | |||||
| c.remove(); | |||||
| g.remove(); | |||||
| b.unwrap(); | |||||
| return | |||||
| } | |||||
| m(n, !1, !0) | |||||
| } | |||||
| } else { | |||||
| a.height = "auto" == a.height ? b.parent().height() : a.height; | |||||
| n = f("<div></div>").addClass(a.wrapperClass).css({position: "relative", | |||||
| overflow: "hidden", width: a.width, height: a.height}); | |||||
| b.css({overflow: "hidden", width: a.width, height: a.height}); | |||||
| var g = f("<div></div>").addClass(a.railClass).css({width: a.size, height: "100%", position: "absolute", top: 0, display: a.alwaysVisible && a.railVisible ? "block" : "none", "border-radius": a.railBorderRadius, background: a.railColor, opacity: a.railOpacity, zIndex: 90}), c = f("<div></div>").addClass(a.barClass).css({background: a.color, width: a.size, position: "absolute", top: 0, opacity: a.opacity, display: a.alwaysVisible ? | |||||
| "block" : "none", "border-radius": a.borderRadius, BorderRadius: a.borderRadius, MozBorderRadius: a.borderRadius, WebkitBorderRadius: a.borderRadius, zIndex: 99}), q = "right" == a.position ? {right: a.distance} : {left: a.distance}; | |||||
| g.css(q); | |||||
| c.css(q); | |||||
| b.wrap(n); | |||||
| b.parent().append(c); | |||||
| b.parent().append(g); | |||||
| a.railDraggable && c.bind("mousedown", function(a) { | |||||
| var b = f(document); | |||||
| y = !0; | |||||
| t = parseFloat(c.css("top")); | |||||
| pageY = a.pageY; | |||||
| b.bind("mousemove.slimscroll", function(a) { | |||||
| currTop = t + a.pageY - pageY; | |||||
| c.css("top", currTop); | |||||
| m(0, c.position().top, !1) | |||||
| }); | |||||
| b.bind("mouseup.slimscroll", function(a) { | |||||
| y = !1; | |||||
| p(); | |||||
| b.unbind(".slimscroll") | |||||
| }); | |||||
| return!1 | |||||
| }).bind("selectstart.slimscroll", function(a) { | |||||
| a.stopPropagation(); | |||||
| a.preventDefault(); | |||||
| return!1 | |||||
| }); | |||||
| g.hover(function() { | |||||
| v() | |||||
| }, function() { | |||||
| p() | |||||
| }); | |||||
| c.hover(function() { | |||||
| x = !0 | |||||
| }, function() { | |||||
| x = !1 | |||||
| }); | |||||
| b.hover(function() { | |||||
| s = !0; | |||||
| v(); | |||||
| p() | |||||
| }, function() { | |||||
| s = !1; | |||||
| p() | |||||
| }); | |||||
| b.bind("touchstart", function(a, b) { | |||||
| a.originalEvent.touches.length && (z = a.originalEvent.touches[0].pageY) | |||||
| }); | |||||
| b.bind("touchmove", function(b) { | |||||
| k || b.originalEvent.preventDefault(); | |||||
| b.originalEvent.touches.length && | |||||
| (m((z - b.originalEvent.touches[0].pageY) / a.touchScrollStep, !0), z = b.originalEvent.touches[0].pageY) | |||||
| }); | |||||
| w(); | |||||
| "bottom" === a.start ? (c.css({top: b.outerHeight() - c.outerHeight()}), m(0, !0)) : "top" !== a.start && (m(f(a.start).position().top, null, !0), a.alwaysVisible || c.hide()); | |||||
| C() | |||||
| } | |||||
| }); | |||||
| return this | |||||
| }}); | |||||
| jQuery.fn.extend({slimscroll: jQuery.fn.slimScroll}) | |||||
| })(jQuery); | |||||
| /*! iCheck v1.0.1 by Damir Sultanov, http://git.io/arlzeA, MIT Licensed */ | |||||
| (function(h) { | |||||
| function F(a, b, d) { | |||||
| var c = a[0], e = /er/.test(d) ? m : /bl/.test(d) ? s : l, f = d == H ? {checked: c[l], disabled: c[s], indeterminate: "true" == a.attr(m) || "false" == a.attr(w)} : c[e]; | |||||
| if (/^(ch|di|in)/.test(d) && !f) | |||||
| D(a, e); | |||||
| else if (/^(un|en|de)/.test(d) && f) | |||||
| t(a, e); | |||||
| else if (d == H) | |||||
| for (e in f) | |||||
| f[e] ? D(a, e, !0) : t(a, e, !0); | |||||
| else if (!b || "toggle" == d) { | |||||
| if (!b) | |||||
| a[p]("ifClicked"); | |||||
| f ? c[n] !== u && t(a, e) : D(a, e) | |||||
| } | |||||
| } | |||||
| function D(a, b, d) { | |||||
| var c = a[0], e = a.parent(), f = b == l, A = b == m, B = b == s, K = A ? w : f ? E : "enabled", p = k(a, K + x(c[n])), N = k(a, b + x(c[n])); | |||||
| if (!0 !== c[b]) { | |||||
| if (!d && | |||||
| b == l && c[n] == u && c.name) { | |||||
| var C = a.closest("form"), r = 'input[name="' + c.name + '"]', r = C.length ? C.find(r) : h(r); | |||||
| r.each(function() { | |||||
| this !== c && h(this).data(q) && t(h(this), b) | |||||
| }) | |||||
| } | |||||
| A ? (c[b] = !0, c[l] && t(a, l, "force")) : (d || (c[b] = !0), f && c[m] && t(a, m, !1)); | |||||
| L(a, f, b, d) | |||||
| } | |||||
| c[s] && k(a, y, !0) && e.find("." + I).css(y, "default"); | |||||
| e[v](N || k(a, b) || ""); | |||||
| B ? e.attr("aria-disabled", "true") : e.attr("aria-checked", A ? "mixed" : "true"); | |||||
| e[z](p || k(a, K) || "") | |||||
| } | |||||
| function t(a, b, d) { | |||||
| var c = a[0], e = a.parent(), f = b == l, h = b == m, q = b == s, p = h ? w : f ? E : "enabled", t = k(a, p + x(c[n])), | |||||
| u = k(a, b + x(c[n])); | |||||
| if (!1 !== c[b]) { | |||||
| if (h || !d || "force" == d) | |||||
| c[b] = !1; | |||||
| L(a, f, p, d) | |||||
| } | |||||
| !c[s] && k(a, y, !0) && e.find("." + I).css(y, "pointer"); | |||||
| e[z](u || k(a, b) || ""); | |||||
| q ? e.attr("aria-disabled", "false") : e.attr("aria-checked", "false"); | |||||
| e[v](t || k(a, p) || "") | |||||
| } | |||||
| function M(a, b) { | |||||
| if (a.data(q)) { | |||||
| a.parent().html(a.attr("style", a.data(q).s || "")); | |||||
| if (b) | |||||
| a[p](b); | |||||
| a.off(".i").unwrap(); | |||||
| h(G + '[for="' + a[0].id + '"]').add(a.closest(G)).off(".i") | |||||
| } | |||||
| } | |||||
| function k(a, b, d) { | |||||
| if (a.data(q)) | |||||
| return a.data(q).o[b + (d ? "" : "Class")] | |||||
| } | |||||
| function x(a) { | |||||
| return a.charAt(0).toUpperCase() + | |||||
| a.slice(1) | |||||
| } | |||||
| function L(a, b, d, c) { | |||||
| if (!c) { | |||||
| if (b) | |||||
| a[p]("ifToggled"); | |||||
| a[p]("ifChanged")[p]("if" + x(d)) | |||||
| } | |||||
| } | |||||
| var q = "iCheck", I = q + "-helper", u = "radio", l = "checked", E = "un" + l, s = "disabled", w = "determinate", m = "in" + w, H = "update", n = "type", v = "addClass", z = "removeClass", p = "trigger", G = "label", y = "cursor", J = /ipad|iphone|ipod|android|blackberry|windows phone|opera mini|silk/i.test(navigator.userAgent); | |||||
| h.fn[q] = function(a, b) { | |||||
| var d = 'input[type="checkbox"], input[type="' + u + '"]', c = h(), e = function(a) { | |||||
| a.each(function() { | |||||
| var a = h(this); | |||||
| c = a.is(d) ? | |||||
| c.add(a) : c.add(a.find(d)) | |||||
| }) | |||||
| }; | |||||
| if (/^(check|uncheck|toggle|indeterminate|determinate|disable|enable|update|destroy)$/i.test(a)) | |||||
| return a = a.toLowerCase(), e(this), c.each(function() { | |||||
| var c = h(this); | |||||
| "destroy" == a ? M(c, "ifDestroyed") : F(c, !0, a); | |||||
| h.isFunction(b) && b() | |||||
| }); | |||||
| if ("object" != typeof a && a) | |||||
| return this; | |||||
| var f = h.extend({checkedClass: l, disabledClass: s, indeterminateClass: m, labelHover: !0, aria: !1}, a), k = f.handle, B = f.hoverClass || "hover", x = f.focusClass || "focus", w = f.activeClass || "active", y = !!f.labelHover, C = f.labelHoverClass || | |||||
| "hover", r = ("" + f.increaseArea).replace("%", "") | 0; | |||||
| if ("checkbox" == k || k == u) | |||||
| d = 'input[type="' + k + '"]'; | |||||
| -50 > r && (r = -50); | |||||
| e(this); | |||||
| return c.each(function() { | |||||
| var a = h(this); | |||||
| M(a); | |||||
| var c = this, b = c.id, e = -r + "%", d = 100 + 2 * r + "%", d = {position: "absolute", top: e, left: e, display: "block", width: d, height: d, margin: 0, padding: 0, background: "#fff", border: 0, opacity: 0}, e = J ? {position: "absolute", visibility: "hidden"} : r ? d : {position: "absolute", opacity: 0}, k = "checkbox" == c[n] ? f.checkboxClass || "icheckbox" : f.radioClass || "i" + u, m = h(G + '[for="' + b + '"]').add(a.closest(G)), | |||||
| A = !!f.aria, E = q + "-" + Math.random().toString(36).replace("0.", ""), g = '<div class="' + k + '" ' + (A ? 'role="' + c[n] + '" ' : ""); | |||||
| m.length && A && m.each(function() { | |||||
| g += 'aria-labelledby="'; | |||||
| this.id ? g += this.id : (this.id = E, g += E); | |||||
| g += '"' | |||||
| }); | |||||
| g = a.wrap(g + "/>")[p]("ifCreated").parent().append(f.insert); | |||||
| d = h('<ins class="' + I + '"/>').css(d).appendTo(g); | |||||
| a.data(q, {o: f, s: a.attr("style")}).css(e); | |||||
| f.inheritClass && g[v](c.className || ""); | |||||
| f.inheritID && b && g.attr("id", q + "-" + b); | |||||
| "static" == g.css("position") && g.css("position", "relative"); | |||||
| F(a, !0, H); | |||||
| if (m.length) | |||||
| m.on("click.i mouseover.i mouseout.i touchbegin.i touchend.i", function(b) { | |||||
| var d = b[n], e = h(this); | |||||
| if (!c[s]) { | |||||
| if ("click" == d) { | |||||
| if (h(b.target).is("a")) | |||||
| return; | |||||
| F(a, !1, !0) | |||||
| } else | |||||
| y && (/ut|nd/.test(d) ? (g[z](B), e[z](C)) : (g[v](B), e[v](C))); | |||||
| if (J) | |||||
| b.stopPropagation(); | |||||
| else | |||||
| return!1 | |||||
| } | |||||
| }); | |||||
| a.on("click.i focus.i blur.i keyup.i keydown.i keypress.i", function(b) { | |||||
| var d = b[n]; | |||||
| b = b.keyCode; | |||||
| if ("click" == d) | |||||
| return!1; | |||||
| if ("keydown" == d && 32 == b) | |||||
| return c[n] == u && c[l] || (c[l] ? t(a, l) : D(a, l)), !1; | |||||
| if ("keyup" == d && c[n] == u) | |||||
| !c[l] && D(a, l); | |||||
| else if (/us|ur/.test(d)) | |||||
| g["blur" == | |||||
| d ? z : v](x) | |||||
| }); | |||||
| d.on("click mousedown mouseup mouseover mouseout touchbegin.i touchend.i", function(b) { | |||||
| var d = b[n], e = /wn|up/.test(d) ? w : B; | |||||
| if (!c[s]) { | |||||
| if ("click" == d) | |||||
| F(a, !1, !0); | |||||
| else { | |||||
| if (/wn|er|in/.test(d)) | |||||
| g[v](e); | |||||
| else | |||||
| g[z](e + " " + w); | |||||
| if (m.length && y && e == B) | |||||
| m[/ut|nd/.test(d) ? z : v](C) | |||||
| } | |||||
| if (J) | |||||
| b.stopPropagation(); | |||||
| else | |||||
| return!1 | |||||
| } | |||||
| }) | |||||
| }) | |||||
| } | |||||
| })(window.jQuery || window.Zepto); | |||||
| @@ -0,0 +1,221 @@ | |||||
| /*! | |||||
| * jQuery Mousewheel 3.1.13 | |||||
| * | |||||
| * Copyright jQuery Foundation and other contributors | |||||
| * Released under the MIT license | |||||
| * http://jquery.org/license | |||||
| */ | |||||
| (function (factory) { | |||||
| if ( typeof define === 'function' && define.amd ) { | |||||
| // AMD. Register as an anonymous module. | |||||
| define(['jquery'], factory); | |||||
| } else if (typeof exports === 'object') { | |||||
| // Node/CommonJS style for Browserify | |||||
| module.exports = factory; | |||||
| } else { | |||||
| // Browser globals | |||||
| factory(jQuery); | |||||
| } | |||||
| }(function ($) { | |||||
| var toFix = ['wheel', 'mousewheel', 'DOMMouseScroll', 'MozMousePixelScroll'], | |||||
| toBind = ( 'onwheel' in document || document.documentMode >= 9 ) ? | |||||
| ['wheel'] : ['mousewheel', 'DomMouseScroll', 'MozMousePixelScroll'], | |||||
| slice = Array.prototype.slice, | |||||
| nullLowestDeltaTimeout, lowestDelta; | |||||
| if ( $.event.fixHooks ) { | |||||
| for ( var i = toFix.length; i; ) { | |||||
| $.event.fixHooks[ toFix[--i] ] = $.event.mouseHooks; | |||||
| } | |||||
| } | |||||
| var special = $.event.special.mousewheel = { | |||||
| version: '3.1.12', | |||||
| setup: function() { | |||||
| if ( this.addEventListener ) { | |||||
| for ( var i = toBind.length; i; ) { | |||||
| this.addEventListener( toBind[--i], handler, false ); | |||||
| } | |||||
| } else { | |||||
| this.onmousewheel = handler; | |||||
| } | |||||
| // Store the line height and page height for this particular element | |||||
| $.data(this, 'mousewheel-line-height', special.getLineHeight(this)); | |||||
| $.data(this, 'mousewheel-page-height', special.getPageHeight(this)); | |||||
| }, | |||||
| teardown: function() { | |||||
| if ( this.removeEventListener ) { | |||||
| for ( var i = toBind.length; i; ) { | |||||
| this.removeEventListener( toBind[--i], handler, false ); | |||||
| } | |||||
| } else { | |||||
| this.onmousewheel = null; | |||||
| } | |||||
| // Clean up the data we added to the element | |||||
| $.removeData(this, 'mousewheel-line-height'); | |||||
| $.removeData(this, 'mousewheel-page-height'); | |||||
| }, | |||||
| getLineHeight: function(elem) { | |||||
| var $elem = $(elem), | |||||
| $parent = $elem['offsetParent' in $.fn ? 'offsetParent' : 'parent'](); | |||||
| if (!$parent.length) { | |||||
| $parent = $('body'); | |||||
| } | |||||
| return parseInt($parent.css('fontSize'), 10) || parseInt($elem.css('fontSize'), 10) || 16; | |||||
| }, | |||||
| getPageHeight: function(elem) { | |||||
| return $(elem).height(); | |||||
| }, | |||||
| settings: { | |||||
| adjustOldDeltas: true, // see shouldAdjustOldDeltas() below | |||||
| normalizeOffset: true // calls getBoundingClientRect for each event | |||||
| } | |||||
| }; | |||||
| $.fn.extend({ | |||||
| mousewheel: function(fn) { | |||||
| return fn ? this.bind('mousewheel', fn) : this.trigger('mousewheel'); | |||||
| }, | |||||
| unmousewheel: function(fn) { | |||||
| return this.unbind('mousewheel', fn); | |||||
| } | |||||
| }); | |||||
| function handler(event) { | |||||
| var orgEvent = event || window.event, | |||||
| args = slice.call(arguments, 1), | |||||
| delta = 0, | |||||
| deltaX = 0, | |||||
| deltaY = 0, | |||||
| absDelta = 0, | |||||
| offsetX = 0, | |||||
| offsetY = 0; | |||||
| event = $.event.fix(orgEvent); | |||||
| event.type = 'mousewheel'; | |||||
| // Old school scrollwheel delta | |||||
| if ( 'detail' in orgEvent ) { deltaY = orgEvent.detail * -1; } | |||||
| if ( 'wheelDelta' in orgEvent ) { deltaY = orgEvent.wheelDelta; } | |||||
| if ( 'wheelDeltaY' in orgEvent ) { deltaY = orgEvent.wheelDeltaY; } | |||||
| if ( 'wheelDeltaX' in orgEvent ) { deltaX = orgEvent.wheelDeltaX * -1; } | |||||
| // Firefox < 17 horizontal scrolling related to DOMMouseScroll event | |||||
| if ( 'axis' in orgEvent && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) { | |||||
| deltaX = deltaY * -1; | |||||
| deltaY = 0; | |||||
| } | |||||
| // Set delta to be deltaY or deltaX if deltaY is 0 for backwards compatabilitiy | |||||
| delta = deltaY === 0 ? deltaX : deltaY; | |||||
| // New school wheel delta (wheel event) | |||||
| if ( 'deltaY' in orgEvent ) { | |||||
| deltaY = orgEvent.deltaY * -1; | |||||
| delta = deltaY; | |||||
| } | |||||
| if ( 'deltaX' in orgEvent ) { | |||||
| deltaX = orgEvent.deltaX; | |||||
| if ( deltaY === 0 ) { delta = deltaX * -1; } | |||||
| } | |||||
| // No change actually happened, no reason to go any further | |||||
| if ( deltaY === 0 && deltaX === 0 ) { return; } | |||||
| // Need to convert lines and pages to pixels if we aren't already in pixels | |||||
| // There are three delta modes: | |||||
| // * deltaMode 0 is by pixels, nothing to do | |||||
| // * deltaMode 1 is by lines | |||||
| // * deltaMode 2 is by pages | |||||
| if ( orgEvent.deltaMode === 1 ) { | |||||
| var lineHeight = $.data(this, 'mousewheel-line-height'); | |||||
| delta *= lineHeight; | |||||
| deltaY *= lineHeight; | |||||
| deltaX *= lineHeight; | |||||
| } else if ( orgEvent.deltaMode === 2 ) { | |||||
| var pageHeight = $.data(this, 'mousewheel-page-height'); | |||||
| delta *= pageHeight; | |||||
| deltaY *= pageHeight; | |||||
| deltaX *= pageHeight; | |||||
| } | |||||
| // Store lowest absolute delta to normalize the delta values | |||||
| absDelta = Math.max( Math.abs(deltaY), Math.abs(deltaX) ); | |||||
| if ( !lowestDelta || absDelta < lowestDelta ) { | |||||
| lowestDelta = absDelta; | |||||
| // Adjust older deltas if necessary | |||||
| if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) { | |||||
| lowestDelta /= 40; | |||||
| } | |||||
| } | |||||
| // Adjust older deltas if necessary | |||||
| if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) { | |||||
| // Divide all the things by 40! | |||||
| delta /= 40; | |||||
| deltaX /= 40; | |||||
| deltaY /= 40; | |||||
| } | |||||
| // Get a whole, normalized value for the deltas | |||||
| delta = Math[ delta >= 1 ? 'floor' : 'ceil' ](delta / lowestDelta); | |||||
| deltaX = Math[ deltaX >= 1 ? 'floor' : 'ceil' ](deltaX / lowestDelta); | |||||
| deltaY = Math[ deltaY >= 1 ? 'floor' : 'ceil' ](deltaY / lowestDelta); | |||||
| // Normalise offsetX and offsetY properties | |||||
| if ( special.settings.normalizeOffset && this.getBoundingClientRect ) { | |||||
| var boundingRect = this.getBoundingClientRect(); | |||||
| offsetX = event.clientX - boundingRect.left; | |||||
| offsetY = event.clientY - boundingRect.top; | |||||
| } | |||||
| // Add information to the event object | |||||
| event.deltaX = deltaX; | |||||
| event.deltaY = deltaY; | |||||
| event.deltaFactor = lowestDelta; | |||||
| event.offsetX = offsetX; | |||||
| event.offsetY = offsetY; | |||||
| // Go ahead and set deltaMode to 0 since we converted to pixels | |||||
| // Although this is a little odd since we overwrite the deltaX/Y | |||||
| // properties with normalized deltas. | |||||
| event.deltaMode = 0; | |||||
| // Add event and delta to the front of the arguments | |||||
| args.unshift(event, delta, deltaX, deltaY); | |||||
| // Clearout lowestDelta after sometime to better | |||||
| // handle multiple device types that give different | |||||
| // a different lowestDelta | |||||
| // Ex: trackpad = 3 and mouse wheel = 120 | |||||
| if (nullLowestDeltaTimeout) { clearTimeout(nullLowestDeltaTimeout); } | |||||
| nullLowestDeltaTimeout = setTimeout(nullLowestDelta, 200); | |||||
| return ($.event.dispatch || $.event.handle).apply(this, args); | |||||
| } | |||||
| function nullLowestDelta() { | |||||
| lowestDelta = null; | |||||
| } | |||||
| function shouldAdjustOldDeltas(orgEvent, absDelta) { | |||||
| // If this is an older event and the delta is divisable by 120, | |||||
| // then we are assuming that the browser is treating this as an | |||||
| // older mouse wheel event and that we should divide the deltas | |||||
| // by 40 to try and get a more usable deltaFactor. | |||||
| // Side note, this actually impacts the reported scroll distance | |||||
| // in older browsers and can cause scrolling to be slower than native. | |||||
| // Turn this off by setting $.event.special.mousewheel.settings.adjustOldDeltas to false. | |||||
| return special.settings.adjustOldDeltas && orgEvent.type === 'mousewheel' && absDelta % 120 === 0; | |||||
| } | |||||
| })); | |||||
| @@ -0,0 +1,965 @@ | |||||
| var token; | |||||
| if(isEmpty(token)){ | |||||
| var meta = $("meta[name=_uid]"); | |||||
| if(!isEmpty(meta)){ | |||||
| token = meta.attr("content"); | |||||
| console.log("token is uid:" + token); | |||||
| } | |||||
| } | |||||
| var authorMeta = $("meta[name=author]"); | |||||
| var userName; | |||||
| if(!isEmpty(authorMeta)){ | |||||
| userName = authorMeta.attr("content"); | |||||
| console.log("user name=" + userName); | |||||
| } | |||||
| var userType; | |||||
| if(isEmpty(userType)){ | |||||
| userType =1; | |||||
| } | |||||
| var ip = getIp(); | |||||
| var pageSize = 10; | |||||
| var tableData; | |||||
| var tablePageData; | |||||
| var preDictTaskData; | |||||
| var dataSetTaskData; | |||||
| var userInfoData; | |||||
| var labelPropertyData; | |||||
| var repoId = $('#repoId').val(); | |||||
| console.log("repoId=" + repoId); | |||||
| function setDataSetTask(){ | |||||
| dataset_task_list(); | |||||
| display_createdatasetlabel(0); | |||||
| //getUser(); | |||||
| //dislpayUser(); | |||||
| getLabelPropertyTask(); | |||||
| displayLabelPropertyTask(); | |||||
| $(".ui.dataset.modal").modal("show"); | |||||
| } | |||||
| function getLabelPropertyTask(){ | |||||
| $.ajax({ | |||||
| type:"GET", | |||||
| url:ip + "/api/label-property-task-all/", | |||||
| headers: { | |||||
| authorization:token, | |||||
| }, | |||||
| dataType:"json", | |||||
| async:false, | |||||
| success:function(json){ | |||||
| labelPropertyData = json; | |||||
| console.log(json); | |||||
| }, | |||||
| error:function(response) { | |||||
| redirect(response); | |||||
| } | |||||
| }); | |||||
| } | |||||
| function displayLabelPropertyTask(){ | |||||
| var html="<option value=\"\" selected=\"\">请选择</option>"; | |||||
| for (var i=0;i<labelPropertyData.length;i++){ | |||||
| var row = "<option value=\""+labelPropertyData[i].id+ | |||||
| "\">"+labelPropertyData[i].task_name + | |||||
| "</option>"; | |||||
| html=html+row; | |||||
| } | |||||
| console.log(html); | |||||
| document.getElementById('labelpropertytask_dataset').innerHTML=html; | |||||
| document.getElementById('labelpropertytask_auto').innerHTML=html; | |||||
| } | |||||
| function dataset_task_list(){ | |||||
| $.ajax({ | |||||
| type:"GET", | |||||
| url:ip + "/gitea-dataset/", | |||||
| headers: { | |||||
| authorization:token, | |||||
| }, | |||||
| dataType:"json", | |||||
| data:{ | |||||
| 'repoId':repoId, | |||||
| 'dateset_type':'[1]' | |||||
| }, | |||||
| async:false, | |||||
| success:function(json){ | |||||
| dataSetTaskData = json; | |||||
| console.log(json); | |||||
| // return json.token; | |||||
| }, | |||||
| error:function(response) { | |||||
| redirect(response); | |||||
| } | |||||
| }); | |||||
| } | |||||
| function countLabel(){ | |||||
| $.ajax({ | |||||
| type:"GET", | |||||
| url:ip + "/gitea/label-count/", | |||||
| headers: { | |||||
| authorization:token, | |||||
| }, | |||||
| dataType:"json", | |||||
| async:false, | |||||
| success:function(json){ | |||||
| alert("请等待几分钟,服务端正在加紧统计。"); | |||||
| }, | |||||
| error:function(response) { | |||||
| redirect(response); | |||||
| } | |||||
| }); | |||||
| } | |||||
| function display_createdatasetlabel(sindex=-1){ | |||||
| var html=""; | |||||
| for (var i=0;i<dataSetTaskData.length;i++){ | |||||
| if (i==sindex){ | |||||
| var row = "<option value=\""+dataSetTaskData[i].id+ | |||||
| "\" selected=\"\">"+dataSetTaskData[i].task_name+ | |||||
| "</option>"; | |||||
| $("#datasetlabeltaskname").attr({value:dataSetTaskData[i].task_name + "-人工标注"}); | |||||
| }else{ | |||||
| var row = "<option value=\""+dataSetTaskData[i].id+ | |||||
| "\">"+dataSetTaskData[i].task_name+ | |||||
| "</option>"; | |||||
| } | |||||
| html=html+row; | |||||
| } | |||||
| console.log(html); | |||||
| document.getElementById('dataset_list').innerHTML=html; | |||||
| } | |||||
| function setPredictTask(){ | |||||
| pre_predict_task_list(); | |||||
| display_createlabel(0); | |||||
| getUser(); | |||||
| dislpayUser(); | |||||
| getLabelPropertyTask(); | |||||
| displayLabelPropertyTask(); | |||||
| } | |||||
| function pre_predict_task_list(){ | |||||
| $.ajax({ | |||||
| type:"GET", | |||||
| url:ip + "/api/pre-predict-taskforLabel/", | |||||
| headers: { | |||||
| authorization:token, | |||||
| }, | |||||
| dataType:"json", | |||||
| async:false, | |||||
| success:function(json){ | |||||
| preDictTaskData = json; | |||||
| console.log(json); | |||||
| // return json.token; | |||||
| }, | |||||
| error:function(response) { | |||||
| redirect(response); | |||||
| } | |||||
| }); | |||||
| } | |||||
| function sele_Change(sele){ | |||||
| var predictTaskName = $('#pre_predict_task_for_label option:selected').text(); | |||||
| console.log("select predictTaskName =" + predictTaskName); | |||||
| $("#labeltaskname").attr({value:predictTaskName+"-人工标注"}); | |||||
| } | |||||
| function sele_export_Change(sele){ | |||||
| var isNeedPicture = $('#isNeedPicture option:selected').val(); | |||||
| if(isNeedPicture == 3){ | |||||
| document.getElementById("maxscore_div").style.display="block"; | |||||
| document.getElementById("minscore_div").style.display="block"; | |||||
| $('#maxscore').val("1.0"); | |||||
| $('#minscore').val("0.6"); | |||||
| }else{ | |||||
| document.getElementById("maxscore_div").style.display="none"; | |||||
| document.getElementById("minscore_div").style.display="none"; | |||||
| $('#maxscore').val(""); | |||||
| $('#minscore').val(""); | |||||
| } | |||||
| } | |||||
| function dataset_sele_Change(sele){ | |||||
| var dataset_listName = $('#dataset_list option:selected').text(); | |||||
| console.log("select dataset_list =" + dataset_listName); | |||||
| $("#datasetlabeltaskname").attr({value:dataset_listName+"-人工标注"}); | |||||
| } | |||||
| function display_createlabel(sindex=-1){ | |||||
| var html=""; | |||||
| for (var i=0;i<preDictTaskData.length;i++){ | |||||
| if (i==sindex){ | |||||
| var row = "<option value=\""+preDictTaskData[i].id+ | |||||
| "\" selected=\"\">"+preDictTaskData[i].task_name+ | |||||
| "</option>"; | |||||
| $("#labeltaskname").attr({value:preDictTaskData[i].task_name + "-人工标注"}); | |||||
| }else{ | |||||
| var row = "<option value=\""+preDictTaskData[i].id+ | |||||
| "\">"+preDictTaskData[i].task_name+ | |||||
| "</option>"; | |||||
| } | |||||
| html=html+row; | |||||
| } | |||||
| console.log(html); | |||||
| document.getElementById('pre_predict_task_for_label').innerHTML=html; | |||||
| } | |||||
| var createsucced; | |||||
| function submit_datasettask(){ | |||||
| console.log($('#datasetlabeltaskname').val()); | |||||
| var task_name = $('#datasetlabeltaskname').val(); | |||||
| if (isEmpty(task_name) || task_name.length > 32){ | |||||
| alert("人工标注任务名称不能为空或者不能超过32个字符。"); | |||||
| return; | |||||
| } | |||||
| var assign_user_id = $('#assign_user option:selected').val(); | |||||
| if(isEmpty(assign_user_id)){ | |||||
| assign_user_id = token; | |||||
| } | |||||
| var relate_task_id = $('#dataset_list option:selected').val(); | |||||
| if(isEmpty(relate_task_id)){ | |||||
| alert("数据集对象不能为空。"); | |||||
| return; | |||||
| } | |||||
| var labelpropertytaskid = $('#labelpropertytask_dataset option:selected').val(); | |||||
| createsucced = true; | |||||
| label_task_create(task_name, relate_task_id, 2,assign_user_id,labelpropertytaskid); | |||||
| if(createsucced){ | |||||
| $(".ui.dataset.modal").modal("hide"); | |||||
| //$("#labelDataModal").modal('hide'); | |||||
| } | |||||
| page(0,pageSize); | |||||
| } | |||||
| function submit_labeltask(){ | |||||
| console.log($('#labeltaskname').val()); | |||||
| var task_name = $('#labeltaskname').val(); | |||||
| if (isEmpty(task_name) || task_name.length > 32){ | |||||
| alert("人工标注任务名称不能为空或者不能超过32个字符。"); | |||||
| return; | |||||
| } | |||||
| var relate_task_id = $('#pre_predict_task_for_label option:selected').val(); | |||||
| if(isEmpty(relate_task_id)){ | |||||
| alert("关联的自动标注任务不能为空。"); | |||||
| return; | |||||
| } | |||||
| var assign_user_id = $('#label_assign_user option:selected').val(); | |||||
| if(isEmpty(assign_user_id)){ | |||||
| assign_user_id = token; | |||||
| } | |||||
| var labelpropertytaskid = $('#labelpropertytask_dataset option:selected').val(); | |||||
| createsucced = true; | |||||
| label_task_create(task_name, relate_task_id, 1,assign_user_id,labelpropertytaskid); | |||||
| if(createsucced){ | |||||
| $("#labelModal").modal('hide'); | |||||
| } | |||||
| page(0,pageSize); | |||||
| } | |||||
| function label_task_create(task_name, relate_task_id, taskType,assign_user_id,labelpropertytaskid){ | |||||
| var task_flow_type = $('#task_flow_type option:selected').val(); | |||||
| var relate_other_label_task = []; | |||||
| if(task_flow_type == 2){ | |||||
| var items = document.getElementsByName("category"); | |||||
| for (i = 0; i < items.length; i++) { | |||||
| if (items[i].checked) { | |||||
| relate_other_label_task.push(items[i].value); | |||||
| } | |||||
| } | |||||
| } | |||||
| relate_other_label_task_jsonstr = JSON.stringify(relate_other_label_task); | |||||
| console.log("relate_task_id=" + relate_task_id); | |||||
| $.ajax({ | |||||
| type:"POST", | |||||
| contentType:'application/json', | |||||
| url:ip + "/gitea/label-task/", | |||||
| dataType:"json", | |||||
| async:false, | |||||
| headers: { | |||||
| authorization:token, | |||||
| }, | |||||
| beforeSend: function (xhr) { | |||||
| xhr.withCredentials = true | |||||
| }, | |||||
| data:JSON.stringify({'task_name':task_name, | |||||
| 'assign_user_id':assign_user_id, | |||||
| 'task_flow_type':task_flow_type, | |||||
| 'relate_task_id':relate_task_id,//task id | |||||
| 'relate_other_label_task': relate_other_label_task_jsonstr, | |||||
| "taskType": taskType, | |||||
| "appid": repoId, | |||||
| "createUserName":userName, | |||||
| "labelPropertyTaskId":labelpropertytaskid | |||||
| }), | |||||
| success:function(res){ | |||||
| console.log(res); | |||||
| if(res.code == 0){ | |||||
| alert("人工校验任务创建成功!"); | |||||
| createsucced = true; | |||||
| } | |||||
| else{ | |||||
| alert("创建人工标注任务失败," + res.message); | |||||
| createsucced = false; | |||||
| } | |||||
| }, | |||||
| error:function(response) { | |||||
| redirect(response); | |||||
| } | |||||
| }); | |||||
| } | |||||
| function list(current,pageSize){ | |||||
| $.ajax({ | |||||
| type:"GET", | |||||
| url:ip + "/gitea/label-task-page/", | |||||
| headers: { | |||||
| authorization:token, | |||||
| }, | |||||
| dataType:"json", | |||||
| data:{'startPage':current, | |||||
| 'pageSize':pageSize}, | |||||
| async:false, | |||||
| success:function(json){ | |||||
| tablePageData = json; | |||||
| tableData = json.data; | |||||
| //console.log(json); | |||||
| }, | |||||
| error:function(response) { | |||||
| redirect(response); | |||||
| } | |||||
| }); | |||||
| } | |||||
| var otherUserLabelTaskData; | |||||
| function flow_type_sele_Change(sele){ | |||||
| var task_flow_type = $('#task_flow_type option:selected').val(); | |||||
| if(task_flow_type == 2){ | |||||
| var datasetid = $('#dataset_list option:selected').val(); | |||||
| getOtherUserLabelTaskByDataSetId(datasetid); | |||||
| var html = "<p>请选择该数据集要审核的标注任务</p>"; | |||||
| for(var i = 0; i < otherUserLabelTaskData.length; i++){ | |||||
| html += "<p><input type=\"checkbox\" name=\"category\" value=\"" + otherUserLabelTaskData[i].id + "\"/>" + otherUserLabelTaskData[i].task_name + "(标注人:" + otherUserLabelTaskData[i].assign_user + ")" + "</p>"; | |||||
| } | |||||
| document.getElementById('related_task_list').innerHTML=html; | |||||
| }else{ | |||||
| document.getElementById('related_task_list').innerHTML= ""; | |||||
| } | |||||
| } | |||||
| function getOtherUserLabelTaskByDataSetId(datasetid){ | |||||
| $.ajax({ | |||||
| type:"GET", | |||||
| url:ip + "/gitea/label-related-task/" + datasetid + "/", | |||||
| headers: { | |||||
| authorization:token, | |||||
| }, | |||||
| dataType:"json", | |||||
| async:false, | |||||
| success:function(json){ | |||||
| otherUserLabelTaskData = json; | |||||
| console.log(json); | |||||
| }, | |||||
| error:function(response) { | |||||
| redirect(response); | |||||
| } | |||||
| }); | |||||
| } | |||||
| function dislpayUser(){ | |||||
| var html="<option value=\"\" selected=\"\">请选择</option>"; | |||||
| for (var i=0;i<userInfoData.length;i++){ | |||||
| var row = "<option value=\""+userInfoData[i].id+ | |||||
| "\">"+userInfoData[i].username+ | |||||
| "</option>"; | |||||
| html=html+row; | |||||
| } | |||||
| console.log(html); | |||||
| document.getElementById('assign_user').innerHTML=html; | |||||
| document.getElementById('label_assign_user').innerHTML=html; | |||||
| } | |||||
| function getUser(){ | |||||
| $.ajax({ | |||||
| type:"GET", | |||||
| url:ip + "/api/queryAllUser/", | |||||
| headers: { | |||||
| authorization:token, | |||||
| }, | |||||
| dataType:"json", | |||||
| async:false, | |||||
| success:function(json){ | |||||
| userInfoData = json; | |||||
| console.log(json); | |||||
| }, | |||||
| error:function(response) { | |||||
| redirect(response); | |||||
| } | |||||
| }); | |||||
| } | |||||
| function delete_labeltask(){ | |||||
| var stop = del(); | |||||
| if (stop){ | |||||
| return; | |||||
| } | |||||
| var Check = $("table[id='label_task_list'] input[type=checkbox]:checked");//在table中找input下类型为checkbox属性为选中状态的数据 | |||||
| Check.each(function () {//遍历 | |||||
| var row = $(this).parent("td").parent("tr");//获取选中行 | |||||
| var id = row.find("[id='labeltask_id']").html();//获取name='Sid'的值 | |||||
| delete_labeltask_byid(id); | |||||
| }); | |||||
| page(0,pageSize); | |||||
| } | |||||
| function del(){ | |||||
| if($("table[id='label_task_list'] input[type=checkbox]").is(":checked")) { | |||||
| if (confirm("确实要删除吗?")) { | |||||
| // alert("已经删除!"); | |||||
| return false; | |||||
| } else { | |||||
| // alert("已经取消了删除操作"); | |||||
| return true; | |||||
| } | |||||
| }else if($("table[id='label_task_list']").find("input").length=="0"){ | |||||
| alert("暂无可删的数据!"); | |||||
| return true; | |||||
| }else{ | |||||
| alert("请先选择需要删除的选项!"); | |||||
| return true; | |||||
| } | |||||
| } | |||||
| function delete_labeltask_byid(label_task_id){ | |||||
| $.ajax({ | |||||
| type:"DELETE", | |||||
| url:ip + "/gitea/label-task/", | |||||
| headers: { | |||||
| authorization:token, | |||||
| }, | |||||
| dataType:"json", | |||||
| async:false, | |||||
| data:{'label_task_id': label_task_id}, | |||||
| success:function(json){ | |||||
| console.log(json); | |||||
| }, | |||||
| error:function(response) { | |||||
| redirect(response); | |||||
| } | |||||
| }); | |||||
| } | |||||
| function getTaskTypeDesc(task_type){ | |||||
| if(task_type == 1){ | |||||
| return "自动标注结果"; | |||||
| }else if(task_type == 2){ | |||||
| return "原始数据集-图片"; | |||||
| }else if(task_type == 3){ | |||||
| return "原始数据集-CT影像"; | |||||
| }else if(task_type == 4){ | |||||
| return "原始数据集-视频"; | |||||
| } | |||||
| return "其它"; | |||||
| } | |||||
| function getLabelDesc(task_flow_type){ | |||||
| if(task_flow_type == 2){ | |||||
| return "审核"; | |||||
| }else{ | |||||
| return "人工" | |||||
| } | |||||
| } | |||||
| function getTaskSataus(task_status,task_status_desc){ | |||||
| if(task_status == 0){ | |||||
| return "标注中:" + task_status_desc; | |||||
| }else if(task_status == 1){ | |||||
| return "审核中:" + task_status_desc; | |||||
| } | |||||
| else if(task_status == -1){ | |||||
| return "关联的数据集已经被删除。" | |||||
| } | |||||
| } | |||||
| function getVerify(task_status,id,task_type){ | |||||
| console.log("task_status=" + task_status + " userType=" + userType); | |||||
| if(task_status == 0 && (userType == 1 || userType == 0) ){ | |||||
| return "<a onclick=\"startToVerify(\'"+id+"\',\'" + task_type +"\');\" class=\"btn btn-xs btn-success\">转审核</a> "; | |||||
| }else if(task_status == 1 && userType == 2){ | |||||
| return "<a onclick=\"goVerify(\'"+id+"\',\'" + task_type +"\');\" class=\"btn btn-xs btn-success\">进入审核</a> " + "<a onclick=\"startToLabel(\'"+id+"\',\'" + task_type +"\');\" class=\"btn btn-xs btn-success\">转标注</a> "; | |||||
| }else{ | |||||
| return ""; | |||||
| } | |||||
| } | |||||
| function getLabel(task_status,id,task_type,task_flow_type){ | |||||
| if(task_status == 0 && (userType == 1 || userType == 0)){ | |||||
| return "<a onclick=\"personLabel(\'" + id + "\'," + task_type + ")\"><b>" + getLabelDesc(task_flow_type) + "标注</b></a><br>"; | |||||
| }else{ | |||||
| return ""; | |||||
| } | |||||
| } | |||||
| function display_list(){ | |||||
| var html="<tr>\ | |||||
| <th></th>\ | |||||
| <th id=\"labeltask_head\"></th>\ | |||||
| <th>标注任务名称</th>\ | |||||
| <th>关联的数据集名称</th>\ | |||||
| <th>数据类型</th>\ | |||||
| <th>标注人员</th>\ | |||||
| <th>审核人员</th>\ | |||||
| <th>任务开始时间</th>\ | |||||
| <th>任务状态</th>\ | |||||
| <th>总标注数量</th>\ | |||||
| <th>操作</th>\ | |||||
| </tr>"; | |||||
| for (var i=0;i<tableData.length;i++){ | |||||
| var row = "<tr>\ | |||||
| <td><input type=\"checkbox\" class=\"flat-grey list-child\"/></td>\ | |||||
| <td id=\"labeltask_id\">"+tableData[i].id+"</td>\ | |||||
| <td>"+tableData[i].task_name+"</td>\ | |||||
| <td>"+tableData[i].relate_task_name+"</td>\ | |||||
| <td>"+ getTaskTypeDesc(tableData[i].task_type) +"</td>\ | |||||
| <td>"+tableData[i].assign_user+"</td>\ | |||||
| <td>"+tableData[i].verify_user+"</td>\ | |||||
| <td>"+tableData[i].task_add_time+"</td>\ | |||||
| <td>"+getTaskSataus(tableData[i].task_status,tableData[i].task_status_desc)+"</td>\ | |||||
| <td>"+tableData[i].total_label+"</td>\ | |||||
| <td>" + | |||||
| getLabel(tableData[i].task_status,tableData[i].id,tableData[i].task_type,tableData[i].task_flow_type) + "<a onclick=\"setTaskId(\'"+tableData[i].id+"\');\"><b>导出标注</b></a>" | |||||
| + | |||||
| "</td>\ | |||||
| </tr>"; | |||||
| html=html+row; | |||||
| } | |||||
| //console.log(html); | |||||
| document.getElementById('label_task_list').innerHTML=html; | |||||
| $('#label_task_list tr').find('td:eq(1)').hide(); | |||||
| $('#label_task_list tr').find('th:eq(1)').hide(); | |||||
| } | |||||
| function startToLabel(taskid, task_type){//从审核转回标注,标注人不变。 | |||||
| $.ajax({ | |||||
| type:"PATCH", | |||||
| url:ip + "/gitea/label-task-status/", | |||||
| dataType:"json", | |||||
| async:false, | |||||
| headers: { | |||||
| authorization:token, | |||||
| }, | |||||
| data:{ | |||||
| "label_task_id" : taskid, | |||||
| "verify_user_id" : 0, | |||||
| "task_status" : 0 | |||||
| }, | |||||
| success:function(res){ | |||||
| console.log(res); | |||||
| }, | |||||
| error:function(response) { | |||||
| redirect(response); | |||||
| } | |||||
| }); | |||||
| var current =$('#displayPage1').text(); | |||||
| page(current - 1,pageSize); | |||||
| } | |||||
| function startToVerify(taskid, task_type){ | |||||
| $("#hide_labeltasktoverifyid").val(taskid); | |||||
| $.ajax({ | |||||
| type:"GET", | |||||
| url:ip + "/api/queryVerifyUser/", | |||||
| headers: { | |||||
| authorization:token, | |||||
| }, | |||||
| dataType:"json", | |||||
| async:false, | |||||
| success:function(json){ | |||||
| console.log(json); | |||||
| var html="<option value=\"\" selected=\"\">请选择</option>"; | |||||
| for (var i=0;i<json.length; i++){ | |||||
| var row = "<option value=\""+json[i].id+"\">" + json[i].username + "</option>"; | |||||
| html=html+row; | |||||
| } | |||||
| document.getElementById('label_verify_user').innerHTML=html; | |||||
| }, | |||||
| error:function(response) { | |||||
| redirect(response); | |||||
| } | |||||
| }); | |||||
| $("#startToVerify").modal('show'); | |||||
| } | |||||
| function submit_labeltask_toverify(){ | |||||
| var label_task_id = $('#hide_labeltasktoverifyid').val(); | |||||
| console.log("label_task_id=" +label_task_id); | |||||
| var verify_user_id = $('#label_verify_user option:selected').val(); | |||||
| //修改状态 | |||||
| $.ajax({ | |||||
| type:"PATCH", | |||||
| url:ip + "/gitea/label-task-status/", | |||||
| dataType:"json", | |||||
| async:false, | |||||
| headers: { | |||||
| authorization:token, | |||||
| }, | |||||
| data:{ | |||||
| "label_task_id" : label_task_id, | |||||
| "verify_user_id" : verify_user_id, | |||||
| "task_status" : 1 | |||||
| }, | |||||
| success:function(res){ | |||||
| console.log(res); | |||||
| }, | |||||
| error:function(response) { | |||||
| redirect(response); | |||||
| } | |||||
| }); | |||||
| $("#startToVerify").modal('hide'); | |||||
| var current =$('#displayPage1').text(); | |||||
| page(current - 1,pageSize); | |||||
| } | |||||
| function goVerify(taskid, task_type){ | |||||
| sessionStorage.setItem('label_task',taskid); | |||||
| sessionStorage.setItem('label_task_status',1);//审核 | |||||
| console.log("task_type=" + task_type); | |||||
| if(task_type == 2 || task_type == 1 || task_type == 4){ | |||||
| window.location.href="labeling.html"; | |||||
| }else if(task_type == 3){ | |||||
| window.location.href="labelingDcm.html"; | |||||
| } | |||||
| } | |||||
| function personLabel(taskid, task_type){ | |||||
| sessionStorage.setItem('label_task',taskid); | |||||
| sessionStorage.setItem('token',token); | |||||
| sessionStorage.setItem('userType',1); | |||||
| var pathname = window.location.pathname; | |||||
| var search = window.location.search | |||||
| var url_name = pathname + search | |||||
| sessionStorage.setItem('return_url',url_name); | |||||
| console.log("task_type=" + task_type); | |||||
| if(task_type == 2 || task_type == 1 || task_type == 4){ | |||||
| window.open("/self/labeling.html?","标注"+new Date().getMilliseconds()); | |||||
| //window.location.href="/self/labeling.html"; | |||||
| }else if(task_type == 3){ | |||||
| window.location.href="labelingDcm.html"; | |||||
| } | |||||
| } | |||||
| function setMultiTaskId(){ | |||||
| var Check = $("table[id='label_task_list'] input[type=checkbox]:checked");//在table中找input下类型为checkbox属性为选中状态的数据 | |||||
| if(Check.length == 0){ | |||||
| alert("请选择一个或者多个标注数据进行导出。"); | |||||
| return; | |||||
| } | |||||
| var taskList = []; | |||||
| Check.each(function () {//遍历 | |||||
| var row = $(this).parent("td").parent("tr");//获取选中行 | |||||
| var id = row.find("[id='labeltask_id']").html();//获取name='Sid'的值 | |||||
| taskList.push(id); | |||||
| //$('#hide_labeltaskid').val(id); | |||||
| }); | |||||
| setTaskId(JSON.stringify(taskList)); | |||||
| } | |||||
| function setTaskId(labeltaskid){ | |||||
| $('#hide_labeltaskid').val(labeltaskid); | |||||
| console.log("go here1"); | |||||
| bar.style.width='1%'; | |||||
| document.getElementById('text-progress').innerHTML="0%"; | |||||
| document.getElementById("predtask_id").removeAttribute("disabled"); | |||||
| console.log("go here2"); | |||||
| $(".ui.export.modal").modal("show"); | |||||
| } | |||||
| function isBeetween(score_threshhold){ | |||||
| if(isEmpty(score_threshhold)){ | |||||
| return true; | |||||
| } | |||||
| var regPos = /^\d+(\.\d+)?$/; //非负浮点数 | |||||
| if(!regPos.test(score_threshhold)){ | |||||
| return false; | |||||
| }else{ | |||||
| if(score_threshhold >1 || score_threshhold < 0){ | |||||
| return false; | |||||
| } | |||||
| } | |||||
| return true; | |||||
| } | |||||
| function downloadFile(){ | |||||
| var labeltaskid = $('#hide_labeltaskid').val(); | |||||
| var isNeedPicture = $('#isNeedPicture option:selected').val(); | |||||
| var maxscore = $('#maxscore').val(); | |||||
| var minscore = $('#minscore').val(); | |||||
| var exportFormat = $('#exportFormat option:selected').val(); | |||||
| if(isNeedPicture == 3){ | |||||
| if(!isBeetween(maxscore)){ | |||||
| alert("标注得分最大值应该填写0--1.0之间的数值。"); | |||||
| return; | |||||
| } | |||||
| if(!isBeetween(minscore)){ | |||||
| alert("标注得分最小值应该填写0--1.0之间的数值。"); | |||||
| return; | |||||
| } | |||||
| if(!isEmpty(maxscore) && !isEmpty(minscore)){ | |||||
| if(minscore>maxscore){ | |||||
| alert("标注得分最小值应该小于标注得分最大值。"); | |||||
| return; | |||||
| } | |||||
| } | |||||
| } | |||||
| document.getElementById("predtask_id").setAttribute("disabled", true); | |||||
| var taskreturnid = ""; | |||||
| $.ajax({ | |||||
| type:"GET", | |||||
| url:ip + "/gitea-label-task-export/", | |||||
| headers: { | |||||
| authorization:token, | |||||
| }, | |||||
| dataType:"json", | |||||
| data:{ | |||||
| "label_task_id" : labeltaskid, | |||||
| "needPicture" : isNeedPicture, | |||||
| "exportFormat":exportFormat, | |||||
| "maxscore":maxscore, | |||||
| "minscore":minscore | |||||
| }, | |||||
| async:false, | |||||
| success:function(json){ | |||||
| taskreturnid = json.message; | |||||
| console.log(json); | |||||
| }, | |||||
| error:function(response) { | |||||
| redirect(response); | |||||
| } | |||||
| }); | |||||
| console.log("taskreturnid=" +taskreturnid); | |||||
| if(!isEmpty(taskreturnid)){ | |||||
| setIntervalToDo(taskreturnid); | |||||
| } | |||||
| } | |||||
| var timeId=[]; | |||||
| var count; | |||||
| var progress; | |||||
| function setIntervalToDo(taskreturnid){ | |||||
| count=0; | |||||
| var tmpTimeId = self.setInterval("clock('" + taskreturnid +"')",1000);//5秒刷新 | |||||
| timeId.push(tmpTimeId); | |||||
| console.log("开始刷新。timeId=" + tmpTimeId); | |||||
| } | |||||
| function clock(taskreturnid){ | |||||
| count++; | |||||
| if(count > 600 ){ | |||||
| for(var i = 0;i < timeId.length; i++){ | |||||
| console.log("清除定时器1。exportTimeId=" + timeId[i]); | |||||
| window.clearInterval(timeId[i]); | |||||
| } | |||||
| timeId = []; | |||||
| $(".ui.export.modal").modal("hide"); | |||||
| return; | |||||
| } | |||||
| $.ajax({ | |||||
| type:"GET", | |||||
| url:ip + "/api/query-download-progress/", | |||||
| headers: { | |||||
| authorization:token, | |||||
| }, | |||||
| dataType:"json", | |||||
| data:{'taskId': taskreturnid}, | |||||
| async:false, | |||||
| success:function(json){ | |||||
| progress = json; | |||||
| console.log(json); | |||||
| }, | |||||
| error:function(response) { | |||||
| progress = null; | |||||
| console.log('query return null.'); | |||||
| redirect(response); | |||||
| } | |||||
| }); | |||||
| if(!isEmpty(progress)){ | |||||
| if(progress.progress >= 100){ | |||||
| var iSpeed = progress.progress; | |||||
| bar.style.width=iSpeed+'%'; | |||||
| document.getElementById('text-progress').innerHTML=iSpeed+'%' + ",开始下载文件。" | |||||
| for(var i = 0;i < timeId.length; i++){ | |||||
| console.log("清除定时器2。exportTimeId=" + timeId[i]); | |||||
| window.clearInterval(timeId[i]); | |||||
| } | |||||
| timeId = []; | |||||
| var url = ip + "/api/label-file-download/"; | |||||
| var $iframe = $('<iframe />'); | |||||
| var $form = $('<form method="get" target="_self"/>'); | |||||
| $form.attr('action', url); //设置get的url地址 | |||||
| $form.append('<input type="hidden" name="taskId" value="' + taskreturnid + '" />'); | |||||
| $iframe.append($form); | |||||
| $(document.body).append($iframe); | |||||
| $form[0].submit();//提交表单 | |||||
| $iframe.remove();//移除框架 | |||||
| $(".ui.export.modal").modal("hide"); | |||||
| }else{ | |||||
| //更新进度 | |||||
| var iSpeed = progress.progress; | |||||
| bar.style.width=iSpeed+'%'; | |||||
| document.getElementById('text-progress').innerHTML=iSpeed+'%' | |||||
| } | |||||
| }else{ | |||||
| count = 600; | |||||
| } | |||||
| } | |||||
| function page(current,pageSize){ | |||||
| list(current,pageSize); | |||||
| display_list(); | |||||
| setPage(tablePageData,pageSize); | |||||
| sessionStorage.setItem('label_task_page',current); | |||||
| } | |||||
| function nextPage(){ | |||||
| var current = $('#displayPage1').text(); | |||||
| console.log("current=" + current); | |||||
| page(current,pageSize); | |||||
| } | |||||
| function prePage(){ | |||||
| var current =$('#displayPage1').text(); | |||||
| console.log("current=" + current); | |||||
| if(current > 1){ | |||||
| console.log("current=" + (current - 2)); | |||||
| page(current - 2,pageSize); | |||||
| } | |||||
| } | |||||
| function goPage(){ | |||||
| var goNum = $('#goNum').val(); | |||||
| var pageTotal = $("#totalNum").text(); | |||||
| var pageNum = parseInt(pageTotal/pageSize); | |||||
| if(pageTotal%pageSize!=0){ | |||||
| pageNum += 1; | |||||
| }else { | |||||
| pageNum = pageNum; | |||||
| } | |||||
| if (goNum<=0){ | |||||
| alert("请输入大于0的数值"); | |||||
| } | |||||
| else if(goNum<=pageNum){ | |||||
| page(goNum - 1,pageSize); | |||||
| } | |||||
| else{ | |||||
| alert("不能超出总页码!"); | |||||
| } | |||||
| } | |||||
| $("#goNum").keydown(function (e) { | |||||
| if (e.keyCode == 13) { | |||||
| goPage(); | |||||
| } | |||||
| }); | |||||
| function setPage(pageData,pageSize){ | |||||
| if (isEmpty(pageData)){ | |||||
| return; | |||||
| } | |||||
| var startIndex = pageData.current * pageSize; | |||||
| if(pageData.total > 0){ | |||||
| startIndex = startIndex + 1; | |||||
| } | |||||
| $('#startIndex').text(startIndex); | |||||
| $('#endIndex').text(pageData.current * pageSize + pageData.data.length); | |||||
| $('#totalNum').text(pageData.total); | |||||
| $('#displayPage1').text(pageData.current + 1); | |||||
| console.log("set prePage status, pageData.current=" + pageData.current); | |||||
| if(pageData.current == 0){ | |||||
| console.log("set prePage disabled."); | |||||
| $('#prePage').removeAttr("href"); | |||||
| $('#prePage').attr('style','color:#f5f5f6;'); | |||||
| } | |||||
| else{ | |||||
| $('#prePage').attr("href","javascript:prePage()"); | |||||
| $('#prePage').attr('style','color:#000;'); | |||||
| } | |||||
| if((pageData.current + 1) * pageSize >= pageData.total){ | |||||
| console.log("set nextPage disabled."); | |||||
| $('#nextPage').removeAttr("href"); | |||||
| } | |||||
| else{ | |||||
| $('#nextPage').attr("href","javascript:nextPage()"); | |||||
| } | |||||
| var pageTotal = pageData.total; | |||||
| var pageNum = parseInt(pageTotal/pageSize); | |||||
| if(pageTotal%pageSize!=0){ | |||||
| pageNum += 1; | |||||
| }else { | |||||
| pageNum = pageNum; | |||||
| } | |||||
| $("#totalPageNum").text(pageNum); | |||||
| } | |||||
| var tmpCurrent = sessionStorage.getItem("label_task_page"); | |||||
| if(isEmpty(tmpCurrent)){ | |||||
| tmpCurrent = 0; | |||||
| } | |||||
| page(tmpCurrent,pageSize); | |||||
| @@ -0,0 +1,879 @@ | |||||
| <!-- <!DOCTYPE html> --> | |||||
| <!DOCTYPE html> | |||||
| <html > | |||||
| <head> | |||||
| <meta charset="UTF-8"> | |||||
| <title>数据标注平台</title> | |||||
| <meta content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no' name='viewport'> | |||||
| <meta name="description" content="Developed By M Abdur Rokib Promy"> | |||||
| <meta name="keywords" content="Admin, Bootstrap 3, Template, Theme, Responsive"> | |||||
| <!-- bootstrap 3.0.2 --> | |||||
| <link href="/self/css/bootstrap.min.css" rel="stylesheet" type="text/css" /> | |||||
| <!-- font Awesome --> | |||||
| <link href="/self/css/font-awesome.min.css" rel="stylesheet" type="text/css" /> | |||||
| <!-- Ionicons --> | |||||
| <link href="/self/css/ionicons.min.css" rel="stylesheet" type="text/css" /> | |||||
| <!-- google font --> | |||||
| <!-- Theme style --> | |||||
| <link href="/self/css/style.css" rel="stylesheet" type="text/css" /> | |||||
| <link href="/self/css/jquery.yhhDataTable.css" rel="stylesheet" type="text/css" /> | |||||
| <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries --> | |||||
| <!-- WARNING: Respond.js doesn't work if you view the page via file:// --> | |||||
| <!--[if lt IE 9]> | |||||
| <![endif]--> | |||||
| <script> | |||||
| window.config={ | |||||
| AppSubUrl:'', | |||||
| StaticUrlPrefix: '', | |||||
| csrf: '', | |||||
| } | |||||
| var title_text = sessionStorage.getItem('return_url').split('/')[2] | |||||
| console.log(sessionStorage.getItem('return_url').split('/')) | |||||
| title_text = "数据标注-" + title_text + '-OpenI' | |||||
| document.title = title_text | |||||
| </script> | |||||
| <style> | |||||
| html body{ height: 100%;margin: 0;padding: 0;} | |||||
| .containers{ | |||||
| height: 100%; | |||||
| } | |||||
| .table-define td{border-bottom: 1px solid #222324;padding-top: 5px !important;padding-bottom:5px !important;border-top: 0px !important;padding-left: 20px !important;vertical-align: middle !important;} | |||||
| .btn:hover{background: transparent;} | |||||
| .display_area_content { } /* this class is used to clear the display area content */ | |||||
| .force_small_font { font-size:small !important; } | |||||
| .draw_tool{padding:0;color:#fff} | |||||
| .draw_li {padding: 0.2em;border: 0.5px solid rgba(34,35,36,0.2);border-bottom: 0;border-radius: 3px;cursor: pointer;} | |||||
| ul.region_shape { font-size:xx-large; list-style-type:none; overflow:hidden; padding:0.4em 0; margin:0; } | |||||
| /*ul.region_shape li { float:left; padding:0 0.2em; fill:#ffffff; stroke:#000000; }*/ | |||||
| ul.region_shape li { float:right; padding:0 0.2em; fill:#ffffff; stroke:#000000; } | |||||
| ul.region_shape li:hover { cursor:pointer; fill:#ffffff; stroke:#ff0000; } | |||||
| ul.region_shape .selected { fill:#ffffff; stroke:#ff0000; } | |||||
| /*.toolbar { display:inline-block; margin-left:1rem; }*/ | |||||
| .toolbar { display:inline-block; margin-right:1rem; } | |||||
| .toolbar svg { fill:white; margin: 0.2rem 0.1rem; height:1.2rem; -moz-user-select:none; -webkit-user-select:none; -ms-user-select:none;} | |||||
| .toolbar svg:hover { fill:yellow; cursor:pointer; } | |||||
| .toolbar svg:active { fill:white; } | |||||
| .toolbar ul { display:inline-block; padding:0.2rem; margin:0; } | |||||
| /*.toolbar li { display:inline; float:left; padding:0rem 0.3rem; border:1px solid white;} *//* main menu items */ | |||||
| .toolbar li { display:inline; float:right; padding:0rem 0.3rem; border:1px solid white;} | |||||
| .toolbar li:hover { color:red; cursor:pointer; } | |||||
| /* Top panel : #navbar, #toolbar */ | |||||
| .top_panel { font-size:0.9rem; display:block; background-color:#212121; color:#ffffff; z-index:1001; margin-bottom:1rem;} | |||||
| /* Navigation menu bar that appear at the top */ | |||||
| .menubar { display:inline-block; height:1.8rem; } /* height needed to avoid extra bottom border */ | |||||
| .menubar a:link { color:#eeeeee; text-decoration:none; } | |||||
| .menubar a:visited { color:#eeeeee; text-decoration:none; } | |||||
| .menubar ul { display:block; padding:0; margin:0; } | |||||
| /*.menubar li { display:inline; float:left; padding:0.45rem 1rem; }*/ | |||||
| .menubar li { display:inline; float:right; padding:0.45rem 1rem; } | |||||
| .menubar li:hover { background-color:#616161; cursor:default; } | |||||
| .menubar li ul { display:none; background-color:#212121; border:1px solid #616161; min-width:10rem; position:absolute; z-index:100; margin:0.4rem -1rem;} | |||||
| .menubar li ul li { display:block; float:none; color:#eeeeee; margin:0; padding:0.6rem 1rem; } | |||||
| .menubar li ul li:hover { cursor:pointer; } | |||||
| .menubar li ul li.submenu_divider { margin:0 0.4rem; padding:0; height:1px; border-bottom:1px solid #424242; } | |||||
| .menubar li:hover ul { display:block; } | |||||
| /* toolbar containing small icons for tools */ | |||||
| .toolbar { display:inline-block; margin-right:1rem; } | |||||
| /*.toolbar { display:inline-block; margin-left:1rem; }*/ | |||||
| .toolbar svg { fill:white; margin: 0.2rem 0.1rem; height:1.2rem; -moz-user-select:none; -webkit-user-select:none; -ms-user-select:none;} | |||||
| .toolbar svg:hover { fill:yellow; cursor:pointer; } | |||||
| .toolbar svg:active { fill:white; } | |||||
| .toolbar ul { display:inline-block; padding:0.2rem; margin:0; } | |||||
| /*.toolbar li { display:inline; float:left; padding:0rem 0.3rem; border:1px solid white;} *//* main menu items */ | |||||
| .toolbar li { display:inline; float:right; padding:0rem 0.3rem; border:1px solid white;} | |||||
| .toolbar li:hover { color:red; cursor:pointer; } | |||||
| /* Middle panel: containing #image_panel, #leftsidebar */ | |||||
| /*.middle_panel { display:table; table-layout:fixed; width:100%; z-index:1; padding:0;}*/ | |||||
| .middle_panel { display:table; table-layout:fixed; right:0px,width:100%; z-index:1; padding:0;} | |||||
| /*#leftsidebar { display:none; z-index:10; vertical-align:top;}*/ | |||||
| #leftsidebar { display:none; z-index:10; vertical-align:top;} | |||||
| /*#rightsidebar { z-index:-10; vertical-align:left;}*/ | |||||
| /*#display_area { display:table-cell; width:100%; z-index:1; margin:0; padding-left:1em; vertical-align:top; }*/ | |||||
| #display_area { display:table-cell; width:100%; z-index:1; margin:0; padding-right:1em; vertical-align:top; } | |||||
| /* layers of canvas */ | |||||
| /*#image_panel { position:relative; outline:none; } | |||||
| #image_panel img { visibility:hidden; opacity:0; position:absolute; top:0px; left:0px; width:100%; height:100%; outline:none; }*/ | |||||
| #image_panel { position:relative; outline:none; } | |||||
| #image_panel img { visibility:hidden; opacity:0; position:absolute; top:0px; right:0px; width:100%; height:100%; outline:none; } | |||||
| #image_panel canvas { position:absolute; top:0px; left:0px; outline:none;} | |||||
| #image_panel .visible { visibility:visible !important; opacity:1 !important; } | |||||
| #image_panel label>img { visibility:visible; opacity:1; position:relative; width:auto; height:4em; outline:none; } | |||||
| #leftsidebar_collapse_panel { display:none; position:relative; z-index:10; vertical-align:top; } | |||||
| /*#leftsidebar_show_button { font-size:large; margin-left:0.1rem; }*/ | |||||
| #leftsidebar_show_button { font-size:large; margin-right:0.1rem; } | |||||
| #leftsidebar_show_button:hover { color:red; cursor: pointer; } | |||||
| /* Left sidebar accordion */ | |||||
| button.leftsidebar_accordion { font-size:large; background-color:#f2f2f2; cursor:pointer; padding:0.5em 0.5em; width:100%; text-align:left; border:0; outline:none; } | |||||
| button.leftsidebar_accordion:focus { outline: none; } | |||||
| button.leftsidebar_accordion.active, button.leftsidebar_accordion:hover { background-color: #e6e6e6; } | |||||
| button.leftsidebar_accordion:after { content:'\02795'; color:#4d4d4d; float:right; } | |||||
| button.leftsidebar_accordion.active:after { content: '\2796'; } | |||||
| .leftsidebar_accordion_panel { display:none; padding:0 0.5em; font-size:small; border-right:0px solid #f2f2f2; border-bottom:0px solid #f2f2f2; } | |||||
| .leftsidebar_accordion_panel.show { display:block; } | |||||
| /* Keyboard shortcut panel */ | |||||
| .leftsidebar_accordion_panel table { border-collapse:collapse; } | |||||
| .leftsidebar_accordion_panel td { border:1px solid #f2f2f2; padding:0.2rem 0.4rem; } | |||||
| /* buttons */ | |||||
| /*.button_panel { display:inline-block; width:100%; margin:0.2rem 0; }*/ | |||||
| .button_panel { display:inline-block; width:100%; margin:0.2rem 0; } | |||||
| .button_panel .text_button, .text_button { color: #0000ff; padding: 0.2rem 0.2rem; -moz-user-select:none; -webkit-user-select:none; -ms-user-select:none; } | |||||
| .button_panel .flush_right { float:right; } | |||||
| .button_panel .text_button:hover, .text_button:hover { cursor:pointer; } | |||||
| .button_panel .text_button:active, .text_button:active { color: #000000; } | |||||
| .button_panel .active { border-bottom:1px solid black; } | |||||
| .button_panel .button { display:inline-block; padding:0.35rem 0.5rem; margin:0 0.05rem; cursor:pointer; background-color:#cccccc; border-radius:0.2rem; -moz-user-select:none; -webkit-user-select:none; -ms-user-select:none; } | |||||
| .button_panel .button:hover { background-color:black; color:white; } | |||||
| /* Attributes properties: name, description, type, ... */ | |||||
| #attribute_properties { display:table; right:200;width:100%; border-collapse:collapse; margin:1rem 0; border:1px solid #cccccc; } | |||||
| /*#attribute_properties { display:table; border-collapse:collapse; margin:1rem 0; border:1px solid #cccccc; }*/ | |||||
| #attribute_properties .property { display:table-row;} | |||||
| #attribute_properties .property span { display:table-cell; padding: 0.2rem 0.4rem; } | |||||
| #attribute_properties .property span input { width: 100%; border:1px solid #cccccc; margin: 0;} | |||||
| #attribute_properties .property span input:focus { border:1px solid black; } | |||||
| #attribute_properties .property span select { width: 100%; border:1px solid #cccccc; margin: 0;} | |||||
| /* Attributes options: options for attribute type={checkbox,radio,...} */ | |||||
| #attribute_options { display:table; width:100%; border-collapse:collapse; margin:1rem 0; border:1px solid #cccccc; table-layout:fixed; } | |||||
| #attribute_options .new_option_id_entry { display:inline-block; padding:1rem 0.2rem; } | |||||
| #attribute_options .new_option_id_entry input {border:none; border-bottom:1px solid #cccccc; margin: 0; font-size: 1.3rem;} | |||||
| #attribute_options .property { display:table-row;} | |||||
| #attribute_options .property span { display:table-cell; padding: 0.2rem 0.2rem; font-weight:bold; } | |||||
| /*#attribute_options .property input { display:table-cell; width:100%; border:none; border-bottom:1px solid #cccccc; margin: 0; font-size: 0.8rem;}*/ | |||||
| #attribute_options .property input { display:table-cell; width:100%; border:none; border-bottom:1px solid #cccccc; margin: 0; font-size: 1.3rem;} | |||||
| #attribute_options .property input:focus { border-bottom:1px solid #000000; background-color:#f2f2f2; color:#000000; } | |||||
| #attribute_options .property span input[type=checkbox] { vertical-align:middle; } | |||||
| #attribute_options .property span input[type=radio] { vertical-align:middle; } | |||||
| #user_input_panel { position:fixed; display:none; width:100%; height:100%; top:0; left:50; right:0; bottom:0; background-color: rgba(0,0,0,0.6); z-index:1002; } | |||||
| /*#user_input_panel .content { position:fixed; background-color:white; top:50%; left:50%; transform:translate(-50%,-50%); -webkit-transform: translate(-50%, -50%); -moz-transform: translate(-50%, -50%); -o-transform: translate(-50%, -50%); -ms-transform: translate(-50%, -50%); padding:2rem 4rem;}*/ | |||||
| #user_input_panel .content { position:fixed; background-color:white; top:50%; left:50%; transform:translate(-50%,-50%); -webkit-transform: translate(-50%, -50%); -moz-transform: translate(-50%, -50%); -o-transform: translate(-50%, -50%); -ms-transform: translate(-50%, -50%); padding:2rem 4rem;} | |||||
| #user_input_panel .content .title { font-size:large; font-weight:bold; } | |||||
| #user_input_panel .content .user_inputs { display:table; width:100%; border-collapse:collapse;} | |||||
| #user_input_panel .content .user_inputs .row { display:table-row; } | |||||
| #user_input_panel .content .user_inputs .cell { display:table-cell; padding:1rem 0.5rem; vertical-align:middle; border:1px solid #f2f2f2; } | |||||
| #user_input_panel .content .user_confirm { display:table; width:100%; text-align:center; margin:2rem 0;} | |||||
| #user_input_panel .content .user_confirm .ok { display:table-cell; width:48%; } | |||||
| #user_input_panel .content .user_confirm .cancel { display:table-cell; width:48%; } | |||||
| #user_input_panel .content .warning { color:red; } | |||||
| /* Attribute editor */ | |||||
| #annotation_editor_panel { position:fixed; display:none; width:100%; right:0; bottom:0; background-color:white; border-top:2px solid #cccccc; padding:0.2em 1em; overflow:auto; z-index:1001; box-shadow: 0 0 1em #cccccc;} | |||||
| /*#annotation_editor { display:table; margin-bottom:3em; border-collapse:collapse; font-size:inherit; position: absolute; top:500px;left:800px; background-color:white; }*/ | |||||
| #annotation_editor { display:table; margin-bottom:3em; border-collapse:collapse; font-size:inherit; background-color:white; z-index:10024;} | |||||
| #annotation_editor .row { display:table-row; } | |||||
| #annotation_editor .highlight .col { background-color:#e6e6e6;} | |||||
| #annotation_editor .col { display:table-cell; padding:0.4em 0.6em; border:1px solid #000000; vertical-align:middle; font-size:inherit; } | |||||
| #annotation_editor .header { font-weight:bold; white-space:nowrap} | |||||
| #annotation_editor .id { font-weight:bold; } | |||||
| #annotation_editor .col input[type=checkbox] { vertical-align:middle; } | |||||
| #annotation_editor .col input[type=radio] { vertical-align:middle; font-size:inherit; } | |||||
| #annotation_editor .col label { vertical-align:middle; font-size:inherit; } | |||||
| #annotation_editor .col textarea { border:0.1em solid #cccccc; padding:0; margin:0; font-size:inherit; background-color:#ffffff;height:20px;width: 80px} | |||||
| #annotation_editor .col textarea:focus { border:0.1em dashed #cccccc; } | |||||
| #annotation_editor .col span { display:block; } | |||||
| #annotation_editor .col horizontal_container { display:inline-block; } | |||||
| #annotation_editor .col .img_options { display:inline; } | |||||
| #annotation_editor .col .img_options .imrow { display:block; } | |||||
| #annotation_editor .col .img_options span { display:inline-block; margin: 0.2rem 0.4rem;} | |||||
| #annotation_editor .col .img_options span img { height:4em; } | |||||
| #annotation_editor .col .img_options p { margin:0; padding:0; font-size:inherit; } | |||||
| #annotation_editor .col .img_options input[type=radio] { display:none; } | |||||
| #annotation_editor .col .img_options input[type=radio] + label { display:block; cursor:pointer; text-align:center;} | |||||
| #annotation_editor .col .img_options input[type=radio]:checked + label { border: 0.1em solid black; background-color:#cccccc; cursor:default; font-size:inherit; } | |||||
| /* Region shape selection panel inside leftsidebar */ | |||||
| ul.region_shape { font-size:xx-large; list-style-type:none; overflow:hidden; padding:0.4em 0; margin:0; } | |||||
| ul.region_shape li { float:left; padding:0 0.2em; fill:#ffffff; stroke:#000000; } | |||||
| /*ul.region_shape li { float:right; padding:0 0.2em; fill:#ffffff; stroke:#000000; }*/ | |||||
| ul.region_shape li:hover { cursor:pointer; fill:#ffffff; stroke:#ff0000; } | |||||
| ul.region_shape .selected { fill:#ffffff; stroke:#ff0000; } | |||||
| /* cursor coordinates inside region shape selection panel in leftsidebar */ | |||||
| #region_info { font-size:0.8em; margin-bottom:0.4em; } | |||||
| /*#message_panel { display:block; width:100%; position:fixed; bottom:300px; z-index:9999; text-align:center; }*/ | |||||
| #message_panel { display:block; width:100%; position:fixed; bottom:30px; right:0;z-index:9999; text-align:center; } | |||||
| #message_panel .content { display:inline; margin:auto; background-color:#000000; color:#ffff00; font-size:small; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; line-height:2rem; padding: 0.5rem 2rem;} | |||||
| .text_panel { display:none; margin:auto; font-size:medium; line-height:1.3em; margin: 0; max-width:700px; } | |||||
| /*.text_panel li { margin:1em 0; text-align:left; } | |||||
| .text_panel p { text-align:left; }*/ | |||||
| .text_panel li { margin:1em 0; text-align:right; } | |||||
| .text_panel p { text-align:right; } | |||||
| .svg_button:hover { cursor:pointer; } | |||||
| /* Loading spinbar */ | |||||
| .loading_spinbox { display:inline-block; border:0.4em solid #cccccc; border-radius:50%; border-top:0.4em solid black; border-bottom:0.4em solid black;-webkit-animation:spin 2s linear infinite; animation:spin 2s linear infinite; } | |||||
| @-webkit-keyframes spin { 0% { -webkit-transform: rotate(0deg); } 100% { -webkit-transform: rotate(360deg); } } | |||||
| @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } | |||||
| #invisible_file_input { width:0.1px; height:0.1px; opacity:0; overflow:hidden; position:absolute; z-index:-1; } | |||||
| .display_none { display:none !important; } | |||||
| .display_block { display:block !important; } | |||||
| .display_area_content { } /* this class is used to clear the display area content */ | |||||
| .narrow_page_content li { font-size:0.9rem; margin: 0.4rem 0; } | |||||
| .narrow_page_content { width:60%; } | |||||
| .force_small_font { font-size:small !important; } | |||||
| .key { font-family:monospace; padding:1px 6px; background:linear-gradient(to bottom,#f0f0f0,#fcfcfc);; border:1px solid #e0e0e0; white-space:nowrap; color:#303030; border-bottom-width:2px; border-radius:3px; font-size:1.2em; } | |||||
| #progress{ | |||||
| width: 100%; | |||||
| height: 20px; | |||||
| background: rgb(255, 255, 255); | |||||
| } | |||||
| #bar{ | |||||
| width: 1%; | |||||
| height: 20px; | |||||
| margin-top: 1px; | |||||
| background: green; | |||||
| } | |||||
| </style> | |||||
| </head> | |||||
| <body> | |||||
| <svg style="display:none;" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> | |||||
| <defs> | |||||
| <symbol id="via_logo"> | |||||
| <!-- Logo designed by Abhishek Dutta <adutta@robots.ox.ac.uk>, May 2018 --> | |||||
| <title>VGG Image Annotator Logo</title> | |||||
| <rect width="400" height="160" x="0" y="0" fill="#212121"></rect> | |||||
| <text x="56" y="130" font-family="Serif" font-size="100" fill="white">V</text> | |||||
| <text x="180" y="130" font-family="Serif" font-size="100" fill="white">I</text> | |||||
| <text x="270" y="130" font-family="Serif" font-size="100" fill="white">A</text> | |||||
| <rect width="80" height="100" x="52" y="40" stroke="yellow" fill="none" stroke-width="2"></rect> | |||||
| <text x="72" y="30" font-family="'Comic Sans MS', cursive, sans-serif" font-size="18" fill="yellow">VGG</text> | |||||
| <rect width="50" height="100" x="175" y="45" stroke="yellow" fill="none" stroke-width="2"></rect> | |||||
| <text x="175" y="35" font-family="'Comic Sans MS', cursive, sans-serif" font-size="18" fill="yellow">Image</text> | |||||
| <rect width="80" height="100" x="265" y="40" stroke="yellow" fill="none" stroke-width="2"></rect> | |||||
| <text x="265" y="30" font-family="'Comic Sans MS', cursive, sans-serif" font-size="18" fill="yellow">Annotator</text> | |||||
| </symbol> | |||||
| <symbol id="shape_rectangle"> | |||||
| <rect width="20" height="12" x="6" y="10" stroke-width="2"></rect> | |||||
| </symbol> | |||||
| <symbol id="shape_circle"> | |||||
| <title>Circular region shape</title> | |||||
| <circle r="10" cx="16" cy="16" stroke-width="2"></circle> | |||||
| </symbol> | |||||
| <symbol id="shape_ellipse"> | |||||
| <title>Elliptical region shape</title> | |||||
| <ellipse rx="12" ry="8" cx="16" cy="16" stroke-width="2"></ellipse> | |||||
| </symbol> | |||||
| <symbol id="shape_polygon"> | |||||
| <path d="M 15.25,2.2372 3.625,11.6122 6,29.9872 l 20.75,-9.625 2.375,-14.75 z" stroke-width="2"></path> | |||||
| </symbol> | |||||
| <symbol id="shape_point"> | |||||
| <circle r="3" cx="16" cy="16" stroke-width="2"></circle> | |||||
| </symbol> | |||||
| <symbol id="shape_polyline"> | |||||
| <title>Polyline region shape</title> | |||||
| <path d="M 2,12 10,24 18,12 24,18" stroke-width="2"></path> | |||||
| <circle r="1" cx="2" cy="12" stroke-width="2"></circle> | |||||
| <circle r="1" cx="10" cy="24" stroke-width="2"></circle> | |||||
| <circle r="1" cx="18" cy="12" stroke-width="2"></circle> | |||||
| <circle r="1" cx="24" cy="18" stroke-width="2"></circle> | |||||
| </symbol> | |||||
| <!-- Material icons downloaded from https://material.io/icons --> | |||||
| <symbol id="icon_settings"> | |||||
| <path d="M19.43 12.98c.04-.32.07-.64.07-.98s-.03-.66-.07-.98l2.11-1.65c.19-.15.24-.42.12-.64l-2-3.46c-.12-.22-.39-.3-.61-.22l-2.49 1c-.52-.4-1.08-.73-1.69-.98l-.38-2.65C14.46 2.18 14.25 2 14 2h-4c-.25 0-.46.18-.49.42l-.38 2.65c-.61.25-1.17.59-1.69.98l-2.49-1c-.23-.09-.49 0-.61.22l-2 3.46c-.13.22-.07.49.12.64l2.11 1.65c-.04.32-.07.65-.07.98s.03.66.07.98l-2.11 1.65c-.19.15-.24.42-.12.64l2 3.46c.12.22.39.3.61.22l2.49-1c.52.4 1.08.73 1.69.98l.38 2.65c.03.24.24.42.49.42h4c.25 0 .46-.18.49-.42l.38-2.65c.61-.25 1.17-.59 1.69-.98l2.49 1c.23.09.49 0 .61-.22l2-3.46c.12-.22.07-.49-.12-.64l-2.11-1.65zM12 15.5c-1.93 0-3.5-1.57-3.5-3.5s1.57-3.5 3.5-3.5 3.5 1.57 3.5 3.5-1.57 3.5-3.5 3.5z"></path> | |||||
| </symbol> | |||||
| <symbol id="icon_save"> | |||||
| <path d="M17 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V7l-4-4zm-5 16c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3zm3-10H5V5h10v4z"></path> | |||||
| </symbol> | |||||
| <symbol id="icon_open"> | |||||
| <path d="M20 6h-8l-2-2H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm0 12H4V8h16v10z"></path> | |||||
| </symbol> | |||||
| <symbol id="icon_gridon"> | |||||
| <path d="M20 2H4c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zM8 20H4v-4h4v4zm0-6H4v-4h4v4zm0-6H4V4h4v4zm6 12h-4v-4h4v4zm0-6h-4v-4h4v4zm0-6h-4V4h4v4zm6 12h-4v-4h4v4zm0-6h-4v-4h4v4zm0-6h-4V4h4v4z"></path> | |||||
| </symbol> | |||||
| <symbol id="icon_gridoff"> | |||||
| <path d="M8 4v1.45l2 2V4h4v4h-3.45l2 2H14v1.45l2 2V10h4v4h-3.45l2 2H20v1.45l2 2V4c0-1.1-.9-2-2-2H4.55l2 2H8zm8 0h4v4h-4V4zM1.27 1.27L0 2.55l2 2V20c0 1.1.9 2 2 2h15.46l2 2 1.27-1.27L1.27 1.27zM10 12.55L11.45 14H10v-1.45zm-6-6L5.45 8H4V6.55zM8 20H4v-4h4v4zm0-6H4v-4h3.45l.55.55V14zm6 6h-4v-4h3.45l.55.54V20zm2 0v-1.46L17.46 20H16z"></path> | |||||
| </symbol> | |||||
| <symbol id="icon_next"> | |||||
| <path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"></path> | |||||
| </symbol> | |||||
| <symbol id="icon_prev"> | |||||
| <path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"></path> | |||||
| </symbol> | |||||
| <symbol id="icon_list"> | |||||
| <path d="M3 13h2v-2H3v2zm0 4h2v-2H3v2zm0-8h2V7H3v2zm4 4h14v-2H7v2zm0 4h14v-2H7v2zM7 7v2h14V7H7z"></path> | |||||
| </symbol> | |||||
| <symbol id="icon_zoomin"> | |||||
| <path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"></path> | |||||
| <path d="M12 10h-2v2H9v-2H7V9h2V7h1v2h2v1z"/> | |||||
| </symbol> | |||||
| <symbol id="icon_zoomout"> | |||||
| <path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14zM7 9h5v1H7z"></path> | |||||
| </symbol> | |||||
| <symbol id="icon_copy"> | |||||
| <path d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z"></path> | |||||
| </symbol> | |||||
| <symbol id="icon_paste"> | |||||
| <path d="M19 2h-4.18C14.4.84 13.3 0 12 0c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm7 18H5V4h2v3h10V4h2v16z"></path> | |||||
| </symbol> | |||||
| <symbol id="icon_pasten"> | |||||
| <path d="M19 2h-4.18C14.4.84 13.3 0 12 0c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm7 18H5V4h2v3h10V4h2v16z"></path> | |||||
| <text x="8" y="18">n</text> | |||||
| </symbol> | |||||
| <symbol id="icon_pasteundo"> | |||||
| <path d="M19 2h-4.18C14.4.84 13.3 0 12 0c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm7 18H5V4h2v3h10V4h2v16z"></path> | |||||
| <text x="8" y="18">x</text> | |||||
| </symbol> | |||||
| <symbol id="icon_selectall"> | |||||
| <path d="M3 5h2V3c-1.1 0-2 .9-2 2zm0 8h2v-2H3v2zm4 8h2v-2H7v2zM3 9h2V7H3v2zm10-6h-2v2h2V3zm6 0v2h2c0-1.1-.9-2-2-2zM5 21v-2H3c0 1.1.9 2 2 2zm-2-4h2v-2H3v2zM9 3H7v2h2V3zm2 18h2v-2h-2v2zm8-8h2v-2h-2v2zm0 8c1.1 0 2-.9 2-2h-2v2zm0-12h2V7h-2v2zm0 8h2v-2h-2v2zm-4 4h2v-2h-2v2zm0-16h2V3h-2v2zM7 17h10V7H7v10zm2-8h6v6H9V9z"></path> | |||||
| </symbol> | |||||
| <symbol id="icon_close"> | |||||
| <path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"></path> | |||||
| </symbol> | |||||
| <symbol id="icon_insertcomment"> | |||||
| <path d="M20 2H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h14l4 4V4c0-1.1-.9-2-2-2zm-2 12H6v-2h12v2zm0-3H6V9h12v2zm0-3H6V6h12v2z"></path> | |||||
| </symbol> | |||||
| <symbol id="icon_checkbox"> | |||||
| <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"></path> | |||||
| </symbol> | |||||
| <symbol id="icon_fileupload"> | |||||
| <path d="M9 16h6v-6h4l-7-7-7 7h4zm-4 2h14v2H5z"></path> | |||||
| </symbol> | |||||
| <symbol id="icon_filedownload"> | |||||
| <path d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"></path> | |||||
| </symbol> | |||||
| </defs> | |||||
| </svg> | |||||
| <!-- header logo: style can be found in header.less --> | |||||
| <!-- <header class="header" > | |||||
| <div class="logo"> | |||||
| 人工标注 | |||||
| </div> | |||||
| <nav class="navbar navbar-static-top" role="navigation"> | |||||
| <span style="font-size:28px" id="title_id">通用图片标注</span> | |||||
| </nav> | |||||
| </header> --> | |||||
| <div style="height:100vh;display:flex;flex-flow:column nowrap;overflow:hidden;position: relative;"> | |||||
| <header class="header"> | |||||
| <div class="row" style="background-color: #020004;"> | |||||
| <div class="col-lg-1"> | |||||
| <a id="return_url" href="" style="margin: 8px;display: inline-block;"><i class="fa fa-home fa-fw" style="color: #E1E3E6;font-size: 24px;"></i></a> | |||||
| </div> | |||||
| <div class="col-lg-9"> | |||||
| <div class="row"> | |||||
| <div class="col-lg-5" style=" padding-left: 0;"> | |||||
| <!-- <button type="button" class="btn" style="background:#3291F8;margin:8px 12px 8px 0;color: #fff;border-radius: 0;padding: 4px 12px;font-size: 12px;">返回任务</button> | |||||
| <button type="button" class="btn" style="margin: 8px 12px;background:#74818D;color: #fff;border-radius: 0;padding: 4px 12px;font-size: 12px;">跳过</button> | |||||
| <button type="button" class="btn" style="margin: 8px 12px;background:#FF6200;color: #fff;border-radius: 0;padding: 4px 12px;font-size: 12px;">提交</button> --> | |||||
| </div> | |||||
| <div class="col-lg-3" style="text-align: center;;line-height: 42px;color: #fff;"> | |||||
| <span id="float_text"></span> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <div class="col-lg-2"></div> | |||||
| </div> | |||||
| </header> | |||||
| <div class="box1" style="float:left;position: absolute;z-index: 9999;left: 0.4em;top: 3.5em;"> | |||||
| <ul class="draw_tool" style="font-size: 18px;background-color: rgba(12,13,13,0.3);color: rgba(225,227,230,0.8);"> | |||||
| <li id="region_shape_rect" class="selected draw_li" onclick="createRectLabel()" title="新建矩形标注(W)"><i class="fa fa-square-o"></i></li> | |||||
| <li id="region_shape_polygon" class="draw_li" onclick="createMaskLabel()" title="新建多边形标注"><i class="fa fa-first-order" aria-hidden="true"></i> </li> | |||||
| <li id="region_shape_point" class="draw_li" onclick="createPointLabel()" title="新建点标注"><i class="fa fa-dot-circle-o" aria-hidden="true"></i></li> | |||||
| <li id="delete_shape" class="draw_li" onclick="deleterect()" title="删除选中的标注(D)"><i class="fa fa-times-circle-o" aria-hidden="true"></i></li> | |||||
| <li id="delete_all_shape" class="draw_li" onclick="deleteAllRect()" title="删除所有的标注框"><i class="fa fa-times" aria-hidden="true"></i></li> | |||||
| <li id="save_shape" class="draw_li" onclick="save()" title="保存标注(S)"><i class="fa fa-floppy-o" aria-hidden="true"></i></li> | |||||
| <li id="previous_shape"class="draw_li" onclick="last()" title="上一张(Q)"><i class="fa fa-arrow-circle-left" aria-hidden="true"></i></li> | |||||
| <li id="next_shape" class="draw_li" onclick="next()" title="下一张(E)"><i class="fa fa-arrow-circle-right" aria-hidden="true"></i></li> | |||||
| <li id="copy_shape" class="draw_li" onclick="copyOneBox()" title="复制单个选中的标注(C)"><i class="fa fa-file-o" aria-hidden="true"></i></li> | |||||
| <li id="copy_shape" class="draw_li" onclick="copy()" title="复制所有的标注"><i class="fa fa-clone" aria-hidden="true"></i></li> | |||||
| <li id="paste_shape" class="draw_li" onclick="paste()" title="粘贴复制的标注(V)"><i class="fa fa-clipboard" aria-hidden="true"></i></li> | |||||
| <li id="arrow-left" class="draw_li" onclick="moveLeftOnePx()" title="标注左移一个像素"><i class="fa fa-arrow-left" aria-hidden="true"></i> </li> | |||||
| <li id="arrow-right" class="draw_li" onclick="moveRightOnePx()" title="标注右移一个像素"><i class="fa fa-arrow-right" aria-hidden="true"></i> </li> | |||||
| <li id="arrow-up" class="draw_li" onclick="moveUpOnePx()" title="标注上移一个像素"><i class="fa fa-arrow-up" aria-hidden="true"></i></li> | |||||
| <li id="arrow-down" class="draw_li" onclick="moveDownOnePx()" title="标注下移一个像素"><i class="fa fa-arrow-down" aria-hidden="true"></i></li> | |||||
| <li id="setting" class="draw_li" onclick="updateSetting()" title="设置" href="#labeldefine"><i class="fa fa-cog" aria-hidden="true"></i> </li> | |||||
| <li id="skip" class="draw_li" onclick="skipLast()" title="跳转至上次标注的地方"><i class="fa fa-reply" aria-hidden="true"></i></li> | |||||
| <!-- <li class="draw_li" onclick="setAutoModel()" title="自动标注" href="#autoLabel" data-toggle="modal" data-backdrop="static" ><i class="fa fa-cube" aria-hidden="true"></i></li> --> | |||||
| <li class="draw_li" onclick="undo()" title="撤销上次标注(Z)" ><i class="fa fa-reply-all" aria-hidden="true"></i></li> | |||||
| <li style="padding: 0.2em;border: 0.5px solid rgba(34,35,36,0.2);border-radius: 3px;cursor: pointer;" title="清空指定文件的标注" href="#deleteLabel" data-toggle="modal" data-backdrop="static" ><i class="fa fa-eraser" aria-hidden="true"></i></li> | |||||
| </ul> | |||||
| </div> | |||||
| <div class="containers" style="flex: 1;"> | |||||
| <!-- <aside class="left-side sidebar-offcanvas" ></aside> --> | |||||
| <div class="row" style="height: 100%;"> | |||||
| <!-- left-side --> | |||||
| <!-- <div class="col-lg-1" style="background-color: #020004;height: 100%;border-top: 1px solid #222324;padding: 0;"> | |||||
| <div style="line-height: 3em;text-align: center;font-size: 16px;"> | |||||
| <span style="color: #fff;float: left;padding-left: 1.5em;">动物-狗</span> | |||||
| <a style="float: right;padding-right: 1em;"><i class="fa fa-cog" style="color: #74818D;font-size: 18px;cursor: pointer;"></i></a> | |||||
| </div> | |||||
| <div style="clear: both;"> | |||||
| <input type="text" placeholder="搜索标签" style="width: 80%;margin: 0 10%;background-color: transparent;border-radius: 6px;border: 0.5px solid #43474B;outline: none;color: #74818D;padding: 0.1em;"> | |||||
| </div> | |||||
| </div> --> | |||||
| <!-- canvas --> | |||||
| <div class="col-lg-10" id="showPic" style="background-color: #222324;height: 100%;padding: 0;padding-left: 4em;"> | |||||
| <!-- <nav class="navbar navbar-default" role="navigation" id="tool0" style="margin-bottom: 0;"> | |||||
| <div class="leftsidebar_accordion_panel show"> | |||||
| <ul class="region_shape" style="padding: 0;"> | |||||
| <li id="region_shape_rect" class="selected" onclick="createRectLabel()" title="新建矩形标注(W)"><svg height="28" viewbox="0 0 28 28"><use xlink:href="#shape_rectangle"></use></svg></li> | |||||
| <li id="region_shape_polygon" onclick="createMaskLabel()" title="新建多边形标注"><svg height="28" viewbox="0 0 28 28"><use xlink:href="#shape_polygon"></use></svg></li> | |||||
| <li id="region_shape_point" onclick="createPointLabel()" title="新建点标注"><svg height="28" viewbox="0 0 28 28"><use xlink:href="#shape_point"></use></svg></li> | |||||
| <li id="delete_shape" onclick="deleterect()" title="删除选中的标注(D)"><svg height="24" viewbox="0 0 28 28"><use xlink:href="#icon_close"></use></svg></li> | |||||
| <li id="save_shape" onclick="save()" title="保存标注(S)"><svg height="24" viewbox="0 0 28 28"><use xlink:href="#icon_save"></use></svg></li> | |||||
| <li id="previous_shape" onclick="last()" title="上一张(Q)"><svg height="24" viewbox="0 0 28 28"><use xlink:href="#icon_prev"></use></svg></li> | |||||
| <li id="next_shape" onclick="next()" title="下一张(E)"><svg height="24" viewbox="0 0 28 28"><use xlink:href="#icon_next"></use></svg></li> | |||||
| <li id="copy_shape" onclick="copy()" title="复制所有的标注"><svg height="24" viewbox="0 0 28 28"><use xlink:href="#icon_copy"></use></svg></li> | |||||
| <li id="paste_shape" onclick="paste()" title="粘贴复制的标注(V)"><svg height="24" viewbox="0 0 28 28"><use xlink:href="#icon_pasten"></use></svg></li> | |||||
| <li id="copy_shape" style="font-size: 20px;" onclick="copyOneBox()" title="复制单个选中的标注(C)"><i class="fa fa-files-o" style="vertical-align: bottom;" aria-hidden="true"></i></li> | |||||
| <li id="arrow-left" style="font-size: 26px" onclick="moveLeftOnePx()" title="标注左移一个像素"><i class="fa fa-long-arrow-left" aria-hidden="true" ></i></li> | |||||
| <li id="arrow-right" style="font-size: 26px" onclick="moveRightOnePx()" title="标注右移一个像素"><i class="fa fa-long-arrow-right" aria-hidden="true"></i></li> | |||||
| <li id="arrow-up" style="font-size: 26px" onclick="moveUpOnePx()" title="标注上移一个像素"><i class="fa fa-long-arrow-up" aria-hidden="true"></i></li> | |||||
| <li id="arrow-down" style="font-size: 26px" onclick="moveDownOnePx()" title="标注下移一个像素"><i class="fa fa-long-arrow-down" aria-hidden="true"></i></li> | |||||
| <li id="delete_all_shape" style="font-size: 22px;" onclick="deleteAllRect()" title="删除所有的标注框"><i class="fa fa-window-close-o" style="vertical-align: middle;" aria-hidden="true" ></i></li> | |||||
| <li id="setting" onclick="updateSetting()" title="设置" href="#labeldefine"><svg height="24" viewbox="0 0 28 28"><use xlink:href="#icon_settings"></use></svg></li> | |||||
| <li id="skip" style="font-size: 22px" onclick="skipLast()" title="跳转至上次标注的地方"><i class="fa fa-share" aria-hidden="true"></i></li> | |||||
| <li style="font-size: 22px" onclick="setAutoModel()" title="自动标注" href="#autoLabel" data-toggle="modal" data-backdrop="static" ><i class="fa fa-tag" aria-hidden="true"></i></li> | |||||
| <li style="font-size: 22px" onclick="undo()" title="撤销上次标注(Z)" ><i class="fa fa-undo" aria-hidden="true"></i></li> | |||||
| <li style="font-size: 22px" title="清空指定文件的标注" href="#deleteLabel" data-toggle="modal" data-backdrop="static" ><i class="fa fa-eraser" aria-hidden="true"></i></li> | |||||
| </ul> | |||||
| </div> | |||||
| <div id=labeldefine> | |||||
| </div> | |||||
| </nav> --> | |||||
| <div id="labelwin" width="100%" style="display: flex;justify-content: center;align-content: center;" > | |||||
| <input type="hidden" class="form-control" id="postmessage" > | |||||
| <div id = "show_region" style="z-index: 50000;width: 0px;height: 0px"></div> | |||||
| <canvas id="myCanvas" style="border:1px solid #5a5a5a;"></canvas> | |||||
| <div id="float_text"></div> | |||||
| </div> | |||||
| </div> | |||||
| <!-- right side --> | |||||
| <div class="col-lg-2" style="background-color: #020004;height: 100%;border-top: 1px solid #222324;padding: 0;"> | |||||
| <div style="line-height: 3em;text-align: center;font-size: 14px;"> | |||||
| <span id="task_info" style="color: #fff;float: left;padding-left: 1.5em;">train数据集标注任务</span> | |||||
| <!-- <a style="float: right;padding-right: 2em;"><i class="fa fa-cog" style="color: #74818D;font-size: 18px;cursor: pointer;"></i></a> --> | |||||
| </div> | |||||
| <div class="progress" style="clear: both;margin: 0 2em 0 1em;height: 0.5em;"> | |||||
| <div class="progress-bar" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 60%;background-color: #389E0D;"> | |||||
| <span class="sr-only">60% Complete</span> | |||||
| </div> | |||||
| </div> | |||||
| <div style="margin: 1em 1.5em;font-size: 10px;"> | |||||
| <span style="color: #7092BE;margin-right: 1em;">任务标注进度</span><span id="task_progress" style="color:#7092BE;"></span> | |||||
| </div> | |||||
| <div class="panel" style="margin-bottom: 1em;"> | |||||
| <div id = "labelStatus"></div> | |||||
| </div> | |||||
| <div id="nav" style="height:100%"> | |||||
| <ul style="display: flex;padding: 0;margin: 0;color:#7092BE;"> | |||||
| <li id="0" class="active">文件列表</li> | |||||
| <li id="1">标签列表</li> | |||||
| </ul> | |||||
| <div class="tabpannel" style="height: 100%;"> | |||||
| <!-- <h4 class="ui top attached header"> | |||||
| 文件列表 | |||||
| </h4> --> | |||||
| <!-- <table class="ui single line table" id="filelist" style="table-layout:fixed;word-break: break-all;word-wrap: break-word;"> | |||||
| </table> --> | |||||
| <div class="panel-body no-padding" id="filepanel" style="height: 100%;"> | |||||
| <div style="display: flex;padding: 0.3em 0;border-bottom: 1px solid #222324 ;"> | |||||
| <span style="flex: 3;padding-left: 20px;color: #7092BE;">文件名</span> | |||||
| <div class="btn-group" style="flex:1"> | |||||
| <button type="button" class="btn-default dropdown-toggle" | |||||
| data-toggle="dropdown" style="background: transparent;padding: 0;border: 0;vertical-align: top;line-height: 1;color: #7092BE;"> | |||||
| ... | |||||
| </button> | |||||
| <ul class="dropdown-menu" role="menu" style="left:-90px;background: #020004;border: 1px solid #222324;border-radius: 0;width:2em;min-width: 8em;color: #fff;"> | |||||
| <li value="1" onclick="showOrder($(this).attr('value'))" style="font-size: 8px;color: #fff;padding: 0.3em 0 0.3em 2em;width: 100%;text-align: start;border-bottom: 0.5px solid #222324;">按文件名排序</li> | |||||
| <li value="2" onclick="showOrder($(this).attr('value'))" style="font-size: 8px;color: #fff;padding: 0.3em 0 0.3em 2em;width: 100%;text-align: start;">未标注</li> | |||||
| </ul> | |||||
| </div> | |||||
| </div> | |||||
| <table class="table table-condensed table-define" id="filelist" style="table-layout:fixed;overflow:auto;word-break: break-all;word-wrap: break-word;color:#7092BE;font-size: 10px;"> | |||||
| </table> | |||||
| </div> | |||||
| <div class="panel-body" id="filepanel" style='position: absolute;bottom: 0;padding: 0.9em 0;width: 100%;border-top: 1px #ccc solid; color: #7092BE;'> | |||||
| <div style="width: 80%; margin: 0 10%;"> | |||||
| <a id="prePage" href="" style="margin-right: 0.2em;"><i class="fa fa-angle-left"></i></a> | |||||
| <span id="startIndex">0</span>-<span id="endIndex">0</span>/<span id="totalNum">0</span> | |||||
| <span style="margin-left: 0.2em;">第</span><span id="displayPage1">1</span><span style="margin-right: 0.2em;">页</span> | |||||
| <span>跳到</span><input type="text" id="goNum" style="width: 2em;border-radius: 4px;padding: 0 0.4em;margin: 0 0.4em;height: 1.2em;border: 1px solid;" maxlength="5" oninput="value=value.replace(/[^\d]/g,'')"><span>页</span> | |||||
| <a style="margin-left: 0.4em;" id="nextPage" href=""><i class="fa fa-angle-right"></i></a> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <div class="hide1 tabpannel"> | |||||
| <div class="panel-body no-padding" id="labelpanel"> | |||||
| <table class="table table-condensed table-define" style="color: #fff;" > | |||||
| <tbody id="boxlabels"> | |||||
| </tbody> | |||||
| </table> | |||||
| </div><!-- /.panel-body --> | |||||
| <div class="panel-body no-padding" id="labelcountpanel" style="display: none;"> | |||||
| <table class="table table-condensed" id="labelcounttable"> | |||||
| </table> | |||||
| </div><!-- /.panel-body --> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <div class="panel" id="set_attributes" class="force_small_font display_area_content" style="display:none;"> | |||||
| <button class="close" onclick="close_attribute()" style=" padding: .3em 0.8em;"> × </button> | |||||
| <div id="user_input_panel"></div> | |||||
| <div id="message_panel"> | |||||
| <div id="message_panel_content" class="content"></div> | |||||
| </div> | |||||
| <div id="leftsidebar_collapse_panel"> | |||||
| <span class="text_button" onclick="leftsidebar_toggle()" title="Show left sidebar">▸</span> | |||||
| </div> | |||||
| <div id="leftsidebar"> | |||||
| <div class="leftsidebar_accordion_panel show" id="attributes_editor_panel"> | |||||
| <div class="button_panel" style="padding:1rem 0;"> | |||||
| <h4 class="modal-title">设置</h4> | |||||
| </div> | |||||
| <div id="attributes_update_panel"> | |||||
| <div class="button_panel"> | |||||
| <input style="width:50%" type="text" placeholder="attribute name" id="user_input_attribute_id" value=""> | |||||
| <span id="button_add_new_attribute" class="button" onclick="add_new_attribute_from_user_input()" title="Add new attribute">+</span> | |||||
| </div> | |||||
| <div class="button_panel" style="margin:0.1rem 0;width:70%;" > | |||||
| <table class="table table-hover" id="attributes_name_list"> | |||||
| </table> | |||||
| </div> | |||||
| <div id="atttibute_child" > | |||||
| <div id="type_car" style="display: none;"> | |||||
| <span class= "btn btn-xs btn-success" style="margin-left:5px" onclick="show_tpye_attribute();">点击此处快速添加常用车辆类别</span> | |||||
| </div> | |||||
| <div id="type_color" style="display: none;"> | |||||
| <span class= "btn btn-xs btn-success" style="margin-left:5px" onclick="show_color_attribute();">点击此处快速添加常用颜色</span> | |||||
| </div> | |||||
| <div id="attribute_properties"> </div> | |||||
| <div id="attribute_options"></div> | |||||
| <p style="text-align:center"></p> | |||||
| </div> | |||||
| </div> | |||||
| <div> | |||||
| <button type="button" class="btn btn-default" onclick="save_attribute()" id="save" style=" margin:0.5rem 0.3rem "> 保存属性值</button> | |||||
| <button type="button" class="btn btn-default" onclick="export_attribute()" id="export" style=" margin:0.5rem 0.3rem;float:right"> 导出属性值</button> | |||||
| <button type="button" class="btn btn-default" onclick="import_attribute()" id="import" style=" margin:0.5rem 0.3rem;float:right"> 导入属性值</button> | |||||
| </div> | |||||
| </div> | |||||
| </div> <!-- Dialog setAttribute --> | |||||
| <div style="width: 100%;" id="vertical_space"></div> | |||||
| </div><!-- /.panel --> | |||||
| <div aria-hidden="true" aria-labelledby="myModalLabel" role="dialog" tabindex="-1" id="autoLabel" class="modal fade"> | |||||
| <div class="modal-dialog"> | |||||
| <div class="modal-content"> | |||||
| <div class="modal-header"> | |||||
| <button aria-hidden="true" data-dismiss="modal" class="close" type="button">×</button> | |||||
| <h4 class="modal-title">自动标注</h4> | |||||
| </div> | |||||
| <div class="modal-body"> | |||||
| <form role="form"> | |||||
| <div class="form-group"> | |||||
| <label for="exampleInputPassword1">自动标注任务使用的模型</label> | |||||
| <select class="form-control" name="预检模型" id="predict_model" onchange="model_sele_Change(this)"> | |||||
| <option value="" >请选择</option> | |||||
| <!--<option value="1" selected="">Faster RCNN</option> --> | |||||
| </select> | |||||
| </div> | |||||
| <div id="tracking_startid_div" class="form-group" style="display:none"> | |||||
| <label for="exampleInputEmail1">追踪起始图片ID</label> | |||||
| <input type="" class="form-control" id="tracking_startid" placeholder="追踪起始图片ID"> | |||||
| </div> | |||||
| <div id="tracking_endid_div" class="form-group" style="display:none"> | |||||
| <label for="exampleInputEmail1">追踪结束图片ID</label> | |||||
| <input type="" class="form-control" id="tracking_endid" placeholder="追踪结束图片ID"> | |||||
| </div> | |||||
| <div id="label_id_div" class="form-group"> | |||||
| <label for="exampleInputEmail1">标注框ID</label> | |||||
| <input type="" class="form-control" id="label_id" placeholder="标注框ID"> | |||||
| </div> | |||||
| <div id="labelOption_div" class="form-group"> | |||||
| <label for="exampleInputEmail1">标注信息选项</label> | |||||
| <select class="form-control" name="labelOption" id="labelOption"> | |||||
| <option value="4">请选择</option> | |||||
| <!--<option value="0" selected="">合并已有的标注信息</option> | |||||
| <option value="1">删除已有的标注信息</option> | |||||
| <option value="2">识别车的颜色及车的类型</option> --> | |||||
| </select> | |||||
| </div> | |||||
| <div id="progress"> | |||||
| <div id="bar"></div> | |||||
| </div> | |||||
| <div><h5 id="text-progress">0%</h3></div> | |||||
| <button id="predtask_id" type="button" onclick="submit_predtask();">提交</button> | |||||
| </form> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <div aria-hidden="true" aria-labelledby="myModalLabel" role="dialog" tabindex="-1" id="deleteLabel" class="modal fade"> | |||||
| <div class="modal-dialog"> | |||||
| <div class="modal-content"> | |||||
| <div class="modal-header"> | |||||
| <button aria-hidden="true" data-dismiss="modal" class="close" type="button">×</button> | |||||
| <h4 class="modal-title">清空指定文件的标注</h4> | |||||
| </div> | |||||
| <div class="modal-body"> | |||||
| <form role="form"> | |||||
| <div id="delete_startid_div" class="form-group"> | |||||
| <label for="exampleInputEmail1">起始文件ID(对应文件列表中第几条)</label> | |||||
| <input type="" class="form-control" id="delete_startid" placeholder="起始文件ID"> | |||||
| </div> | |||||
| <div id="delete_endid_div" class="form-group"> | |||||
| <label for="exampleInputEmail1">结束文件ID(对应文件列表中第几条)</label> | |||||
| <input type="" class="form-control" id="delete_endid" placeholder="结束文件ID"> | |||||
| </div> | |||||
| <button id="predtask_id" type="button" onclick="submit_deletelabel();">提交</button> | |||||
| </form> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <div aria-hidden="true" aria-labelledby="myModalLabelc" role="dialog" tabindex="-1" id="datasetModal" class="modal fade"> | |||||
| <div class="modal-dialog"> | |||||
| <div class="modal-content"> | |||||
| <div class="modal-header"> | |||||
| <button aria-hidden="true" data-dismiss="modal" class="close" type="button">×</button> | |||||
| <h4 class="modal-title">导入标注属性</h4> | |||||
| </div> | |||||
| <div class="modal-body"> | |||||
| <div class="form-group"> | |||||
| <label id = "labelInfo" for="exampleInputFile">请输入符合格式Json字符串<font color=red>*</font> </label> | |||||
| <div> | |||||
| <textarea id="jsoninput" rows="8" cols="70"> </textarea> | |||||
| </div> | |||||
| </div> | |||||
| <button id="btnSubmit" type="button" onclick="submit_import_property();">提交</button> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <script> | |||||
| // back to label table | |||||
| var back_url = sessionStorage.getItem('return_url') | |||||
| document.getElementById('return_url').setAttribute('href',back_url); | |||||
| var ulObj = document.getElementById('nav').getElementsByTagName('ul')[0]; | |||||
| var divObj = document.getElementsByClassName('tabpannel'); | |||||
| var liObj = document.getElementById('nav').getElementsByTagName('li') | |||||
| ulObj.onclick = function(event){ | |||||
| var ev = window.event || event; | |||||
| var item = ev.srcElement || ev.target; | |||||
| var id = item.getAttribute("id") | |||||
| for (var i=0; i<divObj.length;i++){ | |||||
| if(i == id){ | |||||
| divObj[i].style.display = 'block' | |||||
| liObj[i].classList.add('active') | |||||
| } | |||||
| else{ | |||||
| divObj[i].style.display = 'none' | |||||
| liObj[i].classList.remove('active') | |||||
| } | |||||
| } | |||||
| } | |||||
| </script> | |||||
| <script> | |||||
| var box = document.getElementsByClassName("box1")[0]; //获取元素 | |||||
| var x, y; //鼠标相对与div左边,上边的偏移 | |||||
| var isDrop = false; //移动状态的判断鼠标按下才能移动 | |||||
| box.onmousedown = function(e) { | |||||
| var e = e || window.event; //要用event这个对象来获取鼠标的位置 | |||||
| x = e.clientX - box.offsetLeft; | |||||
| y = e.clientY - box.offsetTop; | |||||
| isDrop = true; //设为true表示可以移动 | |||||
| } | |||||
| document.onmousemove = function(e) { | |||||
| //是否为可移动状态 | |||||
| if(isDrop) { | |||||
| var e = e || window.event; | |||||
| var moveX = e.clientX - x; //得到距离左边移动距离 | |||||
| var moveY = e.clientY - y; //得到距离上边移动距离 | |||||
| //可移动最大距离 | |||||
| var maxX = document.documentElement.clientWidth - box.offsetWidth; | |||||
| var maxY = document.documentElement.clientHeight - box.offsetHeight; | |||||
| //范围限定 当移动的距离最小时取最大 移动的距离最大时取最小 | |||||
| //范围限定方法一 | |||||
| /*if(moveX < 0) { | |||||
| moveX = 0 | |||||
| } else if(moveX > maxX) { | |||||
| moveX = maxX; | |||||
| } | |||||
| if(moveY < 0) { | |||||
| moveY = 0; | |||||
| } else if(moveY > maxY) { | |||||
| moveY = maxY; | |||||
| } */ | |||||
| //范围限定方法二 | |||||
| moveX=Math.min(maxX, Math.max(0,moveX)); | |||||
| moveY=Math.min(maxY, Math.max(0,moveY)); | |||||
| box.style.left = moveX + "px"; | |||||
| box.style.top = moveY + "px"; | |||||
| } else { | |||||
| return; | |||||
| } | |||||
| } | |||||
| document.onmouseup = function() { | |||||
| isDrop = false; //设置为false不可移动 | |||||
| } | |||||
| </script> | |||||
| <script src="/self/func.js" type="text/javascript"></script> | |||||
| <!-- jQuery 2.0.2 --> | |||||
| <!-- --> | |||||
| <script src="/self/js/jquery.min.js" type="text/javascript"></script> | |||||
| <script src="/self/js/jquery.mousewheel.js"></script> | |||||
| <script src="/self/js/jquery.jscrollpane.js"></script> | |||||
| <!-- Bootstrap --> | |||||
| <script src="/self/js/bootstrap.min.js" type="text/javascript"></script> | |||||
| <script src="/self/js/app.js" type="text/javascript" ></script> | |||||
| <script src="/self/js/Director/labelingSelfDefine.js" type="text/javascript"></script> | |||||
| <script src="/self/js/Director/detection.js" type="text/javascript" ></script> | |||||
| <!-- <script src="../js/labelx.js"></script> --> | |||||
| </body> | |||||
| </html> | |||||
| @@ -7,6 +7,7 @@ package routers | |||||
| import ( | import ( | ||||
| "bytes" | "bytes" | ||||
| "net/http" | |||||
| "strings" | "strings" | ||||
| "code.gitea.io/gitea/models" | "code.gitea.io/gitea/models" | ||||
| @@ -32,7 +33,8 @@ const ( | |||||
| // tplExploreOrganizations explore organizations page template | // tplExploreOrganizations explore organizations page template | ||||
| tplExploreOrganizations base.TplName = "explore/organizations" | tplExploreOrganizations base.TplName = "explore/organizations" | ||||
| // tplExploreCode explore code page template | // tplExploreCode explore code page template | ||||
| tplExploreCode base.TplName = "explore/code" | |||||
| tplExploreCode base.TplName = "explore/code" | |||||
| tplExploreImages base.TplName = "explore/images" | |||||
| ) | ) | ||||
| // Home render home page | // Home render home page | ||||
| @@ -135,11 +137,17 @@ func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) { | |||||
| orderBy = models.SearchOrderByForksReverse | orderBy = models.SearchOrderByForksReverse | ||||
| case "fewestforks": | case "fewestforks": | ||||
| orderBy = models.SearchOrderByForks | orderBy = models.SearchOrderByForks | ||||
| case "hot": | |||||
| orderBy = models.SearchOrderByHot | |||||
| case "active": | |||||
| orderBy = models.SearchOrderByActive | |||||
| default: | default: | ||||
| ctx.Data["SortType"] = "recentupdate" | |||||
| orderBy = models.SearchOrderByRecentUpdated | |||||
| ctx.Data["SortType"] = "hot" | |||||
| orderBy = models.SearchOrderByHot | |||||
| } | } | ||||
| //todo:support other topics | |||||
| keyword := strings.Trim(ctx.Query("q"), " ") | keyword := strings.Trim(ctx.Query("q"), " ") | ||||
| topicOnly := ctx.QueryBool("topic") | topicOnly := ctx.QueryBool("topic") | ||||
| ctx.Data["TopicOnly"] = topicOnly | ctx.Data["TopicOnly"] = topicOnly | ||||
| @@ -163,6 +171,11 @@ func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) { | |||||
| ctx.ServerError("SearchRepository", err) | ctx.ServerError("SearchRepository", err) | ||||
| return | return | ||||
| } | } | ||||
| for _, repo := range repos { | |||||
| repo.Hot = int64(repo.NumWatches) + int64(repo.NumStars) + int64(repo.NumForks) + int64(repo.CloneCnt) | |||||
| repo.Active = int64(repo.NumIssues) + int64(repo.NumPulls) + int64(repo.NumCommit) | |||||
| } | |||||
| ctx.Data["Keyword"] = keyword | ctx.Data["Keyword"] = keyword | ||||
| ctx.Data["Total"] = count | ctx.Data["Total"] = count | ||||
| ctx.Data["Repos"] = repos | ctx.Data["Repos"] = repos | ||||
| @@ -173,7 +186,15 @@ func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) { | |||||
| pager.AddParam(ctx, "topic", "TopicOnly") | pager.AddParam(ctx, "topic", "TopicOnly") | ||||
| ctx.Data["Page"] = pager | ctx.Data["Page"] = pager | ||||
| ctx.HTML(200, opts.TplName) | |||||
| recommendOrgs, err := models.GetRecommendOrgInfos() | |||||
| if err != nil { | |||||
| log.Error("GetRecommendOrgInfos failed:%v", err.Error(), ctx.Data["MsgID"]) | |||||
| ctx.ServerError("GetRecommendOrgInfos", err) | |||||
| return | |||||
| } | |||||
| ctx.Data["RecommendOrgs"] = recommendOrgs | |||||
| ctx.HTML(http.StatusOK, opts.TplName) | |||||
| } | } | ||||
| // ExploreRepos render explore repositories page | // ExploreRepos render explore repositories page | ||||
| @@ -475,6 +496,10 @@ func ExploreCode(ctx *context.Context) { | |||||
| ctx.HTML(200, tplExploreCode) | ctx.HTML(200, tplExploreCode) | ||||
| } | } | ||||
| func ExploreImages(ctx *context.Context) { | |||||
| ctx.HTML(200, tplExploreImages) | |||||
| } | |||||
| // NotFound render 404 page | // NotFound render 404 page | ||||
| func NotFound(ctx *context.Context) { | func NotFound(ctx *context.Context) { | ||||
| ctx.Data["Title"] = "Page Not Found" | ctx.Data["Title"] = "Page Not Found" | ||||
| @@ -22,6 +22,7 @@ import ( | |||||
| code_indexer "code.gitea.io/gitea/modules/indexer/code" | code_indexer "code.gitea.io/gitea/modules/indexer/code" | ||||
| issue_indexer "code.gitea.io/gitea/modules/indexer/issues" | issue_indexer "code.gitea.io/gitea/modules/indexer/issues" | ||||
| stats_indexer "code.gitea.io/gitea/modules/indexer/stats" | stats_indexer "code.gitea.io/gitea/modules/indexer/stats" | ||||
| "code.gitea.io/gitea/modules/labelmsg" | |||||
| "code.gitea.io/gitea/modules/log" | "code.gitea.io/gitea/modules/log" | ||||
| "code.gitea.io/gitea/modules/markup" | "code.gitea.io/gitea/modules/markup" | ||||
| "code.gitea.io/gitea/modules/markup/external" | "code.gitea.io/gitea/modules/markup/external" | ||||
| @@ -63,6 +64,7 @@ func NewServices() { | |||||
| _ = cache.NewContext() | _ = cache.NewContext() | ||||
| notification.NewContext() | notification.NewContext() | ||||
| decompression.NewContext() | decompression.NewContext() | ||||
| labelmsg.Init() | |||||
| } | } | ||||
| // In case of problems connecting to DB, retry connection. Eg, PGSQL in Docker Container on Synology | // In case of problems connecting to DB, retry connection. Eg, PGSQL in Docker Container on Synology | ||||
| @@ -0,0 +1,64 @@ | |||||
| // Copyright 2014 The Gogs Authors. All rights reserved. | |||||
| // Copyright 2020 The Gitea Authors. | |||||
| // Use of this source code is governed by a MIT-style | |||||
| // license that can be found in the LICENSE file. | |||||
| package operation | |||||
| import ( | |||||
| "code.gitea.io/gitea/models" | |||||
| "code.gitea.io/gitea/modules/base" | |||||
| "code.gitea.io/gitea/modules/context" | |||||
| "code.gitea.io/gitea/modules/log" | |||||
| "code.gitea.io/gitea/modules/setting" | |||||
| "code.gitea.io/gitea/modules/structs" | |||||
| "code.gitea.io/gitea/routers" | |||||
| ) | |||||
| const ( | |||||
| tplOrgs base.TplName = "admin/org/list" | |||||
| ) | |||||
| type UpdateRecommendOrgs struct { | |||||
| OrgInfos string `binding:"required"` | |||||
| } | |||||
| type OrgInfo struct { | |||||
| OrgID int64 `json:"org_id"` | |||||
| Order int64 `json:"order"` | |||||
| } | |||||
| type OrgInfos struct { | |||||
| OrgInfo []OrgInfo `json:"org_infos"` | |||||
| } | |||||
| // Organizations show all the organizations recommended | |||||
| func Organizations(ctx *context.Context) { | |||||
| ctx.Data["PageIsAdmin"] = true | |||||
| ctx.Data["PageIsAdminOrganizations"] = true | |||||
| routers.RenderUserSearch(ctx, &models.SearchUserOptions{ | |||||
| Type: models.UserTypeOrganization, | |||||
| ListOptions: models.ListOptions{ | |||||
| PageSize: setting.UI.Admin.OrgPagingNum, | |||||
| }, | |||||
| Visible: []structs.VisibleType{structs.VisibleTypePublic, structs.VisibleTypeLimited, structs.VisibleTypePrivate}, | |||||
| }, tplOrgs) | |||||
| } | |||||
| // UpdateRecommendOrganizations update the organizations recommended | |||||
| func UpdateRecommendOrganizations(ctx *context.Context, req OrgInfos) { | |||||
| orgs := make(models.RecommendOrgList, 0, 10) | |||||
| for _, org := range req.OrgInfo { | |||||
| orgs = append(orgs, &models.RecommendOrg{ | |||||
| OrgID: org.OrgID, | |||||
| Order: org.Order, | |||||
| }) | |||||
| } | |||||
| if err := models.UpdateRecommendOrgs(orgs); err != nil { | |||||
| log.Error("UpdateRecommendOrgs failed:%v", err.Error(), ctx.Data["MsgID"]) | |||||
| ctx.ServerError("UpdateRecommendOrgs failed", err) | |||||
| return | |||||
| } | |||||
| } | |||||
| @@ -20,6 +20,7 @@ const ( | |||||
| // Home show organization home page | // Home show organization home page | ||||
| func Home(ctx *context.Context) { | func Home(ctx *context.Context) { | ||||
| ctx.SetParams(":org", ctx.Params(":username")) | ctx.SetParams(":org", ctx.Params(":username")) | ||||
| ctx.Data["PageIsOrgHome"] = true | |||||
| context.HandleOrgAssignment(ctx) | context.HandleOrgAssignment(ctx) | ||||
| if ctx.Written() { | if ctx.Written() { | ||||
| return | return | ||||
| @@ -0,0 +1,37 @@ | |||||
| // Copyright 2020 The Gitea Authors. All rights reserved. | |||||
| // Use of this source code is governed by a MIT-style | |||||
| // license that can be found in the LICENSE file. | |||||
| package private | |||||
| import ( | |||||
| "gitea.com/macaron/macaron" | |||||
| "net/http" | |||||
| "code.gitea.io/gitea/models" | |||||
| "code.gitea.io/gitea/modules/log" | |||||
| ) | |||||
| func UpdateAllRepoCommitCnt(ctx *macaron.Context) { | |||||
| repos, err := models.GetAllRepositories() | |||||
| if err != nil { | |||||
| log.Error("GetAllRepositories failed:%v", err.Error(), ctx.Data["MsgID"]) | |||||
| ctx.JSON(http.StatusInternalServerError, map[string]string{ | |||||
| "error_msg": "GetAllRepositories failed", | |||||
| }) | |||||
| return | |||||
| } | |||||
| for i, repo := range repos { | |||||
| log.Info("%d:begin updateRepoCommitCnt(id = %d, name = %s)", i, repo.ID, repo.Name) | |||||
| if err = updateRepoCommitCnt(ctx, repo); err != nil { | |||||
| log.Error("updateRepoCommitCnt(id = %d, name = %s) failed:%v", repo.ID, repo.Name, err.Error(), ctx.Data["MsgID"]) | |||||
| continue | |||||
| } | |||||
| log.Info("%d:finish updateRepoCommitCnt(id = %d, name = %s)", i, repo.ID, repo.Name) | |||||
| } | |||||
| ctx.JSON(http.StatusOK, map[string]string{ | |||||
| "error_msg": "", | |||||
| }) | |||||
| } | |||||
| @@ -520,12 +520,40 @@ func HookPostReceive(ctx *macaron.Context, opts private.HookOptions) { | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if err := updateRepoCommitCnt(ctx, repo); err != nil { | |||||
| log.Error("updateRepoCommitCnt failed:%v", err.Error(), ctx.Data["MsgID"]) | |||||
| } | |||||
| ctx.JSON(http.StatusOK, private.HookPostReceiveResult{ | ctx.JSON(http.StatusOK, private.HookPostReceiveResult{ | ||||
| Results: results, | Results: results, | ||||
| RepoWasEmpty: wasEmpty, | RepoWasEmpty: wasEmpty, | ||||
| }) | }) | ||||
| } | } | ||||
| func updateRepoCommitCnt(ctx *macaron.Context, repo *models.Repository) error { | |||||
| gitRepo, err := git.OpenRepository(repo.RepoPath()) | |||||
| if err != nil { | |||||
| log.Error("OpenRepository failed:%v", err.Error(), ctx.Data["MsgID"]) | |||||
| return err | |||||
| } | |||||
| defer gitRepo.Close() | |||||
| count, err := gitRepo.GetAllCommitsCount() | |||||
| if err != nil { | |||||
| log.Error("GetAllCommitsCount failed:%v", err.Error(), ctx.Data["MsgID"]) | |||||
| return err | |||||
| } | |||||
| repo.NumCommit = count | |||||
| if err = models.UpdateRepositoryCommitNum(repo); err != nil { | |||||
| log.Error("UpdateRepositoryCommitNum failed:%v", err.Error(), ctx.Data["MsgID"]) | |||||
| return err | |||||
| } | |||||
| return nil | |||||
| } | |||||
| // SetDefaultBranch updates the default branch | // SetDefaultBranch updates the default branch | ||||
| func SetDefaultBranch(ctx *macaron.Context) { | func SetDefaultBranch(ctx *macaron.Context) { | ||||
| ownerName := ctx.Params(":owner") | ownerName := ctx.Params(":owner") | ||||
| @@ -42,6 +42,7 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
| m.Post("/manager/shutdown", Shutdown) | m.Post("/manager/shutdown", Shutdown) | ||||
| m.Post("/manager/restart", Restart) | m.Post("/manager/restart", Restart) | ||||
| m.Post("/manager/flush-queues", bind(private.FlushOptions{}), FlushQueues) | m.Post("/manager/flush-queues", bind(private.FlushOptions{}), FlushQueues) | ||||
| m.Post("/cmd/update_all_repo_commit_cnt", UpdateAllRepoCommitCnt) | |||||
| }, CheckInternalToken) | }, CheckInternalToken) | ||||
| } | } | ||||
| @@ -17,6 +17,7 @@ import ( | |||||
| "code.gitea.io/gitea/models" | "code.gitea.io/gitea/models" | ||||
| "code.gitea.io/gitea/modules/context" | "code.gitea.io/gitea/modules/context" | ||||
| "code.gitea.io/gitea/modules/labelmsg" | |||||
| "code.gitea.io/gitea/modules/log" | "code.gitea.io/gitea/modules/log" | ||||
| "code.gitea.io/gitea/modules/minio_ext" | "code.gitea.io/gitea/modules/minio_ext" | ||||
| "code.gitea.io/gitea/modules/setting" | "code.gitea.io/gitea/modules/setting" | ||||
| @@ -131,7 +132,19 @@ func DeleteAttachment(ctx *context.Context) { | |||||
| ctx.Error(403) | ctx.Error(403) | ||||
| return | return | ||||
| } | } | ||||
| err = models.DeleteAttachment(attach, false) | |||||
| err = models.DeleteAttachment(attach, true) | |||||
| if err != nil { | |||||
| ctx.Error(500, fmt.Sprintf("DeleteAttachment: %v", err)) | |||||
| return | |||||
| } | |||||
| attachjson, _ := json.Marshal(attach) | |||||
| labelmsg.SendDeleteAttachToLabelSys(string(attachjson)) | |||||
| DeleteAllUnzipFile(attach, "") | |||||
| _, err = models.DeleteFileChunkById(attach.UUID) | |||||
| if err != nil { | if err != nil { | ||||
| ctx.Error(500, fmt.Sprintf("DeleteAttachment: %v", err)) | ctx.Error(500, fmt.Sprintf("DeleteAttachment: %v", err)) | ||||
| return | return | ||||
| @@ -141,6 +154,35 @@ func DeleteAttachment(ctx *context.Context) { | |||||
| }) | }) | ||||
| } | } | ||||
| func DownloadUserIsOrgOrCollaboration(ctx *context.Context, attach *models.Attachment) bool { | |||||
| dataset, err := models.GetDatasetByID(attach.DatasetID) | |||||
| if err != nil { | |||||
| log.Info("query dataset error") | |||||
| } else { | |||||
| repo, err := models.GetRepositoryByID(dataset.RepoID) | |||||
| if err != nil { | |||||
| log.Info("query repo error.") | |||||
| } else { | |||||
| repo.GetOwner() | |||||
| if ctx.User != nil { | |||||
| if repo.Owner.IsOrganization() { | |||||
| if repo.Owner.IsUserPartOfOrg(ctx.User.ID) { | |||||
| log.Info("org user may visit the attach.") | |||||
| return true | |||||
| } | |||||
| } | |||||
| isCollaborator, _ := repo.IsCollaborator(ctx.User.ID) | |||||
| if isCollaborator { | |||||
| log.Info("Collaborator user may visit the attach.") | |||||
| return true | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| return false | |||||
| } | |||||
| // GetAttachment serve attachements | // GetAttachment serve attachements | ||||
| func GetAttachment(ctx *context.Context) { | func GetAttachment(ctx *context.Context) { | ||||
| typeCloudBrain := ctx.QueryInt("type") | typeCloudBrain := ctx.QueryInt("type") | ||||
| @@ -165,16 +207,29 @@ func GetAttachment(ctx *context.Context) { | |||||
| ctx.ServerError("LinkedRepository", err) | ctx.ServerError("LinkedRepository", err) | ||||
| return | return | ||||
| } | } | ||||
| dataSet, err := attach.LinkedDataSet() | |||||
| if err != nil { | |||||
| ctx.ServerError("LinkedDataSet", err) | |||||
| return | |||||
| } | |||||
| if repository == nil && dataSet != nil { | |||||
| repository, _ = models.GetRepositoryByID(dataSet.RepoID) | |||||
| unitType = models.UnitTypeDatasets | |||||
| } | |||||
| if repository == nil { //If not linked | if repository == nil { //If not linked | ||||
| if !(ctx.IsSigned && attach.UploaderID == ctx.User.ID) && attach.IsPrivate { //We block if not the uploader | |||||
| //if !(ctx.IsSigned && attach.UploaderID == ctx.User.ID) && attach.IsPrivate { //We block if not the uploader | |||||
| //log.Info("ctx.IsSigned =" + fmt.Sprintf("%v", ctx.IsSigned)) | |||||
| if !(ctx.IsSigned && attach.UploaderID == ctx.User.ID) && attach.IsPrivate && !DownloadUserIsOrgOrCollaboration(ctx, attach) { //We block if not the uploader | |||||
| ctx.Error(http.StatusNotFound) | ctx.Error(http.StatusNotFound) | ||||
| return | return | ||||
| } | } | ||||
| } else { //If we have the repository we check access | } else { //If we have the repository we check access | ||||
| perm, err := models.GetUserRepoPermission(repository, ctx.User) | |||||
| if err != nil { | |||||
| ctx.Error(http.StatusInternalServerError, "GetUserRepoPermission", err.Error()) | |||||
| perm, errPermission := models.GetUserRepoPermission(repository, ctx.User) | |||||
| if errPermission != nil { | |||||
| ctx.Error(http.StatusInternalServerError, "GetUserRepoPermission", errPermission.Error()) | |||||
| return | return | ||||
| } | } | ||||
| if !perm.CanRead(unitType) { | if !perm.CanRead(unitType) { | ||||
| @@ -183,12 +238,6 @@ func GetAttachment(ctx *context.Context) { | |||||
| } | } | ||||
| } | } | ||||
| dataSet, err := attach.LinkedDataSet() | |||||
| if err != nil { | |||||
| ctx.ServerError("LinkedDataSet", err) | |||||
| return | |||||
| } | |||||
| if dataSet != nil { | if dataSet != nil { | ||||
| isPermit, err := models.GetUserDataSetPermission(dataSet, ctx.User) | isPermit, err := models.GetUserDataSetPermission(dataSet, ctx.User) | ||||
| if err != nil { | if err != nil { | ||||
| @@ -205,7 +254,7 @@ func GetAttachment(ctx *context.Context) { | |||||
| if setting.Attachment.StoreType == storage.MinioStorageType { | if setting.Attachment.StoreType == storage.MinioStorageType { | ||||
| url := "" | url := "" | ||||
| if typeCloudBrain == models.TypeCloudBrainOne { | if typeCloudBrain == models.TypeCloudBrainOne { | ||||
| url, err = storage.Attachments.PresignedGetURL(setting.Attachment.Minio.BasePath + attach.RelativePath(), attach.Name) | |||||
| url, err = storage.Attachments.PresignedGetURL(setting.Attachment.Minio.BasePath+attach.RelativePath(), attach.Name) | |||||
| if err != nil { | if err != nil { | ||||
| ctx.ServerError("PresignedGetURL", err) | ctx.ServerError("PresignedGetURL", err) | ||||
| return | return | ||||
| @@ -380,6 +429,21 @@ func UpdateAttachmentDecompressState(ctx *context.Context) { | |||||
| log.Error("UpdateAttachment(%s) failed:%s", uuid, err.Error()) | log.Error("UpdateAttachment(%s) failed:%s", uuid, err.Error()) | ||||
| return | return | ||||
| } | } | ||||
| log.Info("start to send msg to labelsystem ") | |||||
| dataset, _ := models.GetDatasetByID(attach.DatasetID) | |||||
| var labelMap map[string]string | |||||
| labelMap = make(map[string]string) | |||||
| labelMap["UUID"] = uuid | |||||
| labelMap["Type"] = fmt.Sprint(attach.Type) | |||||
| labelMap["UploaderID"] = fmt.Sprint(attach.UploaderID) | |||||
| labelMap["RepoID"] = fmt.Sprint(dataset.RepoID) | |||||
| labelMap["AttachName"] = attach.Name | |||||
| attachjson, _ := json.Marshal(labelMap) | |||||
| labelmsg.SendAddAttachToLabelSys(string(attachjson)) | |||||
| log.Info("end to send msg to labelsystem ") | |||||
| ctx.JSON(200, map[string]string{ | ctx.JSON(200, map[string]string{ | ||||
| "result_code": "0", | "result_code": "0", | ||||
| @@ -454,17 +518,17 @@ func GetSuccessChunks(ctx *context.Context) { | |||||
| if err != nil { | if err != nil { | ||||
| log.Error("GetObsPartInfos failed:%v", err.Error()) | log.Error("GetObsPartInfos failed:%v", err.Error()) | ||||
| } | } | ||||
| } | |||||
| if err != nil { | |||||
| models.DeleteFileChunk(fileChunk) | |||||
| ctx.JSON(200, map[string]string{ | |||||
| "uuid": "", | |||||
| "uploaded": "0", | |||||
| "uploadID": "", | |||||
| "chunks": "", | |||||
| }) | |||||
| return | |||||
| } | |||||
| if err != nil { | |||||
| models.DeleteFileChunk(fileChunk) | |||||
| ctx.JSON(200, map[string]string{ | |||||
| "uuid": "", | |||||
| "uploaded": "0", | |||||
| "uploadID": "", | |||||
| "chunks": "", | |||||
| }) | |||||
| return | |||||
| } | } | ||||
| } | } | ||||
| @@ -702,8 +766,8 @@ func CompleteMultipart(ctx *context.Context) { | |||||
| } | } | ||||
| if attachment.DatasetID != 0 { | if attachment.DatasetID != 0 { | ||||
| if typeCloudBrain == models.TypeCloudBrainOne { | |||||
| if strings.HasSuffix(attachment.Name, ".zip") { | |||||
| if strings.HasSuffix(attachment.Name, ".zip") { | |||||
| if typeCloudBrain == models.TypeCloudBrainOne { | |||||
| err = worker.SendDecompressTask(contexExt.Background(), uuid) | err = worker.SendDecompressTask(contexExt.Background(), uuid) | ||||
| if err != nil { | if err != nil { | ||||
| log.Error("SendDecompressTask(%s) failed:%s", uuid, err.Error()) | log.Error("SendDecompressTask(%s) failed:%s", uuid, err.Error()) | ||||
| @@ -715,6 +779,21 @@ func CompleteMultipart(ctx *context.Context) { | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if typeCloudBrain == models.TypeCloudBrainTwo { | |||||
| attachjson, _ := json.Marshal(attachment) | |||||
| labelmsg.SendDecompressAttachToLabelOBS(string(attachjson)) | |||||
| } | |||||
| } else { | |||||
| dataset, _ := models.GetDatasetByID(attachment.DatasetID) | |||||
| var labelMap map[string]string | |||||
| labelMap = make(map[string]string) | |||||
| labelMap["UUID"] = uuid | |||||
| labelMap["Type"] = fmt.Sprint(attachment.Type) | |||||
| labelMap["UploaderID"] = fmt.Sprint(attachment.UploaderID) | |||||
| labelMap["RepoID"] = fmt.Sprint(dataset.RepoID) | |||||
| labelMap["AttachName"] = attachment.Name | |||||
| attachjson, _ := json.Marshal(labelMap) | |||||
| labelmsg.SendAddAttachToLabelSys(string(attachjson)) | |||||
| } | } | ||||
| } | } | ||||
| @@ -1,17 +1,21 @@ | |||||
| package repo | package repo | ||||
| import ( | import ( | ||||
| "code.gitea.io/gitea/modules/git" | |||||
| "code.gitea.io/gitea/modules/storage" | |||||
| "bufio" | |||||
| "encoding/json" | "encoding/json" | ||||
| "errors" | "errors" | ||||
| "io" | |||||
| "net/http" | "net/http" | ||||
| "os" | "os" | ||||
| "os/exec" | "os/exec" | ||||
| "regexp" | |||||
| "strconv" | "strconv" | ||||
| "strings" | "strings" | ||||
| "time" | "time" | ||||
| "code.gitea.io/gitea/modules/git" | |||||
| "code.gitea.io/gitea/modules/storage" | |||||
| "code.gitea.io/gitea/models" | "code.gitea.io/gitea/models" | ||||
| "code.gitea.io/gitea/modules/auth" | "code.gitea.io/gitea/modules/auth" | ||||
| "code.gitea.io/gitea/modules/base" | "code.gitea.io/gitea/modules/base" | ||||
| @@ -22,10 +26,10 @@ import ( | |||||
| ) | ) | ||||
| const ( | const ( | ||||
| tplCloudBrainIndex base.TplName = "repo/cloudbrain/index" | |||||
| tplCloudBrainNew base.TplName = "repo/cloudbrain/new" | |||||
| tplCloudBrainShow base.TplName = "repo/cloudbrain/show" | |||||
| tplCloudBrainShowModels base.TplName = "repo/cloudbrain/models/index" | |||||
| tplCloudBrainIndex base.TplName = "repo/cloudbrain/index" | |||||
| tplCloudBrainNew base.TplName = "repo/cloudbrain/new" | |||||
| tplCloudBrainShow base.TplName = "repo/cloudbrain/show" | |||||
| tplCloudBrainShowModels base.TplName = "repo/cloudbrain/models/index" | |||||
| ) | ) | ||||
| var ( | var ( | ||||
| @@ -86,17 +90,27 @@ func cutString(str string, lens int) string { | |||||
| return str[:lens] | return str[:lens] | ||||
| } | } | ||||
| func CloudBrainNew(ctx *context.Context) { | |||||
| ctx.Data["PageIsCloudBrain"] = true | |||||
| func jobNamePrefixValid(s string) string { | |||||
| lowStr := strings.ToLower(s) | |||||
| re := regexp.MustCompile(`[^a-z0-9_\\-]+`) | |||||
| removeSpecial := re.ReplaceAllString(lowStr, "") | |||||
| re = regexp.MustCompile(`^[_\\-]+`) | |||||
| return re.ReplaceAllString(removeSpecial, "") | |||||
| } | |||||
| func cloudBrainNewDataPrepare(ctx *context.Context) error{ | |||||
| ctx.Data["PageIsCloudBrain"] = true | |||||
| t := time.Now() | t := time.Now() | ||||
| var jobName = cutString(ctx.User.Name, 5) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:] | |||||
| var jobName = jobNamePrefixValid(cutString(ctx.User.Name, 5)) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:] | |||||
| ctx.Data["job_name"] = jobName | ctx.Data["job_name"] = jobName | ||||
| result, err := cloudbrain.GetImages() | result, err := cloudbrain.GetImages() | ||||
| if err != nil { | if err != nil { | ||||
| ctx.Data["error"] = err.Error() | ctx.Data["error"] = err.Error() | ||||
| log.Error("cloudbrain.GetImages failed:", err.Error(), ctx.Data["msgID"]) | |||||
| log.Error("cloudbrain.GetImages failed:", err.Error(), ctx.Data["MsgID"]) | |||||
| } | } | ||||
| for i, payload := range result.Payload.ImageInfo { | for i, payload := range result.Payload.ImageInfo { | ||||
| @@ -112,7 +126,7 @@ func CloudBrainNew(ctx *context.Context) { | |||||
| resultPublic, err := cloudbrain.GetPublicImages() | resultPublic, err := cloudbrain.GetPublicImages() | ||||
| if err != nil { | if err != nil { | ||||
| ctx.Data["error"] = err.Error() | ctx.Data["error"] = err.Error() | ||||
| log.Error("cloudbrain.GetPublicImages failed:", err.Error(), ctx.Data["msgID"]) | |||||
| log.Error("cloudbrain.GetPublicImages failed:", err.Error(), ctx.Data["MsgID"]) | |||||
| } | } | ||||
| for i, payload := range resultPublic.Payload.ImageInfo { | for i, payload := range resultPublic.Payload.ImageInfo { | ||||
| @@ -127,8 +141,8 @@ func CloudBrainNew(ctx *context.Context) { | |||||
| attachs, err := models.GetAllUserAttachments(ctx.User.ID) | attachs, err := models.GetAllUserAttachments(ctx.User.ID) | ||||
| if err != nil { | if err != nil { | ||||
| ctx.ServerError("GetAllUserAttachments failed:", err) | |||||
| return | |||||
| log.Error("GetAllUserAttachments failed: %v", err, ctx.Data["MsgID"]) | |||||
| return err | |||||
| } | } | ||||
| ctx.Data["attachments"] = attachs | ctx.Data["attachments"] = attachs | ||||
| @@ -148,8 +162,23 @@ func CloudBrainNew(ctx *context.Context) { | |||||
| json.Unmarshal([]byte(setting.GpuTypes), &gpuInfos) | json.Unmarshal([]byte(setting.GpuTypes), &gpuInfos) | ||||
| } | } | ||||
| ctx.Data["gpu_types"] = gpuInfos.GpuInfo | ctx.Data["gpu_types"] = gpuInfos.GpuInfo | ||||
| if cloudbrain.ResourceSpecs == nil { | |||||
| json.Unmarshal([]byte(setting.ResourceSpecs), &cloudbrain.ResourceSpecs) | |||||
| } | |||||
| ctx.Data["resource_specs"] = cloudbrain.ResourceSpecs.ResourceSpec | |||||
| ctx.Data["snn4imagenet_path"] = cloudbrain.Snn4imagenetMountPath | ctx.Data["snn4imagenet_path"] = cloudbrain.Snn4imagenetMountPath | ||||
| ctx.Data["is_snn4imagenet_enabled"] = setting.IsSnn4imagenetEnabled | ctx.Data["is_snn4imagenet_enabled"] = setting.IsSnn4imagenetEnabled | ||||
| return nil | |||||
| } | |||||
| func CloudBrainNew(ctx *context.Context) { | |||||
| err := cloudBrainNewDataPrepare(ctx) | |||||
| if err != nil { | |||||
| ctx.ServerError("get new cloudbrain info failed", err) | |||||
| return | |||||
| } | |||||
| ctx.HTML(200, tplCloudBrainNew) | ctx.HTML(200, tplCloudBrainNew) | ||||
| } | } | ||||
| @@ -162,18 +191,36 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { | |||||
| jobType := form.JobType | jobType := form.JobType | ||||
| gpuQueue := setting.JobType | gpuQueue := setting.JobType | ||||
| codePath := setting.JobPath + jobName + cloudbrain.CodeMountPath | codePath := setting.JobPath + jobName + cloudbrain.CodeMountPath | ||||
| resourceSpecId := form.ResourceSpecId | |||||
| if jobType != string(models.JobTypeBenchmark) && jobType != string(models.JobTypeDebug) && jobType != string(models.JobTypeSnn4imagenet) { | if jobType != string(models.JobTypeBenchmark) && jobType != string(models.JobTypeDebug) && jobType != string(models.JobTypeSnn4imagenet) { | ||||
| log.Error("jobtype error:", jobType, ctx.Data["msgID"]) | |||||
| log.Error("jobtype error:", jobType, ctx.Data["MsgID"]) | |||||
| cloudBrainNewDataPrepare(ctx) | |||||
| ctx.RenderWithErr("jobtype error", tplCloudBrainNew, &form) | ctx.RenderWithErr("jobtype error", tplCloudBrainNew, &form) | ||||
| return | return | ||||
| } | } | ||||
| _, err := models.GetCloudbrainByName(jobName) | |||||
| if err == nil { | |||||
| log.Error("the job name did already exist", ctx.Data["MsgID"]) | |||||
| cloudBrainNewDataPrepare(ctx) | |||||
| ctx.RenderWithErr("the job name did already exist", tplCloudBrainNew, &form) | |||||
| return | |||||
| } else { | |||||
| if !models.IsErrJobNotExist(err) { | |||||
| log.Error("system error, %v", err, ctx.Data["MsgID"]) | |||||
| cloudBrainNewDataPrepare(ctx) | |||||
| ctx.RenderWithErr("system error", tplCloudBrainNew, &form) | |||||
| return | |||||
| } | |||||
| } | |||||
| repo := ctx.Repo.Repository | repo := ctx.Repo.Repository | ||||
| downloadCode(repo, codePath) | downloadCode(repo, codePath) | ||||
| modelPath := setting.JobPath + jobName + cloudbrain.ModelMountPath | modelPath := setting.JobPath + jobName + cloudbrain.ModelMountPath | ||||
| err := os.MkdirAll(modelPath, os.ModePerm) | |||||
| err = os.MkdirAll(modelPath, os.ModePerm) | |||||
| if err != nil { | if err != nil { | ||||
| cloudBrainNewDataPrepare(ctx) | |||||
| ctx.RenderWithErr(err.Error(), tplCloudBrainNew, &form) | ctx.RenderWithErr(err.Error(), tplCloudBrainNew, &form) | ||||
| return | return | ||||
| } | } | ||||
| @@ -195,8 +242,9 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { | |||||
| downloadRateCode(repo, jobName, setting.Snn4imagenetCode, snn4imagenetPath, "", "") | downloadRateCode(repo, jobName, setting.Snn4imagenetCode, snn4imagenetPath, "", "") | ||||
| } | } | ||||
| err = cloudbrain.GenerateTask(ctx, jobName, image, command, uuid, codePath, modelPath, benchmarkPath, snn4imagenetPath, jobType, gpuQueue) | |||||
| err = cloudbrain.GenerateTask(ctx, jobName, image, command, uuid, codePath, modelPath, benchmarkPath, snn4imagenetPath, jobType, gpuQueue, resourceSpecId) | |||||
| if err != nil { | if err != nil { | ||||
| cloudBrainNewDataPrepare(ctx) | |||||
| ctx.RenderWithErr(err.Error(), tplCloudBrainNew, &form) | ctx.RenderWithErr(err.Error(), tplCloudBrainNew, &form) | ||||
| return | return | ||||
| } | } | ||||
| @@ -371,6 +419,38 @@ func CloudBrainShowModels(ctx *context.Context) { | |||||
| ctx.HTML(200, tplCloudBrainShowModels) | ctx.HTML(200, tplCloudBrainShowModels) | ||||
| } | } | ||||
| func GetPublicImages(ctx *context.Context) { | |||||
| getImages(ctx, cloudbrain.Public) | |||||
| } | |||||
| func GetCustomImages(ctx *context.Context) { | |||||
| getImages(ctx, cloudbrain.Custom) | |||||
| } | |||||
| func getImages(ctx *context.Context, imageType string) { | |||||
| log.Info("Get images begin") | |||||
| page := ctx.QueryInt("page") | |||||
| size := ctx.QueryInt("size") | |||||
| name := ctx.Query("name") | |||||
| getImagesResult, err := cloudbrain.GetImagesPageable(page, size, imageType, name) | |||||
| if err != nil { | |||||
| log.Error("Can not get images:%v", err) | |||||
| ctx.JSON(http.StatusOK, models.GetImagesPayload{ | |||||
| Count: 0, | |||||
| TotalPages: 0, | |||||
| ImageInfo: []*models.ImageInfo{}, | |||||
| }) | |||||
| } else { | |||||
| ctx.JSON(http.StatusOK, getImagesResult.Payload) | |||||
| } | |||||
| log.Info("Get images end") | |||||
| } | |||||
| func getModelDirs(jobName string, parentDir string) (string, error) { | func getModelDirs(jobName string, parentDir string) (string, error) { | ||||
| var req string | var req string | ||||
| modelActualPath := setting.JobPath + jobName + "/model/" | modelActualPath := setting.JobPath + jobName + "/model/" | ||||
| @@ -387,7 +467,7 @@ func CloudBrainDownloadModel(ctx *context.Context) { | |||||
| parentDir := ctx.Query("parentDir") | parentDir := ctx.Query("parentDir") | ||||
| fileName := ctx.Query("fileName") | fileName := ctx.Query("fileName") | ||||
| jobName := ctx.Query("jobName") | jobName := ctx.Query("jobName") | ||||
| filePath := "jobs/" +jobName + "/model/" + parentDir | |||||
| filePath := "jobs/" + jobName + "/model/" + parentDir | |||||
| url, err := storage.Attachments.PresignedGetURL(filePath, fileName) | url, err := storage.Attachments.PresignedGetURL(filePath, fileName) | ||||
| if err != nil { | if err != nil { | ||||
| log.Error("PresignedGetURL failed: %v", err.Error(), ctx.Data["msgID"]) | log.Error("PresignedGetURL failed: %v", err.Error(), ctx.Data["msgID"]) | ||||
| @@ -421,6 +501,45 @@ func downloadCode(repo *models.Repository, codePath string) error { | |||||
| return err | return err | ||||
| } | } | ||||
| configFile, err := os.OpenFile(codePath + "/.git/config", os.O_RDWR, 0666) | |||||
| if err != nil { | |||||
| log.Error("open file(%s) failed:%v", codePath + "/,git/config", err) | |||||
| return err | |||||
| } | |||||
| defer configFile.Close() | |||||
| pos := int64(0) | |||||
| reader := bufio.NewReader(configFile) | |||||
| for { | |||||
| line, err := reader.ReadString('\n') | |||||
| if err != nil { | |||||
| if err == io.EOF { | |||||
| log.Error("not find the remote-url") | |||||
| return nil | |||||
| } else { | |||||
| log.Error("read error: %v", err) | |||||
| return err | |||||
| } | |||||
| } | |||||
| if strings.Contains(line, "url") && strings.Contains(line, ".git"){ | |||||
| originUrl := "\turl = " + repo.CloneLink().HTTPS + "\n" | |||||
| if len(line) > len(originUrl) { | |||||
| originUrl += strings.Repeat( " ", len(line) - len(originUrl)) | |||||
| } | |||||
| bytes := []byte(originUrl) | |||||
| _, err := configFile.WriteAt(bytes, pos) | |||||
| if err != nil { | |||||
| log.Error("WriteAt failed:%v", err) | |||||
| return err | |||||
| } | |||||
| break | |||||
| } | |||||
| pos += int64(len(line)) | |||||
| } | |||||
| return nil | return nil | ||||
| } | } | ||||
| @@ -3,13 +3,12 @@ package repo | |||||
| import ( | import ( | ||||
| "sort" | "sort" | ||||
| "code.gitea.io/gitea/modules/setting" | |||||
| "code.gitea.io/gitea/models" | "code.gitea.io/gitea/models" | ||||
| "code.gitea.io/gitea/modules/auth" | "code.gitea.io/gitea/modules/auth" | ||||
| "code.gitea.io/gitea/modules/base" | "code.gitea.io/gitea/modules/base" | ||||
| "code.gitea.io/gitea/modules/context" | "code.gitea.io/gitea/modules/context" | ||||
| "code.gitea.io/gitea/modules/log" | "code.gitea.io/gitea/modules/log" | ||||
| "code.gitea.io/gitea/modules/setting" | |||||
| ) | ) | ||||
| const ( | const ( | ||||
| @@ -24,34 +23,100 @@ func MustEnableDataset(ctx *context.Context) { | |||||
| } | } | ||||
| } | } | ||||
| func filterPrivateAttachments(ctx *context.Context, list []*models.Attachment) []*models.Attachment { | |||||
| func newFilterPrivateAttachments(ctx *context.Context, list []*models.Attachment, repo *models.Repository) []*models.Attachment { | |||||
| if ctx.Repo.CanWrite(models.UnitTypeDatasets) { | if ctx.Repo.CanWrite(models.UnitTypeDatasets) { | ||||
| log.Info("can write.") | |||||
| return list | return list | ||||
| } else { | } else { | ||||
| if repo.Owner == nil { | |||||
| repo.GetOwner() | |||||
| } | |||||
| permission := false | |||||
| if repo.Owner.IsOrganization() && ctx.User != nil { | |||||
| if repo.Owner.IsUserPartOfOrg(ctx.User.ID) { | |||||
| log.Info("user is member of org.") | |||||
| permission = true | |||||
| } | |||||
| } | |||||
| if !permission && ctx.User != nil { | |||||
| isCollaborator, _ := repo.IsCollaborator(ctx.User.ID) | |||||
| if isCollaborator { | |||||
| log.Info("Collaborator user may visit the attach.") | |||||
| permission = true | |||||
| } | |||||
| } | |||||
| var publicList []*models.Attachment | var publicList []*models.Attachment | ||||
| for _, attach := range list { | for _, attach := range list { | ||||
| if !attach.IsPrivate { | if !attach.IsPrivate { | ||||
| publicList = append(publicList, attach) | publicList = append(publicList, attach) | ||||
| } else { | |||||
| if permission { | |||||
| publicList = append(publicList, attach) | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| return publicList | return publicList | ||||
| } | } | ||||
| } | |||||
| func QueryDataSet(ctx *context.Context) []*models.Attachment { | |||||
| repo := ctx.Repo.Repository | |||||
| dataset, err := models.GetDatasetByRepo(repo) | |||||
| if err != nil { | |||||
| log.Error("zou not found dataset 1") | |||||
| ctx.NotFound("GetDatasetByRepo", err) | |||||
| return nil | |||||
| } | |||||
| if ctx.Query("type") == "" { | |||||
| log.Error("zou not found type 2") | |||||
| ctx.NotFound("type error", nil) | |||||
| return nil | |||||
| } | |||||
| err = models.GetDatasetAttachments(ctx.QueryInt("type"), dataset) | |||||
| if err != nil { | |||||
| ctx.ServerError("GetDatasetAttachments", err) | |||||
| return nil | |||||
| } | |||||
| attachments := newFilterPrivateAttachments(ctx, dataset.Attachments, repo) | |||||
| ctx.Data["SortType"] = ctx.Query("sort") | |||||
| switch ctx.Query("sort") { | |||||
| case "newest": | |||||
| sort.Slice(attachments, func(i, j int) bool { | |||||
| return attachments[i].CreatedUnix > attachments[j].CreatedUnix | |||||
| }) | |||||
| case "oldest": | |||||
| sort.Slice(attachments, func(i, j int) bool { | |||||
| return attachments[i].CreatedUnix < attachments[j].CreatedUnix | |||||
| }) | |||||
| default: | |||||
| ctx.Data["SortType"] = "newest" | |||||
| sort.Slice(attachments, func(i, j int) bool { | |||||
| return attachments[i].CreatedUnix > attachments[j].CreatedUnix | |||||
| }) | |||||
| } | |||||
| return attachments | |||||
| } | } | ||||
| func DatasetIndex(ctx *context.Context) { | func DatasetIndex(ctx *context.Context) { | ||||
| log.Info("dataset index 1") | |||||
| MustEnableDataset(ctx) | MustEnableDataset(ctx) | ||||
| repo := ctx.Repo.Repository | repo := ctx.Repo.Repository | ||||
| dataset, err := models.GetDatasetByRepo(repo) | dataset, err := models.GetDatasetByRepo(repo) | ||||
| if err != nil { | if err != nil { | ||||
| log.Error("query dataset, not found repo.") | |||||
| ctx.NotFound("GetDatasetByRepo", err) | ctx.NotFound("GetDatasetByRepo", err) | ||||
| return | return | ||||
| } | } | ||||
| if ctx.Query("type") == "" { | if ctx.Query("type") == "" { | ||||
| log.Error("not found param type") | |||||
| log.Error("query dataset, not found param type") | |||||
| ctx.NotFound("type error", nil) | ctx.NotFound("type error", nil) | ||||
| return | return | ||||
| } | } | ||||
| @@ -60,7 +125,8 @@ func DatasetIndex(ctx *context.Context) { | |||||
| ctx.ServerError("GetDatasetAttachments", err) | ctx.ServerError("GetDatasetAttachments", err) | ||||
| return | return | ||||
| } | } | ||||
| attachments := filterPrivateAttachments(ctx, dataset.Attachments) | |||||
| attachments := newFilterPrivateAttachments(ctx, dataset.Attachments, repo) | |||||
| ctx.Data["SortType"] = ctx.Query("sort") | ctx.Data["SortType"] = ctx.Query("sort") | ||||
| switch ctx.Query("sort") { | switch ctx.Query("sort") { | ||||